You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MediaMetadataRetriever获取视频多缩略图重复问题求助

问题分析与解决方案

先解决MediaMetadataRetriever返回重复缩略图的问题

你遇到的核心问题大概率是时间单位不匹配!MediaMetadataRetriever.getFrameAtTime()方法接收的时间参数是微秒(microseconds),但你从METADATA_KEY_DURATION获取到的时长是毫秒(milliseconds)。你的代码里直接把毫秒数除以3作为时间参数,相当于只取了视频开头几毫秒的位置,自然会得到同一张缩略图。

修正后的代码示例

把计算出来的时间乘以1000转成微秒即可,另外别忘了释放资源避免内存泄漏:

MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever();
try {
    metadataRetriever.setDataSource(MainActivity.this, Uri.parse("android.resource://packageName/raw/test"));
    String durationStr = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
    long durationMs = Long.valueOf(durationStr);
    
    // 计算三个时间点,转成微秒单位
    long time1 = (durationMs / 3) * 1000;
    long time2 = (durationMs * 2 / 3) * 1000;
    long time3 = durationMs * 1000;
    
    Bitmap bitmap1 = metadataRetriever.getFrameAtTime(time1, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
    Bitmap bitmap2 = metadataRetriever.getFrameAtTime(time2, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
    Bitmap bitmap3 = metadataRetriever.getFrameAtTime(time3, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
    
    imgone.setImageBitmap(bitmap1);
    // 这里可以设置其他ImageView的bitmap
} catch (Exception ex) {
    Toast.makeText(MainActivity.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
    // 释放资源,避免内存泄漏
    metadataRetriever.release();
}

关于FFmpeg是否是更好的解决方案

这得看你的具体需求:

  • 如果只是获取几个关键时间点的缩略图,修正后的MediaMetadataRetriever完全够用,它是Android系统原生API,无需额外依赖,轻量又高效。
  • 如果你的需求更复杂:比如要精确到某一帧、批量处理大量视频、对缩略图做自定义裁剪/格式转换,或者遇到MediaMetadataRetriever对某些冷门视频格式支持不佳的情况,那么FFmpeg确实是更好的选择。

你可以用封装好的FFmpegMediaMetadataRetriever库,它基于FFmpeg,支持更多格式,API用法和原生MediaMetadataRetriever类似,能降低集成成本。如果需要更底层的控制,也可以自己编译FFmpeg集成到项目中,但相对会麻烦一些。

内容的提问来源于stack exchange,提问作者ClassA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:14:28