媒体能力概览

鸿蒙的多媒体能力分布在 CameraKit、MediaLibraryKit、AVPlayer 等 Kit 里:相机管拍摄,媒体库管相册文件,播放器管音频视频。先摸清能力地图,再动手写代码。

先想清楚数据从哪来、到哪去,再决定用哪个 Kit。

大多数业务其实只需要三件事:调相机拍一张、从相册选一张、把音视频放出来。这三条链路走通,多媒体的地基就稳了。

相机调用与权限

调用相机前必须申请 ohos.permission.CAMERA,用 abilityAccessCtrl 动态申请,拒绝后要能引导用户去设置。权限是敏感能力的第一道门,别绕过。

import { abilityAccessCtrl, common } from '@kit.AbilityKit'
import { camera } from '@kit.CameraKit'

async function openCamera(context: common.Context) {
  const atManager = abilityAccessCtrl.createAtManager()
  const grant = await atManager.requestPermissionsFromUser(context,
    ['ohos.permission.CAMERA'])
  if (grant.authResults[0] !== 0) {
    return // 未授权,提示用户
  }
  const cameraManager = camera.getCameraManager(context)
  const cameras = cameraManager.getSupportedCameras()
  const cameraDevice = cameras.find(c => c.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK)
}
权限三件套
  • CAMERA拍摄画面。
  • READ_MEDIA读取相册。
  • WRITE_MEDIA写入相册。

申请权限时把用途说清楚,系统弹窗里的一段说明文字能大幅提升授权率。别在启动时一口气申请所有权限,用到再申请,用户反感度最低。

拍照与相册存取

拍照流程:建会话、配输出、拍一张、拿 buffer。鸿蒙里用 cameraManager 创建会话,PhotoOutput 负责出图,保存走 photoAccessHelper。

import { photoAccessHelper } from '@kit.MediaLibraryKit'

async function saveImage(context: common.Context, buffer: ArrayBuffer) {
  const helper = photoAccessHelper.getPhotoAccessHelper(context)
  const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg')
  const fp = await helper.openAsset(uri, photoAccessHelper.PhotoViewMode.READ_WRITE)
  // 向 fp 写入图片数据后关闭
}

相册读取用 photoAccessHelper 的 getAssets 按条件查,按创建时间排序、按类型过滤都能做。别忘了在 Info 配置里声明媒体权限对应的 useScene。

音频播放与录制

音频播放用 AVPlayer,录制用 AudioCapturer 或直接走系统录音。AVPlayer 是统一入口,音频视频都归它管。

import { avPlayer } from '@kit.MediaKit'

async function play(url: string) {
  const player = await avPlayer.createAVPlayer()
  player.url = url
  await player.prepare()
  await player.play()
}

播放状态监听 player.on('stateChange'),缓冲、就绪、结束都从这里拿。录制注意采样率和声道配置,语音场景 16k 单声道就够,别白白占空间。

媒体能力的接入路径并不复杂,但有几个容易踩的坑值得留意:一是权限要在调用前声明并在运行时动态申请,摄像头和麦克风属于敏感权限,用户拒绝后要给出合理的引导说明;二是资源释放,播放器用完要调用 release,避免后台继续占用解码资源;三是格式兼容,鸿蒙的媒体框架对常见容器和编码支持比较全面,但个别低码率或老旧格式可能出现不支持的情况,接入时最好先做一次能力查询,再根据返回值决定是否提示用户升级版本或转码。把这三个问题在开发早期解决掉,多媒体功能上线后出问题的概率会小很多。