15

问题:

如何获取应用程序私有文件的视频缩略图?具体来说,有没有办法直接从 .mpeg 文件中提取视频帧?

背景:

  1. 我的应用程序包括一个可以录制视频的相机。
  2. 出于产品原因,视频文件最初是在应用程序的私有数据目录中以私有模式创建和写入的,使其对应用程序私有。这是通过以下方式完成的:Context#openFileOutput(fileName, Context.MODE_PRIVATE)- 典型的文件路径如下所示:/data/data/[package.name]/files/[fileName].mp4- 仅供参考,我已经尝试过使用Context.MODE_WORLD_READABLEContext.MODE_PRIVATE但它没有帮助。
  3. 即使视频最终可能最终存储在外部存储中(通过将文件移动到Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)) ,也必须在视频位于应用程序私有存储中时显示缩略图。
  4. ThumbnailUtils.createVideoThumbnail(String, int)将文件移动到公共目录(无论将其添加到 MediaStore)后,该文件似乎可以正常工作,但是null当文件在内部存储中时,它会静默失败(返回)。

    • 注意:只要视频文件在应用程序私有存储中,它就不会添加到 MediaStore(设备库上的图像/视频内容提供程序提供)。只有将视频移至外部存储设备后,我才会将其添加到 MediaStore。这是一个与产品相关的决定,我无法绕过;除非有一种方法可以将视频添加到媒体存储中而其他应用程序不可见...我想知道是否可以将应用程序私有存储中的视频添加到媒体存储中并保持应用程序私有但获得所有免费的“服务” " 由媒体商店提供,例如缩略图生成。
4

4 回答 4

3

当然,您不能将 MediaStore 的东西用于私人媒体。如果可能的话,我会使用图像处理库。我知道OpenCV 可以通过提取/调整帧大小轻松做到这一点。- 请看第 2 页的中间部分。

于 2012-01-02T03:48:17.747 回答
2

大多数媒体 API 只是媒体服务器的绑定客户端,在自己的进程中运行。您可以尝试将文件设为临时公开。

于 2012-01-04T19:01:25.540 回答
1

您是否尝试过以下 API,

MediaMetadataRetriever::getFrameAtTime() ,参考Android-developer-page-MediaMetadataRetriever

示例代码:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(filePath);
bitmap = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST);
} catch (IllegalArgumentException ex) {
// Assume this is a corrupt video file
} catch (RuntimeException ex) {
// Assume this is a corrupt video file. }

上面的代码对我有用!但我的文件可以在公共文件夹中访问。

于 2012-01-04T05:36:34.057 回答
0

这适用于姜饼及以上:

try {
    Uri location = Uri.fromFile(context.getFileStreamPath(filePath));
    MediaMetadataRetriever media = new MediaMetadataRetriever();
    ParcelFileDescriptor parcel = ParcelFileDescriptor.open(new File(location.getPath()),ParcelFileDescriptor.MODE_READ_ONLY);
    media.setDataSource(parcel.getFileDescriptor());
    Bitmap thumb = media.getFrameAtTime(0 , MediaMetadataRetriever.OPTION_CLOSEST );
    thumbnail.setImageBitmap(thumb);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
于 2014-04-20T17:18:58.780 回答