当前位置:首页 > 行业动态 > 正文

安卓将一段视频按帧存储为图片

通过MediaMetadataRetriever获取视频帧,循环调用getFrameAtTime()提取每帧,将Bitmap存为图片文件

安卓将视频按帧存储为图片的实现方法

核心思路

通过 MediaMetadataRetriever 提取视频帧,逐帧转换为 Bitmap 并保存为图片文件,需注意权限管理、性能优化及存储路径处理。


实现步骤

  1. 权限申请

    • 读取视频文件:READ_EXTERNAL_STORAGE
    • 写入图片文件:WRITE_EXTERNAL_STORAGE(Android 10+ 需适配分区存储)
  2. 初始化工具类

    安卓将一段视频按帧存储为图片

    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
  3. 设置数据源

    retriever.setDataSource(videoFilePath); // 视频文件路径
  4. 获取视频元数据

    安卓将一段视频按帧存储为图片

    • 时长:retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
    • 帧率:需手动计算或从文件解析(如 ffprobe 工具)。
  5. 逐帧提取与保存

    • 遍历时间戳,按固定间隔(如每秒 1 帧)提取帧。
    • 将 Bitmap 压缩为 JPEG 并保存。

关键代码示例

public void extractFrames(String videoPath, String outputDir) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        retriever.setDataSource(videoPath);
        int duration = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
        int frameRate = 25; // 假设帧率,可动态计算
        int frameInterval = 1000 / frameRate; // 每帧间隔(毫秒)
        for (int i = 0; i < duration; i += frameInterval) {
            Bitmap bitmap = retriever.getFrameAtTime(i  1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
            if (bitmap != null) {
                saveBitmap(bitmap, outputDir + "/frame_" + i + ".jpg");
                bitmap.recycle();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        retriever.release();
    }
}
private void saveBitmap(Bitmap bitmap, String path) {
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(path);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fos != null) {
            try { fos.close(); } catch (IOException ignored) {}
        }
    }
}

注意事项

问题 解决方案
权限拒绝 Android 10+ 使用 MediaStore API 或请求分区存储权限
大视频卡顿 子线程处理,分批加载帧
帧率不准确 使用第三方库(如 FFmpeg)解析真实帧率
OOM风险 及时回收 Bitmap,限制并发任务

相关问题与解答

Q1:如何动态获取视频的真实帧率?
A1:可通过 MediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FPS) 尝试获取,若失败则需使用 FFmpeg 解析视频流。

安卓将一段视频按帧存储为图片

Q2:Android 11+ 如何保存图片到公有目录?
A2:使用 MediaStore.Images.Media.insertImage()ContentResolver 写入系统相册,避免直接操作文件路径