Marco de vídeo de captura de android
Necesito obtener un marco de un archivo de video (puede ser en sdcard, dir de caché o dir de aplicación). Tengo paquete android.media en mi aplicación y dentro tengo clase MediaMetadataRetriever. Para obtener el primer fotograma en un mapa de bits, utilizo el código:
public static Bitmap getVideoFrame(Context context, Uri videoUri) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); retriever.setDataSource(context, videoUri); return retriever.captureFrame(); } catch (IllegalArgumentException ex) { throw new RuntimeException(); } catch (RuntimeException ex) { throw new RuntimeException(); } finally { retriever.release(); } }
Pero esto no está funcionando. Se lanza una excepción (java.lang.RuntimeException: setDataSource failed: status = 0x80000000) cuando establezco el origen de datos. ¿Sabes cómo hacer que este código funcione? O ¿Tiene alguna solución similar (simple) sin usar ffmpeg u otras bibliotecas externas? VideoUri es un uri válido (reproductor de medios puede reproducir video de ese URI)
- Android MediaPlayer parpadea al reproducir vídeos en Android 4.2.2
- Nexus 6 y MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
- Cómo encontrar y reproducir videos descargados por Lynda.com Aplicación para Android o Windows
- No se pueden transmitir vídeos
- Aplicación de la aplicación demo de Android app?
- Cómo reproducir URL de vídeo dentro de la vista web de Android
- Grabación de video en un buffer circular en Android
- Extraer fotogramas de vídeo en Android
- Buffer de vídeo circular Android con sonido
- Android MediaPlayer seekTo no funciona
- ¿Cómo puedo crear un reproductor multimedia personalizado para reproducir un códec personalizado en Android?
- ¿Cómo usar la decodificación acelerada por hardware en Android?
- Cómo seguir reproduciendo video mientras cambia a modo horizontal android
Lo siguiente funciona para mí:
public static Bitmap getVideoFrame(FileDescriptor FD) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(FD); return retriever.getFrameAtTime(); } catch (IllegalArgumentException ex) { ex.printStackTrace(); } catch (RuntimeException ex) { ex.printStackTrace(); } finally { try { retriever.release(); } catch (RuntimeException ex) { } } return null; }
También funciona si utiliza una ruta de acceso en lugar de un descriptor de archivo.
Prueba esto, lo he usado y su funcionamiento
public static Bitmap getVideoFrame(Context context, Uri uri) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(uri.toString(),new HashMap<String, String>()); return retriever.getFrameAtTime(); } catch (IllegalArgumentException ex) { ex.printStackTrace(); } catch (RuntimeException ex) { ex.printStackTrace(); } finally { try { retriever.release(); } catch (RuntimeException ex) { } } return null; }
En lugar de uri puede pasar directamente su url.
Tengo el mismo error en mi solicitud. Vi en este sitio que
Esta es una manera no oficial de hacerlo y sólo funcionará en cupcake (y quizás versión posterior). El equipo de Android no garantiza que libmedia_jni.so, que utiliza el archivo java, se incluirá o tendrá la misma interfaz en futuras versiones.
http://osdir.com/ml/AndroidDevelopers/2009-06/msg02442.html
He actualizado mi teléfono a GingerBread y ya no funciona.
Los de Uri no son muy específicos. A veces se refieren a algo en un paquete. A menudo necesitan ser traducidos a una forma de camino absoluto. La otra instancia en la que usaste el Uri, probablemente fue lo suficientemente inteligente para comprobar qué tipo de Uri era. Este caso que usted ha demostrado no parece estar mirando muy duro.
Yo estaba recibiendo el mismo error usando la clase ThumbnailUtils http://developer.android.com/reference/android/media/ThumbnailUtils.html
Se utiliza MediaMetadataRetriever bajo el capó y la mayoría de las veces se puede enviar un filepath utilizando este método sin ningún problema:
public static Bitmap createVideoThumbnail (String filePath, int kind)
Sin embargo, en Android 4.0.4, seguí recibiendo el mismo error que @gabi estaba viendo. El uso de un descriptor de archivo resolvió el problema y todavía funciona para dispositivos que no sean 4.0.4. De hecho terminé subclasificando ThumbnailUtils. Aquí está mi método de subclase:
public static Bitmap createVideoThumbnail(FileDescriptor fDescriptor, int kind) { Bitmap bitmap = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(fDescriptor); bitmap = retriever.getFrameAtTime(-1); } catch (IllegalArgumentException ex) { // Assume this is a corrupt video file Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString()); } catch (RuntimeException ex) { // Assume this is a corrupt video file. Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString()); } finally { try { retriever.release(); } catch (RuntimeException ex) { // Ignore failures while cleaning up. } } if (bitmap == null) return null; if (kind == Images.Thumbnails.MINI_KIND) { // Scale down the bitmap if it's too large. int width = bitmap.getWidth(); int height = bitmap.getHeight(); int max = Math.max(width, height); if (max > 512) { float scale = 512f / max; int w = Math.round(scale * width); int h = Math.round(scale * height); bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true); } } else if (kind == Images.Thumbnails.MICRO_KIND) { bitmap = extractThumbnail(bitmap, TARGET_SIZE_MICRO_THUMBNAIL, TARGET_SIZE_MICRO_THUMBNAIL, OPTIONS_RECYCLE_INPUT); } return bitmap; }
La excepción también se activa cuando el File
no existe. Así que antes de llamar a setDataSource()
es mejor comprobar si el new File(url).exists()
.
He utilizado este código y eso está funcionando para mí. Usted puede intentar éste.
if (Build.VERSION.SDK_INT >= 14) { ffmpegMetaDataRetriever.setDataSource( videoFile.getAbsolutePath(), new HashMap<String, String>()); } else { ffmpegMetaDataRetriever.setDataSource(videoFile .getAbsolutePath()); }
Por lo que hay una manera específica de obtener el marco de vídeo como
File sdcard = Environment.getExternalStorageDirectory(); File file = new File(sdcard, "myvideo.mp4");
- Utilidad de Google Maps: cómo obtener todos los marcadores de ClusterManager <?>?
- Android creando cadena de animación ViewPropertyAnimator