鸿蒙系统中音视频的采集与播放
在鸿蒙APP的开发中,音视频能力作为核心交互载体,其应用场景深度融入各行各业的数字化进程,成为连接用户、场景与服务的关键纽带,如实时互动、远程协作、短视频/自媒体、电商直播带货等场景都需要音视频的采集或播放等能力。
一.视频的采集
在鸿蒙开发中,视频的采集官方建议使用Camera Kit框架接口来完成,Camera Kit适用于需要自定义相机功能的场景,如手动对焦、曝光控制、视频流处理、多摄像头切换等,Camera工作流程如下图。
图1 相机工作流程
应用可以通过控制Camera,实现图像显示(预览)、视频录制(录像)等基础操作。在实现基本操作过程中,Camera Kit会控制相机设备采集和输出数据,采集的图像数据在相机底层的设备硬件接口(HDI,Hardware Device Interfaces),直接通过BufferQueue传递到具体的功能模块进行处理。BufferQueue在开发中一般无需关注,用于将底层处理的数据及时送到上层进行图像显示。以视频录制为例,应用在录制视频过程中,需先创建一个视频Surface用于传递数据,并提供给Camera Kit,Camera Kit可控制相机设备采集视频数据,生成视频流。采集的数据通过底层相机HDI处理后,通过Surface将视频流传递给媒体录制服务,媒体录制服务对视频数据进行处理后,保存为视频文件,完成视频录制。
图2 相机开发模型
视频采集的使用流程如下:
1)申请相机权限
在开发应用时,需要先申请相机相关权限,确保应用拥有访问相机硬件及其他功能的权限,在module.json5中配置Camera权限申请
另外,也需要在运行时,通过弹窗动态请求用户授权。
2)获取相机设备列表并选择目标设备
首先,需要先通过调用相机接口来创建一个独立的相机设备。通过CameraManager中的getSupportedCameras方法,获取当前设备支持的相机列表,列表中存储了设备支持的所有相机ID。若列表不为空,则说明列表中的每个ID都支持独立创建相机对象;否则,说明当前设备无可用相机,不可继续后续操作。
3)获取相机支持的Profile
在应用开发中,获取相机支持的Profile(输出流配置)是构建健壮应用的核心环节,首先通过CameraOutputCapability获取的Profile集合包含设备支持的分辨率、帧率、图像格式等关键参数。例如用户代码中硬编码的imageWidth: 1920和imageHeight: 1080需通过遍历previewProfiles验证是否合法;另外用户代码中固定imageWidth和imageHeight的写法可能存在设备兼容性问题,通过Profile可实现动态匹配最佳分辨率。
4)创建预览会话,绑定预览Surface
相机使用预览、数据采集前,均需要创建相机会话。向会话中添加相机的输入流和输出流,调用addInput添加相机的输入流;调用addOutput添加相机的输出流。配置输入流即添加设备输入,对用户而言,相当于选择设备的某一相机拍摄;配置输出流,即选择数据将以什么形式输出。
在开发界面时,首先需要通过创建XComponent组件为预览流提供Surface,再通过获取XComponent组件对应Surface的ID创建预览流,预览流画面即可直接在XComponent组件内渲染,上述xComponentSurfaceId即为XComponent组件为预览创建的SurfaceId。
5)启动预览或采集
预览是启动相机后看见的画面,通常在录像前执行,启动相机会话,获取预览流数据。
6)资源释放
视频的采集除了ArkTS接口外,也提供了C/C++接口,开发者可以导入NDK接口,在CMake脚本中链接相关动态库,调用C/C++接口来完成上述同样的功能。
二.音频的采集
鸿蒙系统提供了多样化的API,来帮助开发者完成音频录制的开发,不同的API适用于不同音频使用场景或不同开发语言。因此,选择合适的音频录制API,有助于降低开发工作量,实现更佳的音频录制效果。
1) AudioCapturer:用于音频输入的ArkTS/JS API,仅支持PCM格式,需要应用持续读取音频数据进行工作。应用可以在音频输出后添加数据处理,适用于更专业、更多样化的媒体录制应用开发。
2) OpenSL ES:一套跨平台标准化的音频Native API,同样提供音频输入原子能力,仅支持PCM格式,适用于从其他嵌入式平台移植,或依赖在Native层实现音频输入功能的录音应用使用。
3) OHAudio:用于音频输入的Native API,此API在设计上实现归一,同时支持普通音频通路和低时延通路。仅支持PCM格式,适用于依赖Native层实现音频输入功能的场景。
但是,由于OpenSL ES无法满足音频系统的能力拓展,官方建议开发者使用OHAudio替代OpenSL ES开发音频业务。OHAudio与OpenSL ES支持的功能范围也略有差异,OHAudio增加支持低时延播放/录制、监听业务变化等功能,OpenSL ES目前尚未支持。
本文着重以AudioCapturer为例讲解如何开发音频录制功能。使用AudioCapturer录制音频涉及到AudioCapturer实例的创建、音频采集参数的配置、采集的开始与停止、资源的释放等,开发步骤如下:
创建AudioCapturer实例
当设置Mic音频源(即SourceType为SOURCE_TYPE_MIC、SOURCE_TYPE_VOICE_RECOGNITION、SOURCE_TYPE_VOICE_COMMUNICATION、SOURCE_TYPE_VOICE_MESSAGE)时,需要申请麦克风权限ohos.permission.MICROPHONE,也需要在运行时,通过弹窗动态请求用户授权。
其中,audioCapturerOptions为音频参数,可以设置音频采集的采样率、通道数、采样格式等信息。
订阅监听音频数据读入回调
在处理数据时,不建议使用多线程来处理数据读取,readData方法所的线程中,也不建议执行耗时任务,否则可能会导致数据处理线程响应回调延迟,进而引发录音数据缺失,造成卡顿杂音等音频问题。
调用start()方法开始录制音频
调用stop()方法停止录制
调用release()方法销毁实例释放资源
通过以上步骤,可以正确使用 AudioCapturer 实现应用中的音频采集功能。实际开发中,建议结合官方文档和具体场景调整参数与处理逻辑。
OHAudio是系统在API version 10中引入的一套C API,此API在设计上实现归一,同时支持普通音频通路和低时延通路。仅支持PCM格式,适用于依赖Native层实现音频输入功能的场景,有需要的开发者可以参考官方API进行开发。
三. 音视频播放
鸿蒙系统为音视频播放提供了2个系统播放器,AVPlayer(播放音视频)和SoundPool(播放短音频)。使用SoundPool可以实现简单的提示音,当设备接收到新消息时,会发出短促的“滴滴”声;使用AVPlayer实现音乐(或视频)播放器,循环播放一首音乐或播一段视频,本文主要以AVPlayer为例进行说明。
AVPlayer主要工作是将Audio/Video媒体资源(比如mp4/mp3/mkv/mpeg-ts等)转码为可供渲染的图像和可听见的音频模拟信号,并通过输出设备进行播放。AVPlayer提供功能完善一体化播放能力,应用只需要提供流媒体来源,不负责数据解析和解码就可达成播放效果,AVPlayer与外部模块的交互关系如图所示。
图3 AVPlayer交互关系图
AVPlayer不建议应用开发者自制码流进行测试,以免产生无法播放、卡顿、花屏等兼容性问题。若发生此类问题不会影响系统,退出播放即可。
AVPlayer支持的协议如下:
协议类型 | 协议描述 |
本地点播 | 协议格式:支持file descriptor,禁止file path |
网络点播 | 协议格式:支持http/https/hls/dash |
网络直播 | 协议格式:支持hls/http-flv |
AVPlayer支持的音频播放格式如下:
音频容器规格 | 规格描述 |
m4a | 音频格式:AAC |
aac | 音频格式:AAC |
mp3 | 音频格式:MP3 |
ogg | 音频格式:VORBIS |
wav | 音频格式:PCM |
amr | 音频格式:AMR |
ape | 音频格式:APE |
AVPlayer支持的视频播放格式和主流分辨率如下:
视频容器规格 | 规格描述 | 分辨率 |
mp4 | 视频格式:H265/H264 音频格式:AAC/MP3 | 主流分辨率,如4K/1080P/720P/480P/270P |
mkv | 视频格式:H265/H264 音频格式:AAC/MP3 | 主流分辨率,如4K/1080P/720P/480P/270P |
ts | 视频格式:H265/H264 音频格式:AAC/MP3 | 主流分辨率,如4K/1080P/720P/480P/270P |
AVPlayer支持的字幕格式如下:
字幕容器规格 | 支持的协议 | 支持的加载方式 |
srt | 本地点播(fd)/网络点播(http/https/hls/dash) | 外挂字幕 |
vtt | 本地点播(fd)/网络点播(http/https/hls/dash) | 外挂字幕 |
webvtt | 网络点播(dash协议) | 内置字幕 |
AVPlayer开发步骤如下:
创建AVPlayer实例
调用createAVPlayer()方法创建AVPlayer实例,AVPlayer初始化后为idle状态。
设置业务需要的监听事件
根据业务需要,开发者可选择设置需要的监听事件,搭配全流程场景使用。
设置播放资源
AVPlayer支持本地资源的播放,也支持使用网络播放路径。如果使用本地资源播放,必须确认资源文件可用,并使用应用沙箱路径访问对应资源。如果使用网络播放路径,需声明权限:ohos.permission.INTERNET。
准备播放
如果是播放视频,需要先设置视频窗口。需要从XComponent组件获取surfaceID,用于显示画面。
播放控制:播放play(),暂停pause(),跳转seek(),停止stop()
更换资源(可选):调用reset()重置资源,允许更换播放资源url
如果播放过程中需要更换新的资源,可以先调用reset()方法,然后更新播放资源即可。
退出播放并销毁资源
AVPlayer提供了较为齐全的播放功能,基本能满足业务大多数的播放需求,但也存在以下的局限性。
1)缺乏本地缓存机制
默认仅通过内存缓冲区实现边播边缓存,数据不会持久化到沙箱。如果需要缓存场景必须依赖第三方库(如OhosVideoCache)实现本地存储,增加开发复杂度。
2)后台播放限制
未接入Background Tasks Kit时,后台播放可能被系统中断。需要额外开发长时任务管理逻辑才能实现稳定的后台播放。
3)协议与格式支持局限
流媒体协议支持程度依赖系统版本,部分特殊编码格式需要单独适配。DRM内容播放需要额外接入版权保护模块。