diff --git a/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder.png b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder.png new file mode 100644 index 0000000000000000000000000000000000000000..4ebc911893f4ebeb4bd914df5b94f24bf1787907 Binary files /dev/null and b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder.png differ diff --git a/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder_machine.png b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder_machine.png new file mode 100644 index 0000000000000000000000000000000000000000..b836458d068acc56f31d5d867d6565a6eb6884bf Binary files /dev/null and b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_encoder_machine.png differ diff --git a/zh-cn/application-dev/media/video-encoder.md b/zh-cn/application-dev/media/video-encoder.md new file mode 100644 index 0000000000000000000000000000000000000000..491b6c5f0b309c713cc4024cef221824a0ea60e6 --- /dev/null +++ b/zh-cn/application-dev/media/video-encoder.md @@ -0,0 +1,140 @@ +# 视频编码开发指导 + +## 场景介绍 + +视频编码的主要工作是对原始视频数据进行压缩编码。 + +**图1** 视频编码状态机 + +![zh-ch_image_image_video_encoder_machine](figures/zh-ch_image_image_video_encoder_machine.png) + +**图2** 视频编码零层图 + +![zh-ch_image_image_video_encoder](figures/zh-ch_image_image_video_encoder.png) + +## 视频编码开发步骤 + +详细API含义可参考:[js-apis-media.md](../reference/apis/js-apis-media.md)的VideoEncoderProcessor。 + +### 全流程场景 + +包含流程:创建编码器、设置监听事件、配置媒体信息、获取surfaceID并配置给数据源、准备编码、开始编码、获取编码后数据的媒体信息、清空缓存、停止编码、重置编码器、销毁编码器。 + +```js +/* 用于打印编码后数据的媒体信息 */ +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoEncoder key is ' + item); + console.info('videoEncoder value is ' + property); + } +} + +/* 设置订阅事件回调函数 */ +function SetCallback() { + videoEncoder.on('outputAvailable', (buffer) => { + console.info('videoEncoder outputAvailable'); + /* 根据业务场景消费buffer */ + /* 消费完毕,将buffer归还给编码器,调用该接口后,不得再对buffer进行读写操作 */ + videoEncoder.releaseOutput(buffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder releaseOutput success'); + } else { + console.info(`videoEncoder releaseOutput fail, errMessage:${error.message}`); + } + }); + }); + + videoEncoder.on('error', (error) => { + console.info(`error happened, errName is ${error.name}`); + console.info(`error happened, errCode is ${error.code}`); + console.info(`error happened, errMessage is ${error.message}`); + }); + + videoEncoder.on('outputFormatChanged', (format) => { + if (typeof(format) != 'undefined') { + printfDescription(format); + } + }); +} + +/* 函数调用发生错误时用于上报错误信息 */ +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} + +/* 函数调用发生异常时用于上报错误信息 */ +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +let videoEncoder = undefined; +let surfaceID = undefined; +let mediaDescription = { + "width": 1920, + "height": 1080, + "pixel_format": media.VideoPixelformat.NV21, + "frame_rate": 60.00, +} + +/* 1.创建编码器 */ +await media.createVideoEncoderByMime(media.CodecMimeType.VIDEO_AVC).then((encoder) => { + if (typeof(encoder) != 'undefined') { + videoEncoder = encoder; + console.info('videoEncoder createVideoEncoderByMime success'); + } else { + console.info('videoEncoder createVideoEncoderByMime fail'); + } +}, failureCallback).catch(catchCallback); + +/* 2.设置监听事件 */ +SetCallback(); + +/* 3.配置媒体信息 */ +await videoEncoder.configure(mediaDescription).then(() => { + console.log('videoEncoder configure success'); +}, failureCallback).catch(catchCallback); + +/* 4.获取surfaceID并配置给数据源 */ +await videoEncoder.getInputSurface().then((id) => { + /* 将surfaceID配置给数据源 */ +}, failureCallback).catch(catchCallback); + +/* 5.准备编码 */ +await videoEncoder.prepare().then(() => { + console.log('videoEncoder prepare success'); +}, failureCallback).catch(catchCallback); + +/* 6.开始编码 */ +await videoEncoder.start().then(() => { + console.log('videoEncoder start success'); +}, failureCallback).catch(catchCallback); + +/* 7.获取编码后数据的媒体信息 */ +await videoEncoder.getOutputMediaDescription().then((mediaDescription) => { + console.log('videoEncoder getOutputMediaDescription success'); + printfDescription(mediaDescription); +}, failureCallback).catch(catchCallback); + +/* 8.清空缓存,调用该接口后,所有buffer将归还给编码器,应用不得继续使用 */ +await videoEncoder.flush().then(() => { + console.log('videoEncoder flush success'); +}, failureCallback).catch(catchCallback); + +/* 9.停止编码 */ +await videoEncoder.stop().then(() => { + console.log('videoEncoder stop success'); +}, failureCallback).catch(catchCallback); + +/* 10.重置编码器 */ +await videoEncoder.reset().then(() => { + console.log('videoEncoder reset success'); +}, failureCallback).catch(catchCallback); + +/* 11.销毁编码器 */ +await videoEncoder.release().then(() => { + console.log('videoEncoder release success'); +}, failureCallback).catch(catchCallback); +videoEncoder = undefined; +``` + diff --git a/zh-cn/application-dev/reference/apis/js-apis-media.md b/zh-cn/application-dev/reference/apis/js-apis-media.md index 8855a83325232bff6fa06fdcf142f17f9100f307..a7e9787cf017c2eee224afe3c79b392342d09a19 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-media.md +++ b/zh-cn/application-dev/reference/apis/js-apis-media.md @@ -6,6 +6,7 @@ - 音频播放([AudioPlayer](#audioplayer)) - 音频录制([AudioRecorder](#audiorecorder)) +- 视频编码([VideoEncoderProcessor](#videoencodeprocessor8)) 后续将提供以下功能:视频播放、视频录制、DataSource音视频播放、音视频编解码、容器封装解封装、媒体能力查询等功能。 @@ -90,7 +91,136 @@ await media.createAudioPlayerAsync.then((audio) => { }, failureCallback).catch(catchCallback); ``` +## media.createVideoEncoderByName8+ + +createVideoEncoderByName(name: string, callback: AsyncCallback<[VideoEncodeProcessor](#videoencodeprocessor8)>): void + +通过编码器名称,创建指定的视频编码器实例。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------------------ | ---- | ------------------------------ | +| name | string | 是 | 编码器名称。 | +| callback | AsyncCallback<[VideoEncodeProcessor](#videoencodeprocessor8)> | 是 | 接口调用的回调函数,包含视频编码器实例。 | + +**示例:** + +```js +media.createVideoEncoderByName('avenc_mpeg4', (error, encoder) => { + if (typeof(encoder) != 'undefined') { + videoEncoder = encoder; + console.info('videoEncoder createVideoEncoderByName success'); + } else { + console.info(`videoEncoder createVideoEncoderByName fail, error:${error.message}`); + } +}); +``` + +## media.createVideoEncoderByName8+ + +createVideoEncoderByName(name: string): Promise<[VideoEncodeProcessor](#videoencodeprocessor8)> + +通过编码器名称,创建指定的视频编码器实例。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------- | +| name | string | 是 | 编码器名称。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------------- | ----------------------------------- | +| Promise<[VideoEncodeProcessor](#videoencodeprocessor8)> | 接口调用的返回值,包含视频编码器实例。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await media.createVideoEncoderByName('avenc_mpeg4').then((encoder) => { + if (typeof(encoder) != 'undefined') { + videoEncoder = encoder; + console.info('videoEncoder createVideoEncoderByName success'); + } else { + console.info('videoEncoder createVideoEncoderByName fail'); + } +}, failureCallback).catch(catchCallback); +``` + +## media.createVideoEncoderByMime8+ + +createVideoEncoderByMime(codecMime: string, callback: AsyncCallback<[VideoEncodeProcessor](#videoencodeprocessor8)>) + +根据[CodecMimeType](#codecmimetype8),创建优选的视频编码器实例。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------------------------------------------ | ---- | ----------------------------------------------------------- | +| codecMime | string | 是 | MIME类型,具体可参考[CodecMimeType](#codecmimetype8)。 | +| callback | AsyncCallback<[VideoEncodeProcessor](#videoencodeprocessor8)> | 是 | 接口调用的回调函数,包含视频编码器实例。| + +**示例:** + +```js +media.createVideoEncoderByMime('video/avc', (error, encoder) => { + if (typeof(encoder) != 'undefined') { + videoEncoder = encoder; + console.info('videoEncoder createVideoEncoderByMime success'); + } else { + console.info(`videoEncoder createVideoEncoderByMime fail, error:${error.message}`); + } +}); +``` + +## media.createVideoEncoderByMime8+ + +createVideoEncoderByMime(name: string): Promise<[VideoEncodeProcessor](#videoencodeprocessor8)> + +根据[CodecMimeType](#codecmimetype8),创建优选的视频编码器实例。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------- | +| codecMime | string | 是 | MIME类型,具体可参考[CodecMimeType](#codecmimetype8)。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------------- | ----------------------------------- | +| Promise<[VideoEncodeProcessor](#videoencodeprocessor8)> | 接口调用的返回值,包含视频编码器实例。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await media.createVideoEncoderByMime('video/avc').then((encoder) => { + if (typeof(encoder) != 'undefined') { + videoEncoder = encoder; + console.info('videoEncoder createVideoEncoderByMime success'); + } else { + console.info('videoEncoder createVideoEncoderByMime fail'); + } +}, failureCallback).catch(catchCallback); +``` + ## media.createAudioRecorder + createAudioRecorder(): AudioRecorder 创建音频录制的实例来控制音频的录制。 @@ -104,7 +234,7 @@ createAudioRecorder(): AudioRecorder **示例:** ``` -var audiorecorder = media.createAudioRecorder(); +var audiorecorder = media.createAudioRecorder(); ``` ## MediaErrorCode8+ @@ -423,24 +553,24 @@ on(type: 'play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeCh ```js let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 - console.info('audio set source success'); + console.info('audio set source success'); audioPlayer.play(); //开始播放,并触发'play'事件回调 }); audioPlayer.on('play', () => { //设置'play'事件回调 - console.info('audio play success'); + console.info('audio play success'); audioPlayer.seek(30000); //调用seek方法,并触发'timeUpdate'事件回调 }); audioPlayer.on('pause', () => { //设置'pause'事件回调 - console.info('audio pause success'); + console.info('audio pause success'); audioPlayer.stop(); //停止播放,并触发'stop'事件回调 }); audioPlayer.on('reset', () => { //设置'reset'事件回调 - console.info('audio reset success'); + console.info('audio reset success'); audioPlayer.release(); //释放播放实例资源 audioPlayer = undefined; }); audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 - if (typeof(seekDoneTime) == "undefined") { + if (typeof(seekDoneTime) == "undefined") { console.info('audio seek fail'); return; } @@ -448,15 +578,15 @@ audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回 audioPlayer.setVolume(0.5); //设置音量为50%,并触发'volumeChange'事件回调 }); audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 - console.info('audio volumeChange success'); + console.info('audio volumeChange success'); audioPlayer.pause(); //暂停播放,并触发'pause'事件回调 }); audioPlayer.on('finish', () => { //设置'finish'事件回调 - console.info('audio play finish'); + console.info('audio play finish'); audioPlayer.stop(); //停止播放,并触发'stop'事件回调 }); audioPlayer.on('error', (error) => { //设置'error'事件回调 - console.info(`audio error called, errName is ${error.name}`); + console.info(`audio error called, errName is ${error.name}`); console.info(`audio error called, errCode is ${error.code}`); console.info(`audio error called, errMessage is ${error.message}`); }); @@ -506,7 +636,7 @@ on(type: 'error', callback: ErrorCallback): void ```js audioPlayer.on('error', (error) => { //设置'error'事件回调 - console.info(`audio error called, errName is ${error.name}`); //打印错误类型名称 + console.info(`audio error called, errName is ${error.name}`); //打印错误类型名称 console.info(`audio error called, errCode is ${error.code}`); //打印错误码 console.info(`audio error called, errMessage is ${error.message}`);//打印错误类型详细描述 }); @@ -703,4 +833,768 @@ on(type: 'error', callback: ErrorCallback): void | 名称 | 默认值 | 说明 | | -------- | ------ | ------------------------------------------------------------ | | MPEG_4 | 2 | 封装为MPEG-4格式。 | -| AAC_ADTS | 6 | 封装为ADTS(Audio Data Transport Stream)格式,是AAC音频的传输流格式。 | \ No newline at end of file +| AAC_ADTS | 6 | 封装为ADTS(Audio Data Transport Stream)格式,是AAC音频的传输流格式。 | + +## VideoEncodeProcessor8+ + +视频编码管理类,在调用VideoEncodeProcessor的方法前,需要先通过[createVideoEncoderByName()](#media.createvideoencoderbyname8)或[createVideoEncoderByMime()](#media.createvideoencoderbymime8)构建一个[VideoEncodeProcessor](#videoencodeprocessor8)实例。 + +视频编码demo可参考:[视频编码开发指导](../../media/video-encoder.md) + +### configure8+ + +configure(desc: [MediaDescription](#mediadescription8), callback: AsyncCallback\): void + +配置媒体信息。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。
必须设置的媒体信息:MD_KEY_WIDTH、MD_KEY_HEIGHT、MD_KEY_FRAME_RATE、MD_KEY_PIXEL_FORMAT。 | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +let mediaDescription = { + "width": 1920, + "height": 1080, + "pixel_format": media.VideoPixelformat.NV21, + "frame_rate": 60.00, +} +videoEncoder.configure(mediaDescription, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder configure success'); + } else { + console.info(`videoEncoder configure fail, errMessage:${error.message}`); + } +}); +``` + +### configure8+ + +configure(desc: [MediaDescription](#mediadescription8)): Promise\ + +配置媒体信息。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。
必须设置的媒体信息:MD_KEY_WIDTH、MD_KEY_HEIGHT、MD_KEY_FRAME_RATE、MD_KEY_PIXEL_FORMAT。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 接口调用的返回值。| + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +let mediaDescription = { + "width": 1920, + "height": 1080, + "pixel_format": media.VideoPixelformat.NV21, + "frame_rate": 60.00, +} +await videoEncoder.configure(mediaDescription).then(() => { + console.log('videoEncoder configure success'); +}, failureCallback).catch(catchCallback); +``` + +### prepare8+ + +prepare(callback: AsyncCallback\): void + +准备编码。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.prepare((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder prepare success'); + } else { + console.info(`videoEncoder prepare fail, errMessage:${error.message}`); + } +}); +``` + +### prepare8+ + +prepare(): Promise\ + +准备编码。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.prepare().then(() => { + console.log('videoEncoder prepare success'); +}, failureCallback).catch(catchCallback); +``` + +### start8+ + +start(callback: AsyncCallback\): void + +开始编码。在start()方法调用前需订阅[outputAvailable](#videoencodeprocessor_on_outputavailable)事件。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.start((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder start success'); + } else { + console.info(`videoEncoder start fail, errMessage:${error.message}`); + } +}); +``` + +### start8+ + +start(): Promise\ + +开始编码。在start()方法调用前需订阅[outputAvailable](#videoencodeprocessor_on_outputavailable)事件。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.start().then(() => { + console.log('videoEncoder start success'); +}, failureCallback).catch(catchCallback); +``` + +### stop8+ + +stop(callback: AsyncCallback\): void + +停止编码。可调用[start()](#videoencodeprocessor_start1)继续编码。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.stop((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder stop success'); + } else { + console.info(`videoEncoder stop fail, errMessage:${error.message}`); + } +}); +``` + +### stop8+ + +stop: Promise\ + +停止编码。可调用[start()](#videoencodeprocessor_start1)继续编码。通过注册回调函数获取返回值。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.stop().then(() => { + console.log('videoEncoder stop success'); +}, failureCallback).catch(catchCallback); +``` + +### flush8+ + +flush(callback: AsyncCallback\): void + +清空缓存队列。调用该接口后,不能使用之前通过[outputAvailable](#videoencodeprocessor_on_outputavailable)获取的buffer。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.flush((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder flush success'); + } else { + console.info(`videoEncoder flush fail, errMessage:${error.message}`); + } +}); +``` + +### flush8+ + +flush(): Promise\ + +清空缓存队列。调用该接口后,不能使用之前通过[outputAvailable](#videoencodeprocessor_on_outputavailable)获取的buffer。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | ----------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.flush().then(() => { + console.log('videoEncoder flush success'); +}, failureCallback).catch(catchCallback); +``` + +### reset8+ + +reset(callback: AsyncCallback\): void + +重置编码器。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.reset((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder reset success'); + } else { + console.info(`videoEncoder reset fail, errMessage:${error.message}`); + } +}); +``` + +### reset8+ + +reset(): Promise\ + +重置编码器。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.reset().then(() => { + console.log('videoEncoder reset success'); +}, failureCallback).catch(catchCallback); +``` + +### release8+ + +release(callback: AsyncCallback\): void + +释放编码器资源。应用需手动release,不能依赖内存回收机制。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.release((error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder release success'); + videoEncoder = undefined; + } else { + console.info(`videoEncoder release fail, errMessage:${error.message}`); + } +}); +``` + +### release8+ + +release(): Promise\ + +释放编码器资源。应用需手动release,不能依赖内存回收机制。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.release().then(() => { + console.log('videoEncoder release success'); +}, failureCallback).catch(catchCallback); +videoEncoder = undefined; +``` + +### releaseOutput8+ + +releaseOutput(buffer: [CodecBuffer](#codecbuffer8), callback: AsyncCallback\): void + +将输出buffer归还给编码器。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | -------------------------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 输出buffer。 | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.on('outputAvailable', (outputBuffer) => { + videoEncoder.releaseOutput(outputBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder releaseOutput success'); + } else { + console.info(`videoEncoder releaseOutput fail, errMessage:${error.message}`); + } + }); +}); +``` + +### releaseOutput8+ + +releaseOutput(buffer: [CodecBuffer](#codecbuffer8)): Promise\ + +将输出buffer归还给编码器。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | -------------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 输出buffer。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +videoEncoder.on('outputAvailable', (outputBuffer) => { + await videoEncoder.releaseOutput(outputBuffer).then(() => { + console.log('videoEncoder releaseOutput success'); + }, failureCallback).catch(catchCallback); +}); +``` + +### setParameter8+ + +setParameter(desc: [MediaDescription](#mediadescription8), callback: AsyncCallback\): void + +动态设置媒体信息,是否生效依赖于硬件平台。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。 | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数。| + +**示例:** + +```js +let mediaDescription = { + "req_i_frame" : 1, // 动态请求I帧 +} + +videoEncoder.setParameter(mediaDescription, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder setParameter success'); + } else { + console.info(`videoEncoder setParameter fail, errMessage:${error.message}`); + } +}); +``` + +### setParameter8+ + +setParameter(desc: [MediaDescription](#mediadescription8)): Promise\ + +动态设置媒体信息,是否生效依赖于硬件平台。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------------------- | +| Promise\ | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +let mediaDescription = { + "req_i_frame" : 1, // 动态请求I帧 +} + +await videoEncoder.setParameter(mediaDescription).then(() => { + console.log('videoEncoder setParameter success'); +}, failureCallback).catch(catchCallback); +``` + +### getInputSurface8+ + +getInputSurface(callback: AsyncCallback\): void + +获取用作编码输入源的surface的ID。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------------------- | ---- | ---------------------------------------- | +| callback | AsyncCallback\ | 是 | 接口调用的回调函数,包含surfaceID。 | + +**示例:** + +```js +videoEncoder.getInputSurface((error, id) => { + /* 将surfaceID配置给数据源 */ +}); +``` + +### getInputSurface8+ + +getInputSurface(): Promise\ + +获取用作编码输入源的surface的ID。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------------------- | +| Promise\ | 接口调用的返回值,包含surfaceID。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.getInputSurface().then((id) => { + console.log('videoEncoder getInputSurface success'); + /* 将surfaceID配置给数据源 */ +}, failureCallback).catch(catchCallback); +``` + +### getOutputMediaDescription8+ + +getOutputMediaDescription(callback: AsyncCallback<[MediaDescription](#mediadescription8)>): void + +获取输出buffer的媒体信息。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------------------- | ---- | ---------------------------------------- | +| callback | AsyncCallback<[MediaDescription](#mediadescription8)> | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoEncoder key is ' + item); + console.info('videoEncoder value is ' + property); + } +} + +videoEncoder.getOutputMediaDescription((error, mediaDescription) => { + if (typeof(mediaDescription) != 'undefined') { + console.log('videoEncoder getOutputMediaDescription success'); + printfDescription(mediaDescription); + } else { + console.log('videoEncoder getOutputMediaDescription fail'); + } +}); +``` + +### getOutputMediaDescription8+ + +getOutputMediaDescription(): Promise<[MediaDescription](#mediadescription8)> + +获取输出buffer的媒体信息。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------------------- | +| Promise<[MediaDescription](#mediadescription8)> | 接口调用的返回值。 | + +**示例:** + +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoEncoder key is ' + item); + console.info('videoEncoder value is ' + property); + } +} +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.getOutputMediaDescription().then((mediaDescription) => { + console.log('videoEncoder getOutputMediaDescription success'); + printfDescription(mediaDescription); +}, failureCallback).catch(catchCallback); +``` + +### getVideoEncoderCaps8+ + +getVideoEncoderCaps(callback: AsyncCallback<[VideoCaps](#videocaps8)>): void + +获取编码器能力。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------------- | ---- | ------------------------------ | +| callback | AsyncCallback<[VideoCaps](#videocaps8)> | 是 | 接口调用的回调函数。 | + +**示例:** + +```js +videoEncoder.getVideoEncoderCaps((error, videoCaps) => { + if (typeof(videoCaps) != 'undefined') { + console.log('videoEncoder getVideoEncoderCaps success'); + printfDescription(mediaDescription); + } else { + console.log('videoEncoder getVideoEncoderCaps fail'); + } +}); +``` + +### getVideoEncoderCaps8+ + +getVideoEncoder(): Promise<[VideoCaps](#videocaps8)> + +获取编码器能力。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------- | +| Promise<[VideoCaps](#videocaps8)> | 接口调用的返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoEncoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoEncoder catchCallback, error:${error.message}`); +} + +await videoEncoder.getVideoEncoderCaps().then((videoCaps) => { + console.log('videoEncoder getVideoEncoderCaps success'); +}, failureCallback).catch(catchCallback); +``` + +### on('error')8+ + +on(type: 'error', callback: ErrorCallback<[CodecError](#codecerror8)>): void + +订阅视频编码错误事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件名称。 | +| callback | ErrorCallback<[CodecError](#codecerror8)> | 是 | 错误信息。 | + +**示例:** + +```js +videoEncoder.on('error', (error) => { + console.info(`error happened, errName is ${error.name}`); + console.info(`error happened, errCode is ${error.code}`); + console.info(`error happened, errMessage is ${error.message}`); +}); +``` + +### on('outputFormatChanged')8+ + +on(type: 'outputFormatChanged', callback: Callback<[MediaDescription](#mediadescription8)>) + +订阅输出buffer的媒体信息变化事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------ | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件名称。 | +| callback | Callback<[MediaDescription](#mediadescription8)> | 是 | 输出buffer的媒体信息。 | + +**示例:** + +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoEncoder key is ' + item); + console.info('videoEncoder value is ' + property); + } +} + +videoEncoder.on('outputFormatChanged', (format) => { + if (typeof(format) != 'undefined') { + printfDescription(format); + } +}); +``` + +### on('outputAvailable')8+ + +on(type: 'outputAvailable', callback: Callback<[CodecBuffer](#codecbuffer8)>) + +订阅输出buffer事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 事件名称。 | +| callback | Callback<[CodecBuffer](#codecbuffer8)> | 是 | 输出buffer。 | + +**示例:** + +```js +videoEncoder.on('outputAvailable', (outBuffer) => { + console.info('videoEncoder outputAvailable'); + /* 根据业务场景消费buffer */ + /* 消费完毕,将buffer归还给编码器,调用该接口后,不能再对buffer进行读写操作 */ + videoEncoder.releaseOutput(outBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoEncoder releaseOutput success'); + } else { + console.info(`videoEncoder releaseOutput fail, errMessage:${error.message}`); + } + }); +}); +``` \ No newline at end of file