marco de video de captura de Android

Necesito obtener un marco de un archivo de video (puede estar en sdcard, cache dir o app dir). Tengo el paquete android.media en mi aplicación y en mi interior tengo la clase MediaMetadataRetriever. Para obtener el primer fotogtwig en un bitmap, uso 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. 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 (el reproductor de medios puede reproducir videos de ese URI)

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 usa una ruta en lugar de un descriptor de archivo.

Prueba esto, lo he usado y funciona

 public static Bitmap getVideoFrame(Context context, Uri uri) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(uri.toString(),new HashMap()); 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 puedes pasar directamente tu url.

Tengo el mismo error en mi solicitud. Vi en este sitio que

esta es una forma no oficial de hacerlo y solo funcionará en cupcake (y tal vez en versiones posteriores). El equipo de Android no garantiza que libmedia_jni.so, que utiliza el archivo java, se incluirá o tendrá la misma interfaz en versiones futuras.

http://osdir.com/ml/AndroidDevelopers/2009-06/msg02442.html

He actualizado mi teléfono a GingerBread y ya no funciona.

Los Uri no son muy específicos. A veces se refieren a algo en un paquete. A menudo necesitan ser traducidos a una forma de ruta absoluta. La otra instancia en la que utilizó el Uri, probablemente fue lo suficientemente inteligente como para comprobar qué tipo de Uri era. Este caso que has mostrado parece no estar muy duro.

Estaba obteniendo el mismo error usando la clase ThumbnailUtils http://developer.android.com/reference/android/media/ThumbnailUtils.html
Utiliza MediaMetadataRetriever bajo el capó y la mayoría de las veces puede enviarlo a través de 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 estaba viendo @gabi. El uso de un descriptor de archivo en su lugar resolvió el problema y aún funciona para dispositivos que no sean 4.0.4. De hecho, terminé subclasando 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 se produce también cuando el File no existe. Entonces, antes de llamar a setDataSource() será mejor que compruebe si el new File(url).exists() .

Usé este código y eso está funcionando para mí. puedes probar este.

 if (Build.VERSION.SDK_INT >= 14) { ffmpegMetaDataRetriever.setDataSource( videoFile.getAbsolutePath(), new HashMap()); } else { ffmpegMetaDataRetriever.setDataSource(videoFile .getAbsolutePath()); } 

entonces hay una manera específica de obtener el marco del video como

  File sdcard = Environment.getExternalStorageDirectory(); File file = new File(sdcard, "myvideo.mp4");