第18章 HarmonyOs开发图解之 媒体数据管理

HarmonyOS 学习系统 | 阶段三:高级深耕期


学习目标

序号 能力
1 掌握 AVMetadataHelper 获取媒体元数据和截取视频帧
2 能够使用 AVStorage 查询设备中的图片/音频/视频文件
3 掌握 AVThumbnailUtils 快速生成缩略图

核心图解

HarmonyOS 多媒体框架全景图

内容讲解

18.1 媒体数据管理概述

媒体数据管理模块提供了对多媒体文件的"元数据"访问能力——不需要打开或播放文件,就能获取标题、时长、分辨率、艺术家等描述信息。同时支持快速生成视频和图片的缩略图,以及查询设备中存储的所有媒体文件。

生活化类比:媒体元数据就像"图书卡片"

想象你去图书馆,每本书的书脊上都贴着一张小卡片(元数据),上面写着书名、作者、页数、出版日期——你不需要翻开书就能了解它的基本信息。AVMetadataHelper 就是帮你读取这些"卡片"的工具。AVThumbnailUtils 则像缩印服务,把一本书的封面缩小成一张小卡片,方便你快速浏览大量书籍的概貌。

18.2 AVMetadataHelper:元数据与视频帧

AVMetadataHelper helper = new AVMetadataHelper();

// 设置数据源(文件路径或 URI)
helper.setSource("resources/rawfile/big_buck_bunny.mp4");

// 获取元数据
String duration = helper.resolveMetadata(AVMetadataResolver.META_KEY_DURATION);
String mimeType = helper.resolveMetadata(AVMetadataResolver.META_KEY_MIME_TYPE);
String title = helper.resolveMetadata(AVMetadataResolver.META_KEY_TITLE);
String artist = helper.resolveMetadata(AVMetadataResolver.META_KEY_ARTIST);
HiLog.info(TAG, "时长: " + duration + ", 格式: " + mimeType);

// 截取视频帧(获取当前时间点的画面)
PixelMap pixelMap = helper.fetchVideoPixelMapByTime();

// 释放资源
helper.release();

18.3 AVThumbnailUtils:快速生成缩略图

// 生成视频缩略图
PixelMap videoThumbnail = AVThumbnailUtils.createVideoThumbnail(
    new File("path/to/video.mp4"),
    new Size(200, 200) // 缩略图尺寸
);

// 生成图片缩略图
PixelMap imageThumbnail = AVThumbnailUtils.createImageThumbnail(
    new File("path/to/photo.jpg"),
    new Size(200, 200)
);

18.4 AVStorage:媒体文件查询

AVStorage 提供了通过 AVColumns 定义的标准列名来查询设备中的媒体文件信息。

// 查询所有图片文件
DataAbilityHelper helper = DataAbilityHelper.creator(context);
ResultSet resultSet = helper.query(
    AVStorage.Images.Media.EXTERNAL_DATA_URI,  // 图片URI
    new String[]{
        AVStorage.Images.Media.COLUMN_NAME,     // 文件名
        AVStorage.Images.Media.COLUMN_SIZE,     // 文件大小
        AVStorage.Images.Media.COLUMN_DATE_ADDED // 添加日期
    },
    null, null, AVStorage.Images.Media.COLUMN_DATE_ADDED + " DESC");

while (resultSet.goToNextRow()) {
    String name = resultSet.getString(0);
    long size = resultSet.getLong(1);
    String date = resultSet.getString(2);
    HiLog.info(TAG, "图片: " + name + ", 大小: " + size + ", 日期: " + date);
}

代码速查卡

API 功能 示例
new AVMetadataHelper() 创建元数据辅助类 new AVMetadataHelper()
setSource(path) 设置数据源 helper.setSource("path/to/video.mp4")
resolveMetadata(key) 获取元数据 helper.resolveMetadata(META_KEY_DURATION)
fetchVideoPixelMapByTime() 截取视频帧 helper.fetchVideoPixelMapByTime()
createVideoThumbnail(file, size) 生成视频缩略图 AVThumbnailUtils.createVideoThumbnail(...)
createImageThumbnail(file, size) 生成图片缩略图 AVThumbnailUtils.createImageThumbnail(...)
AVStorage.Images.Media.EXTERNAL_DATA_URI 查询图片 URI 用于 DataAbilityHelper.query()

与 Android/iOS 对比

特性 HarmonyOS Android iOS
元数据获取 AVMetadataHelper MediaMetadataRetriever AVAsset
视频帧截取 fetchVideoPixelMapByTime getFrameAtTime() AVAssetImageGenerator
缩略图生成 AVThumbnailUtils ThumbnailUtils PHImageManager
媒体文件查询 AVStorage + DataAbilityHelper MediaStore + ContentResolver Photos Framework (PHFetchResult)

⚠️ 踩坑回忆录

为什么 AVMetadataHelper 返回的时长是 0?

因为我在 setSource 之后立刻调用了 resolveMetadata,但此时文件还在异步解析中!文件越大,解析越慢。正确做法是等 setSource 的回调确认完成后再查询元数据,或者加一个适当的延迟。

还有一个坑:读取用户存储的媒体文件需要 ohos.permission.READ_USER_STORAGE 权限,别漏了。没有这个权限,AVStorage 查询会返回空结果集,不会有任何报错提示——这种"静默失败"最坑人,排查了半天才发现是权限问题。


必做实操任务

序号 任务 难度
1 获取视频文件的元数据(时长、格式、分辨率)并展示
2 截取视频帧并显示为图片
3 为视频列表生成缩略图(类似视频 App 的封面)
4 查询设备中所有图片文件并展示为网格列表
5 实现一个简单的媒体文件浏览器(图片 + 视频)

学习检查清单

  • 能使用 AVMetadataHelper 获取媒体文件的元数据
  • 能截取视频帧并转换为 PixelMap
  • 能使用 AVThumbnailUtils 生成缩略图
  • 能使用 AVStorage 查询设备中的媒体文件
  • 知道为什么 setSource 后不能立即查询元数据
  • 知道读取用户存储需要 READ_USER_STORAGE 权限
  • 能区分 AVStorage 中图片/音频/视频的查询 URI
  • 能正确释放 AVMetadataHelper 资源

进阶方向

  • 结合第 14 章图像能力,实现图片批量压缩和格式转换工具
  • 学习 AVStorage 的增删改操作,实现媒体文件管理 App
  • 探索分布式文件系统,跨设备访问媒体文件
    片/音频/视频的查询 URI
  • 能正确释放 AVMetadataHelper 资源

进阶方向

  • 结合第 14 章图像能力,实现图片批量压缩和格式转换工具
  • 学习 AVStorage 的增删改操作,实现媒体文件管理 App
  • 探索分布式文件系统,跨设备访问媒体文件
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐