我需要获取视频文件的框架(可能是sdcard,cache dir或app dir)。我在我的应用程序中有android.media包,我有类MediaMetadataRetriever。要将第一帧放入位图,我使用代码:
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 :(得分:13)
以下适用于我:
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;
}
如果您使用路径而不是文件描述符,也可以使用。
答案 1 :(得分: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,您可以直接传递您的网址。
答案 2 :(得分:0)
我的申请也有同样的错误。我在这个网站上看到了
这是一种非官方的做法 它只适用于蛋糕(和 也许以后的版本)。 Android团队 不能保证 libmedia_jni.so,这是java文件 使用,将被包括或拥有 未来版本中的相同界面。
http://osdir.com/ml/AndroidDevelopers/2009-06/msg02442.html
我已将手机更新为GingerBread,但它不再有效了。
答案 3 :(得分:0)
Uri不是很具体。有时它们会引用捆绑中的某些东西。它们通常需要转换为绝对路径形式。在你使用Uri的另一个例子中,它可能非常聪明,可以检查它是什么类型的Uri。你所展示的这种情况看起来并不是很难看。
答案 4 :(得分:0)
我使用 ThumbnailUtils 类http://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;
}
答案 5 :(得分:0)
当File
不存在时,也会抛出异常。因此,在致电setDataSource()
之前,您最好先检查new File(url).exists()
。
答案 6 :(得分:0)
我使用了这段代码,这对我有用。你可以尝试这个。
if (Build.VERSION.SDK_INT >= 14) {
ffmpegMetaDataRetriever.setDataSource(
videoFile.getAbsolutePath(),
new HashMap<String, String>());
} else {
ffmpegMetaDataRetriever.setDataSource(videoFile
.getAbsolutePath());
}
答案 7 :(得分:-2)
所以有一种特定的方法可以从视频中获取帧
File sdcard = Environment.getExternalStorageDirectory();
File file = new File(sdcard, "myvideo.mp4");