Android:如何获取应用程序私有文件的视频缩略图?

发布于 2024-12-22 06:48:27 字数 1440 浏览 1 评论 0 原文

问题:

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

背景:

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

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

Question:

How do you get a video thumbnail for an application-private file?
Specifically, is there a way to extract video frames from an .mpeg file directly?

Background:

  1. My application includes a camera that can record video.
  2. For product reasons, the video file is initially created and written in private mode in the application's private data directory, making it private to the application. This is done using: Context#openFileOutput(fileName, Context.MODE_PRIVATE) - a typical file path looks like this: /data/data/[package.name]/files/[fileName].mp4 -- FYI I already tried using Context.MODE_WORLD_READABLE instead of Context.MODE_PRIVATE but it didn't help.
  3. Even though the video may eventually end up in external storage (by moving the file to Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)), the thumbnail must be displayed while the video is in application-private storage.
  4. It seems like ThumbnailUtils.createVideoThumbnail(String, int) works fine for the file after it is moved to the public directory (regardless of adding it to the MediaStore), but silently fails (returns null) when the file is in internal storage.

    • Note: as long as the video file is in application-private storage, it is not added to the MediaStore (the image/video content provider on the device Gallery feeds on). Only once the video is moved to external storage do I add it the MediaStore. This is a product-related decision which I cannot circumnavigate; unless there's a way to add the video the media store without it being visible to other apps... I wonder if videos in application-private storage can be added to the media store and would remain application-private but gain all the free "services" provided by the media store such as thumbnail generation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

长途伴 2024-12-29 06:48:27

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

Of course, you can't use MediaStore stuff for private media. I would use a image process library if it is possible at all. I know OpenCV can do that easily by extracting/resizing a frame. - please look at middle section of page 2.

向日葵 2024-12-29 06:48:27

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

Most of media APIs are just binder client of media server which runs in its own process. You may try to make the file public temporary.

调妓 2024-12-29 06:48:27

您是否尝试过使用以下 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. }

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

have you tried with the below API,

MediaMetadataRetriever::getFrameAtTime() , refer to Android-developer-page-MediaMetadataRetriever

sample code:

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

The above piece of code worked for me!! but my file is accessible in the public folders.

淡淡の花香 2024-12-29 06:48:27

这适用于 Gingerbread 及以上版本:

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

This works on Gingerbread and up:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文