codecamp

鸿蒙OS 视频编解码开发指导

场景介绍

视频编解码的主要工作是将视频进行编码和解码。

接口说明

接口名 功能描述
createDecoder() 创建解码器Codec实例。
createEncoder() 创建编码器Codec实例。
registerCodecListener(ICodecListener listener) 注册侦听器用来异步接收编码或解码后的数据。
setSource(Source source, TrackInfo trackInfo) 根据解码器的源轨道信息设置数据源,对于编码器trackInfo无效。
setSourceFormat(Format format) 编码器的管道模式下,设置编码器编码格式。
setCodecFormat(Format format) 普通模式设置编/解码器参数。
setVideoSurface(Surface surface) 设置解码器的Surface。
getAvailableBuffer(long timeout) 普通模式获取可用ByteBuffer。
writeBuffer(ByteBuffer buffer, BufferInfo info) 推送源数据给Codec。
getBufferFormat(ByteBuffer buffer) 获取输出Buffer数据格式。
start() 启动编/解码。
stop() 停止编/解码。
release() 释放所有资源。

普通模式开发步骤

在普通模式下进行编解码,应用必须持续地传输数据到 Codec 实例。

编码的具体开发步骤如下

  1. 创建编码 Codec 实例,可调用 createEncoder() 创建。

   final Codec encoder = Codec.createEncoder();

  1. 构造数据源格式,并设置给 Codec 实例,调用 setCodecFormat(),代码示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setCodecFormat(fmt);

  1. 如果需要编码过程中,检测是否读取到 Buffer 数据以及是否发生异常,可以构造 ICodecListener, ICodecListener 需要实现两个方法,实现读到 Buffer 数据时、编码发生异常时做相应的操作。举例中读到 buffer 时,获取 buffer 的 format 格式,异常时抛出运行时异常,代码示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 调用 start() 方法开始编码。

  1. 调用 getAvailableBuffer() 取到一个可用的 ByteBuffer,把数据填入 ByteBuffer 里,然后再调用 writeBuffer() 把 ByteBuffer 写入编码器实例。

  1. 调用 stop() 方法停止编码。

  1. 编码任务结束后,调用 release() 释放资源。

解码的具体开发步骤如下:

  1. 创建解码 Codec 实例,可调用 createDecoder() 创建。

  1. 构造数据源格式,并设置给 Codec 实例,调用 setCodecFormat(),代码示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setCodecFormat(fmt);

  1. (可选)如果需要解码过程中,检测是否读取到 Buffer 数据以及是否发生异常,可以构造 ICodecListener,ICodecListener 需要实现两个方法,实现读到 Buffer 数据时、解码发生异常时做相应的操作。举例中读到 buffer 时,获取 buffer 的 format 格式,异常时抛出运行时异常,代码示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 调用 start() 方法开始解码。

  1. 调用 getAvailableBuffer 取到一个可用的 ByteBuffer,把数据填入 ByteBuffer 里,然后再调用 writeBuffer 把 ByteBuffer 写入解码器实例。

  1. 调用 stop() 方法停止解码。

  1. 解码任务结束后,调用 release() 释放资源。

管道模式开发步骤

管道模式下应用只需要调用 Source 类的 setSource() 方法,数据会自动解析并传输给 Codec 实例。管道模式编码支持视频流编码和音频流编码。

编码的具体开发步骤如下:

  1. 调用 createEncoder() 创建编码 Codec 实例。

  1. 调用 setSource() 设置数据源,支持设定文件路径或者文件 File Descriptor。

  1. 构造数据源格式或者从 Extractor 中读取数据源格式,并设置给 Codec 实例,调用 setSourceFormat(),构造数据原格式代码示例如下:

   Format fmt = new Format();
   fmt.putStringValue(Format.MIME, Format.VIDEO_AVC);
   fmt.putIntValue(Format.WIDTH, 1920);
   fmt.putIntValue(Format.HEIGHT, 1080);
   fmt.putIntValue(Format.BIT_RATE, 392000);
   fmt.putIntValue(Format.FRAME_RATE, 30);
   fmt.putIntValue(Format.FRAME_INTERVAL, -1);
   codec.setSourceFormat(fmt);

  1. (可选)如果需要编码过程中,检测是否读取到 Buffer 数据以及是否发生异常,可以构造 ICodecListener,ICodecListener 需要实现两个方法,实现读到 Buffer 数据时、编码发生异常时做相应的操作。举例中读到 buffer 时,获取 buffer 的 format 格式,异常时抛出运行时异常,代码示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 调用 start() 方法开始编码。

  1. 调用 stop() 方法停止编码。

  1. 编码任务结束后,调用 release() 释放资源。

解码的具体开发步骤如下:

  1. 调用 createDecoder()创建解码 Codec 实例。

  1. 调用 setSource()设置数据源,支持设定文件路径或者文件 File Descriptor。

  1. (可选)如果需要解码过程中,检测是否读取到 Buffer数据以及是否发生异常,可以构造 ICodecListener,ICodecListener 需要实现两个方法,实现读到 Buffer 数据时、解码发生异常时做相应的操作。举例中读到 buffer 时,获取 buffer 的 format 格式,异常时抛出运行时异常,代码示例如下:

   Codec.ICodecListener listener = new Codec.ICodecListener() {
       @Override
       public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
           Format fmt = codec.getBufferFormat(byteBuffer);
       }

    
       @Override
       public void onError(int errorCode, int act, int trackId) {
           throw new RuntimeException();
       }
   };

  1. 调用 start() 方法开始解码。

  1. 调用 stop() 方法停止解码。

  1. 解码任务结束后,调用 release() 释放资源。
鸿蒙OS 媒体编解码能力查询开发指导
鸿蒙OS 视频播放开发指导
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

鸿蒙OS 开发

鸿蒙OS 术语

鸿蒙OS Java API参考

鸿蒙OS ohos.aafwk.ability

鸿蒙OS ohos.aafwk.abilityjet.activedata

鸿蒙OS ohos.aafwk.content

鸿蒙OS java.lang

鸿蒙OS java.Util

鸿蒙OS java.Util class

鸿蒙OS ohos.data.dataability

鸿蒙OS ohos.data.dataability class

鸿蒙OS ohos.agp.components

鸿蒙OS ohos.agp.components interface

鸿蒙OS ohos.agp.components class

鸿蒙OS ohos.global.configuration

鸿蒙OS java.io

鸿蒙OS ohos.data.resultset

鸿蒙OS ohos.data.resultset interface

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }