2011-03-17 94 views
6

我需要得到一个视频文件的框架(它可能在SD卡,缓存目录或应用程序目录)。我在我的应用程序中包装了android.media,并且里面有了MediaMetadataRetriever类。要使第一帧成为位图,我使用代码:android capture video frame

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(); 
    } 
} 

但是,这不起作用。它会在设置数据源时引发异常(java.lang.RuntimeException:setDataSource failed:status = 0x80000000)。你知道如何使这个代码工作吗?或者你有没有使用ffmpeg或其他外部库的类似(简单)解决方案? videoUri是一个有效的URI(媒体播放器可以播放来自该URI的视频)

+0

你能否提供一个你的问题的样本,我试了很多这种样本,最后不得不问你。 – ManishSB 2015-04-18 11:11:19

回答

11

对我来说,以下工作:

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; 
    } 

如果你使用一个路径,而不是一个文件描述符的也有效。

+0

什么值应该作为FileDescripter参数传递。 Real认为,在我的应用程序中,只有视频网址,并且想要获取该视频文件的帧列表... – 2012-04-10 04:31:00

+0

要获取FileDescriptor对象,请执行以下操作: - openFileInput(myVideoFileName).getFD()。为此,视频必须位于您的应用程序专用目录中。您还可以更改为公共静态位图getVideoFrame(String FD)并传递您的视频路径。 – 2012-04-16 09:26:45

+0

在一秒钟内,视频有25到30帧。能够获得所有帧。因为通过这种技术,我每次得到3-4个重复帧,并且一些帧丢失。 – 2014-04-25 05:19:54

0

我的应用程序有同样的错误。我看到在这个网站上

这是做 的一个非官方的方式,它只会在蛋糕的工作(和 也许以后版本)。 Android团队 不保证将在未来版本中包含 Java文件 的 libmedia_jni.so或具有相同接口的 。

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

我已经更新了我的电话姜饼,它不工作了。

0

Uri的不是很具体。有时他们指的是捆绑的东西。他们经常需要翻译成绝对路径形式。在你使用Uri的另一个例子中,它可能足够聪明来检查它是什么样的Uri。你已经显示的这个案例看起来不是很难。

-2

所以有摆脱视频帧

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

您是要求还是回复? – 2012-03-20 14:04:58

+0

它给错误...现在它的工作...我想我的eclipse编辑器有一些问题。无论如何谢谢 – 2012-03-20 14:17:43

+0

我的评论是问你“这2行代码是你的答案还是你的问题的一个问题?” – 2012-03-20 14:18:42

6

尝试这种特殊的方式,我用它和它的工作

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; 
} 

在的地方,你可以直接通过URI的你的网址。

+0

它需要api 14.如何在它下面的api中使用。 – Suraj 2014-01-07 06:51:18

+0

您只需使用此FFmpegMediaMetadataRetriever https://github.com/wseemann/FFmpegMediaMetadataRetriever – arul 2014-05-16 12:43:58

0

我用的是ThumbnailUtilshttp://developer.android.com/reference/android/media/ThumbnailUtils.html
它采用MediaMetadataRetriever引擎盖下,大部分的时间,你可以使用这种方法没有问题,它发送一个文件路径得到相同的错误:

public static Bitmap createVideoThumbnail (String filePath, int kind) 

但是,在Android 4.0.4上,我不断收到@gabi看到的相同错误。使用文件描述符代替解决了这个问题,并且仍然适用于非4.0.4设备。我实际上结束了ThumbnailUtils的子类化。这是我的子类方法:

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; 
} 
0

File不存在时也会抛出异常。因此在致电setDataSource()之前,最好检查new File(url).exists()

0

我使用了这段代码,这对我很有用。你可以试试这个。

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