diff --git a/zh-cn/application-dev/media/Readme-CN.md b/zh-cn/application-dev/media/Readme-CN.md index f4c1c506f20fc22be84dc8822ab63b20a9f3d4b2..230a66423de529e007dbd394a9feffcc2894b291 100755 --- a/zh-cn/application-dev/media/Readme-CN.md +++ b/zh-cn/application-dev/media/Readme-CN.md @@ -1,3 +1,7 @@ +--- + +--- + # 媒体 - 音频 @@ -6,3 +10,6 @@ - [音频管理开发指导](audio-management.md) - [音频录制开发指导](audio-recorder.md) +- 视频 + - [视频解码开发指导](video-decoder.md) + diff --git a/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder.png b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder.png new file mode 100644 index 0000000000000000000000000000000000000000..14fd8f2cb91c5851b5038235cbe8039f776551a7 Binary files /dev/null and b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder.png differ diff --git a/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder_machine.jpg b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder_machine.jpg new file mode 100644 index 0000000000000000000000000000000000000000..53fa93485e779d22500d6c2d2d32e0a32636fa58 Binary files /dev/null and b/zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder_machine.jpg differ diff --git a/zh-cn/application-dev/media/video-decoder.md b/zh-cn/application-dev/media/video-decoder.md new file mode 100644 index 0000000000000000000000000000000000000000..582cc534bf59b57be732e54c7e67ea0dd7aeb503 --- /dev/null +++ b/zh-cn/application-dev/media/video-decoder.md @@ -0,0 +1,251 @@ +# 视频解码开发指导 + +## 场景介绍 + +视频解码的主要工作是将编码后的数据解码为原始数据,同时对视频解码任务进行管理。 + +**图1** 视频解码状态机 + +![zh-ch_image_image_video_decoder_machine](figures/zh-ch_image_image_video_decoder_machine.jpg) + +## 视频解码零层图 + +**图2** 视频解码零层图 + +![zh-ch_image_image_video_decoder](figures/zh-ch_image_image_video_decoder.png) + +*注意:视频解码需要显示、解码等硬件能力。 + +## 视频解码开发步骤 + +详细API含义可参考:[js-apis-media.md](../reference/apis/js-apis-media.md) + +### 全流程场景 + +包含流程:创建视频解码实例、设置监听事件、配置解码视频的媒体信息、设置surfaceID、准备视频解码、开始视频解码、获取视频媒体信息、清空缓存、停止解码、重置视频解码、销毁视频解码器资源 + +```js +/* 用于打印视频媒体信息 */ +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoDecoder key is ' + item); + console.info('videoDecoder value is ' + property); + } +} + +/* 设置订阅事件回调函数 */ +function SetCallback() { + videoDecoder.on('inputAvailable', (inBuffer) => { // 订阅视频解码的输入视频帧内存事件 + console.info('videoDecoder inputAvailable success'); + /* 将要解码的视频帧数据写入inBuffer后,再将其推入队列中 */ + videoDecoder.queueInput(inBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder queueInput success'); + } else { + console.info(`videoDecoder queueInput fail, errMessage:${error.message}`); + } + }); + }); + videoDecoder.on('outputAvailable', (outBuffer) => { // 订阅视频解码的输出解码后内存事件 + console.info('videoDecoder outputAvailable success'); + /* 获取outBuffer中的时间戳和index信息后,将其从队列中释放 */ + videoDecoder.releaseOutput(outBuffer, true, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder releaseOutput success'); + } else { + console.info(`videoDecoder releaseOutput fail, errMessage:${error.message}`); + } + }); + }); + videoDecoder.on('error', (error) => { // 订阅视频解码错误事件,若出现报错,则需销毁资源,重新开始 + 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}`);// 打印错误类型详细描述 + }); + videoDecoder.on('outputFormatChanged', (format) => { // 订阅视频解码媒体信息变化事件 + if (typeof(format) != 'undefined') { + printfDescription(format); + } + }); +} + +/* 函数调用发生错误时用于上报错误信息 */ +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} + +/* 函数调用发生异常时用于上报错误信息 */ +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +let videoDecoder = undefined; +let surfaceID = undefined; +let mediaDescription = { + "width" : 1920, + "height" : 1080, + "pixel_format" : media.VideoPixelformat.NV12, + "frame_rate" : 60.00, +} + +/* 1.创建视频解码实例 */ +await media.createVideoDecoderByName('avdec_h264').then((decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByName success'); + } else { + console.info('videoDecoder createVideoDecoderByName fail'); + } +}, failureCallback).catch(catchCallback); + +/* 2.设置监听事件 */ +SetCallback(); + +/* 3.配置解码视频的媒体信息 */ +await videoDecoder.configure(mediaDescription).then(() => { + console.log('videoDecoder configure success'); +}, failureCallback).catch(catchCallback); + +/* 调用Xcomponent的接口用于获取surfaceID,将其保存在surfaceID中 */ +/* 4.设置surfaceID */ +await videoDecoder.setOutputSurface(surfaceID, true).then(() => { + console.log('videoDecoder setOutputSurface success'); +}, failureCallback).catch(catchCallback); + +/* 5.准备视频解码 */ +await videoDecoder.prepare().then(() => { + console.log('videoDecoder prepare success'); +}, failureCallback).catch(catchCallback); + +/* 6.开始视频解码 */ +await videoDecoder.start().then(() => { + console.log('videoDecoder start success'); +}, failureCallback).catch(catchCallback); + +/* 触发'inputAvailable'和'outputAvailable'订阅事件 */ + +/* 7.获取视频媒体信息 */ +await videoDecoder.getOutputMediaDescription().then((mediaDescription) => { + console.log('videoDecoder getOutputMediaDescription success'); + printfDescription(mediaDescription); +}, failureCallback).catch(catchCallback); + +/* 8.获取视频解码能力 */ +await videoDecoder.getVideoDecoderCaps().then((videoCaps) => { + console.log('videoDecoder getVideoDecoderCaps success'); +}, failureCallback).catch(catchCallback); + +/* 9.清空缓存 */ +await videoDecoder.flush().then(() => { + console.log('videoDecoder flush success'); +}, failureCallback).catch(catchCallback); + +/* 10.停止解码 */ +await videoDecoder.stop().then(() => { + console.log('videoDecoder stop success'); +}, failureCallback).catch(catchCallback); + +/* 11.重置视频解码 */ +await videoDecoder.reset().then(() => { + console.log('videoDecoder reset success'); +}, failureCallback).catch(catchCallback); + +/* 12.销毁视频解码器资源 */ +await videoDecoder.release().then(() => { + console.log('videoDecoder release success'); +}, failureCallback).catch(catchCallback); +videoDecoder = undefined; // 将视频解码器置空 +``` + +### 正常解码场景 + +```js +/* 设置订阅事件回调函数 */ +function SetCallback() { + videoDecoder.on('inputAvailable', (inBuffer) => { // 订阅视频解码的输入视频帧内存事件 + console.info('videoDecoder inputAvailable success'); + /* 将要解码的视频帧数据写入inBuffer后,再将其推入队列中 */ + videoDecoder.queueInput(inBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder queueInput success'); + } else { + console.info(`videoDecoder queueInput fail, errMessage:${error.message}`); + } + }); + }); + videoDecoder.on('outputAvailable', (outBuffer) => { // 订阅视频解码的输出解码后内存事件 + console.info('videoDecoder outputAvailable success'); + if (outBuffer.flags == media.FrameFlags.EOS_FRAME) { // 读到EOS帧 + await videoDecoder.release().then(() => { // 销毁视频解码器资源 + console.log('videoDecoder release success'); + }, failureCallback).catch(catchCallback); + videoDecoder = undefined; // 将视频解码器置空 + return; + } + /* 获取outBuffer中的时间戳和index信息后,将其从队列中释放 */ + videoDecoder.releaseOutput(outBuffer, true, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder releaseOutput success'); + } else { + console.info(`videoDecoder releaseOutput fail, errMessage:${error.message}`); + } + }); + }); + videoDecoder.on('error', (error) => { // 订阅视频解码错误事件,若出现报错,则需销毁资源,重新开始 + 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}`);// 打印错误类型详细描述 + }); +} + +let videoDecoder = undefined; +let surfaceID = undefined; +let mediaDescription = { + "width" : 1920, + "height" : 1080, + "pixel_format" : media.VideoPixelformat.NV12, + "frame_rate" : 60.00, +} + +/* 1.创建视频解码实例 */ +await media.createVideoDecoderByName('avdec_h264').then((decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByName success'); + } else { + console.info('videoDecoder createVideoDecoderByName fail'); + } +}, failureCallback).catch(catchCallback); + +/* 2.设置监听事件 */ +SetCallback(); + +/* 3.配置解码视频的媒体信息 */ +await videoDecoder.configure(mediaDescription).then(() => { + console.log('videoDecoder configure success'); +}, failureCallback).catch(catchCallback); + +/* 调用Xcomponent的接口用于获取surfaceID,将其保存在surfaceID中 */ +/* 4.设置surfaceID */ +await videoDecoder.setOutputSurface(surfaceID, true).then(() => { + console.log('videoDecoder setOutputSurface success'); +}, failureCallback).catch(catchCallback); + +/* 5.准备视频解码 */ +await videoDecoder.prepare().then(() => { + console.log('videoDecoder prepare success'); +}, failureCallback).catch(catchCallback); + +/* 6.开始视频解码 */ +await videoDecoder.start().then(() => { + console.log('videoDecoder start success'); +}, failureCallback).catch(catchCallback); + +/* + * 触发'inputAvailable'和'outputAvailable'订阅事件 + * 应用将需要解码的视频帧传入'inputAvailable'事件 + * 再将'outputAvailable'事件解码后的视频帧数据送显 + */ +``` + 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 718a612763e60244faa01bf695e5f70e832f87b4..2bbacc43a3b4e6cc85088acbbd40f0fd758326c8 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)) +- 视频解码([VideoDecodeProcessor](#videodecodeprocessor8)) 后续将提供以下功能:视频播放、视频录制、DataSource音视频播放、音视频编解码、容器封装解封装、媒体能力查询等功能。 @@ -90,6 +91,134 @@ await media.createAudioPlayerAsync.then((audio) => { }, failureCallback).catch(catchCallback); ``` +## media.createVideoDecoderByName8+ + +createVideoDecoderByName(name: string, callback: AsyncCallback<[VideoDecodeProcessor](#videodecodeprocessor8)>): void + +通过解码器名称异步方式创建视频解码实例。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------------------ | ---- | ------------------------------ | +| name | string | 是 | 指定解码器名称。 | +| callback | AsyncCallback<[VideoDecodeProcessor](#videodecodeprocessor8)> | 是 | 异步创建视频解码实例回调方法。 | + +**示例:** + +```js +media.createVideoDecoderByName('avdec_h264', (error, decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByName success'); + } else { + console.info(`videoDecoder createVideoDecoderByName fail, error:${error.message}`); + } +}); +``` + +## media.createVideoDecoderByName8+ + +createVideoDecoderByName(name: string): Promise<[VideoDecodeProcessor](#videodecodeprocessor8)> + +通过解码器名称异步方式创建视频解码实例。通过Promise获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------- | +| name | string | 是 | 指定解码器名称。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------------- | ----------------------------------- | +| Promise<[VideoDecodeProcessor](#videodecodeprocessor8)> | 异步创建视频解码实例Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await media.createVideoDecoderByName('avdec_h264').then((decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByName success'); + } else { + console.info('videoDecoder createVideoDecoderByName fail'); + } +}, failureCallback).catch(catchCallback); +``` + +## media.createVideoDecoderByMime8+ + +createVideoDecoderByMime(codecMime: string, callback: AsyncCallback<[VideoDecodeProcessor](#videodecodeprocessor8)>): void + +通过[CodecMimeType](#codecmimetype8)类型异步方式创建视频解码实例。通过注册回调函数获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------------------------------------------------------------ | ---- | ----------------------------------------------------------- | +| codecMime | string | 是 | codecMime类型,具体可参考[CodecMimeType](#codecmimetype8)。 | +| callback | AsyncCallback<[VideoDecodeProcessor](#videodecodeprocessor8)> | 是 | 异步创建视频解码实例回调方法。 | + +**示例:** + +```js +media.createVideoDecoderByMime('video/avc', (error, decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByMime success'); + } else { + console.info(`videoDecoder createVideoDecoderByMime fail, error:${error.message}`); + } +}); +``` + +## media.createVideoDecoderByMime8+ + +createVideoDecoderByMime(name: string): Promise<[VideoDecodeProcessor](#videodecodeprocessor8)> + +通过[CodecMimeType](#codecmimetype8)类型异步方式创建视频解码实例。通过Promise获取返回值。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------- | +| name | string | 是 | 指定解码器名称。 | + +**返回值:** + +| 类型 | 说明 | +| ------------------------------------------------------- | ----------------------------------- | +| Promise<[VideoDecodeProcessor](#videodecodeprocessor8)> | 异步创建视频解码实例Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await media.createVideoDecoderByMime('video/avc').then((decoder) => { + if (typeof(decoder) != 'undefined') { + videoDecoder = decoder; + console.info('videoDecoder createVideoDecoderByMime success'); + } else { + console.info('videoDecoder createVideoDecoderByMime fail'); + } +}, failureCallback).catch(catchCallback); +``` + ## media.createAudioRecorder createAudioRecorder(): AudioRecorder @@ -136,7 +265,7 @@ var audiorecorder = media.createAudioRecorder(); ## CodecMimeType8+ -Codec MIME类型枚举 +codec_mime类型枚举 | 名称 | 值 | 说明 | | ------------ | ----------------- | ------------------------ | @@ -144,23 +273,40 @@ Codec MIME类型枚举 | AUDIO_AAC | "audio/mp4a-latm" | 表示音频/mp4a-latm类型。 | | AUDIO_VORBIS | "audio/vorbis" | 表示音频/vorbis类型。 | | AUDIO_FLAC | "audio/flac" | 表示音频/flac类型。 | +| VIDEO_H263 | "video/h263" | 表示视频/h263类型。 | +| VIDEO_AVC | "video/avc" | 表示视频/avc类型。 | +| VIDEO_MPEG2 | "video/mpeg2" | 表示视频/mpeg2类型。 | +| VIDEO_MPEG4 | "video/mp4v-es" | 表示视频/mp4v-es类型。 | + +## VideoPixelformat8+ + +视频像素格式类型枚举 + +| 名称 | 值 | 说明 | +| ------- | ---- | ----------------- | +| YUVI420 | 1 | 表示YUVI420格式。 | +| NV12 | 2 | 表示NV12格式。 | +| NV21 | 3 | 表示NV21格式。 | ## MediaDescriptionKey8+ 媒体信息描述枚举 -| 名称 | 值 | 说明 | -| ------------------------ | --------------- | ------------------------------------------------------------ | -| MD_KEY_TRACK_INDEX | "track_index" | 表示轨道序号,其对应键值类型为number。 | -| MD_KEY_TRACK_TYPE | "track_type" | 表示轨道类型,其对应键值类型为number,参考[MediaType](#mediatype8)。 | -| MD_KEY_CODEC_MIME | "codec_mime" | 表示codec_mime类型,其对应键值类型为string。 | -| MD_KEY_DURATION | "duration" | 表示媒体时长,其对应键值类型为number,单位为ms。 | -| MD_KEY_BITRATE | "bitrate" | 表示比特率,其对应键值类型为number,单位为bps。 | -| MD_KEY_WIDTH | "width" | 表示视频宽度,其对应键值类型为number,单位为像素。 | -| MD_KEY_HEIGHT | "height" | 表示视频高度,其对应键值类型为number,单位为像素。 | -| MD_KEY_FRAME_RATE | "frame_rate" | 表示视频帧率,其对应键值类型为number,单位为100fps。 | -| MD_KEY_AUD_CHANNEL_COUNT | "channel_count" | 表示声道数,其对应键值类型为number。 | -| MD_KEY_AUD_SAMPLE_RATE | "sample_rate" | 表示采样率,其对应键值类型为number,单位为HZ。 | +| 名称 | 值 | 说明 | +| ------------------------ | ---------------- | ------------------------------------------------------------ | +| MD_KEY_TRACK_INDEX | "track_index" | 表示轨道序号,其对应键值类型为number。 | +| MD_KEY_TRACK_TYPE | "track_type" | 表示轨道类型,其对应键值类型为number,参考[MediaType](#mediatype8)。 | +| MD_KEY_CODEC_MIME | "codec_mime" | 表示codec_mime类型,其对应键值类型为string,参考[CodecMimeType](codecmimetype8)。 | +| MD_KEY_DURATION | "duration" | 表示媒体时长,其对应键值类型为number,单位为ms。 | +| MD_KEY_BITRATE | "bitrate" | 表示比特率,其对应键值类型为number,单位为bps。 | +| MD_KEY_MAX_INPUT_SIZE | "max_input_size“ | 表示输入帧最大内存大小,其对应键值类型为number,单位为Byte。 | +| MD_KEY_WIDTH | "width" | 表示视频宽度,其对应键值类型为number,单位为像素。 | +| MD_KEY_HEIGHT | "height" | 表示视频高度,其对应键值类型为number,单位为像素。 | +| MD_KEY_PIXEL_FORMAT | "pixel_format" | 表示像素格式,其对应键值类型为number,参考[VideoPixelformat](#VideoPixelformat8)。 | +| MD_KEY_FRAME_RATE | "frame_rate" | 表示视频帧率,其对应键值类型为number,单位为fps。 | +| MD_KEY_PROFILE | "codec_profile" | 表示编解码器profile,其对应键值类型为number,参考[AVCProfile](#avcprofile8)、[MPEG2Profile](#mpeg2profile8)、[MPEG4Profile](#mpeg4profile8)、[H263Profile](#h263profile8)。 | +| MD_KEY_AUD_CHANNEL_COUNT | "channel_count" | 表示声道数,其对应键值类型为number。 | +| MD_KEY_AUD_SAMPLE_RATE | "sample_rate" | 表示采样率,其对应键值类型为number,单位为HZ。 | ## BufferingInfoType8+ @@ -173,6 +319,106 @@ Codec MIME类型枚举 | BUFFERING_PERCENT | 3 | 表示缓存百分比。 | | CACHED_DURATION | 4 | 表示缓存时长,单位为毫秒。 | +## FrameFlags8+ + +帧类型枚举 + +| 名称 | 值 | 说明 | +| ------------- | ------ | -------------------- | +| EOS_FRAME | 1 << 0 | 表示码流结束标志。 | +| SYNC_FRAME | 1 << 1 | 表示编解码关键帧。 | +| PARTIAL_FRAME | 1 << 2 | 表示该帧数据不完整。 | +| CODEC_DATA | 1 << 3 | 表示编解码数据帧。 | + +## VideoEncodeBitrateMode8+ + +比特率模式枚举 + +| 名称 | 值 | 说明 | +| ---- | ---- | -------------------- | +| CBR | 0 | 表示常数比特率模式。 | +| VBR | 1 | 表示动态比特率模式。 | +| CQ | 2 | 表示固定画质模式。 | + +## AVCodecType8+ + +编解码器类型枚举 + +| 名称 | 值 | 说明 | +| -------------------------- | ---- | ---------------- | +| AVCODEC_TYPE_VIDEO_ENCODER | 0 | 表示视频编码器。 | +| AVCODEC_TYPE_VIDEO_DECODER | 1 | 表示视频解码器。 | +| AVCODEC_TYPE_AUDIO_ENCODER | 2 | 表示音频编码器。 | +| AVCODEC_TYPE_AUDIO_DECODER | 3 | 表示音频解码器。 | + +## ACVProfile8+ + +H.264 profile类型枚举 + +| 名称 | 值 | +| -------------------------------- | ---- | +| AVC_PROFILE_BASELINE | 0 | +| AVC_PROFILE_CONSTRAINED_BASELINE | 1 | +| AVC_PROFILE_CONSTRAINED_HIGH | 2 | +| AVC_PROFILE_EXTENDED | 3 | +| AVC_PROFILE_HIGH | 4 | +| AVC_PROFILE_HIGH_10 | 5 | +| AVC_PROFILE_HIGH_422 | 6 | +| AVC_PROFILE_HIGH_444 | 7 | +| AVC_PROFILE_MAIN | 8 | + +## MPEG2Profile8+ + +MPEG2 profile类型枚举 + +| 名称 | 值 | +| --------------------- | ---- | +| MPEG2_PROFILE_422 | 0 | +| MPEG2_PROFILE_HIGH | 1 | +| MPEG2_PROFILE_MAIN | 2 | +| MPEG2_PROFILE_SNR | 3 | +| MPEG2_PROFILE_SIMPLE | 4 | +| MPEG2_PROFILE_SPATIAL | 5 | + +## MPEG4Profile8+ + +MPEG4 profile类型枚举 + +| 名称 | 值 | +| -------------------------------- | ---- | +| MPEG4_PROFILE_ADVANCED_CODING | 0 | +| MPEG4_PROFILE_ADVANCED_CORE | 1 | +| MPEG4_PROFILE_ADVANCED_REAL_TIME | 2 | +| MPEG4_PROFILE_ADVANCED_SCALABLE | 3 | +| MPEG4_PROFILE_ADVANCED_SIMPLE | 4 | +| MPEG4_PROFILE_BASIC_ANIMATED | 5 | +| MPEG4_PROFILE_CORE | 6 | +| MPEG4_PROFILE_CORE_SCALABLE | 7 | +| MPEG4_PROFILE_HYBRID | 8 | +| MPEG4_PROFILE_MAIN | 9 | +| MPEG4_PROFILE_NBIT | 10 | +| MPEG4_PROFILE_SCALABLE_TEXXTURE | 11 | +| MPEG4_PROFILE_SIMPLE | 12 | +| MPEG4_PROFILE_SIMPLE_FBA | 13 | +| MPEG4_PROFILE_SIMPLE_FACE | 14 | +| MPEG4_PROFILE_SIMPLE_SCALABLE | 15 | + +## H263Profile8+ + +H263 profile类型枚举 + +| 名称 | 值 | +| -------------------------------- | ---- | +| H263_PROFILE_BACKWARD_COMPATIBLE | 0 | +| H263_PROFILE_BASELINE | 1 | +| H263_PROFILE_H320_CODING | 2 | +| H263_PROFILE_HIGH_COMPRESSION | 3 | +| H263_PROFILE_HIGH_LATENCY | 4 | +| H263_PROFILE_ISW_V2 | 5 | +| H263_PROFILE_ISW_V3 | 6 | +| H263_PROFILE_INTERLACE | 7 | +| H263_PROFILE_INTERNET | 8 | + ## AudioPlayer 音频播放管理类,用于管理和播放音频媒体。在调用AudioPlayer的方法前,需要先通过[createAudioPlayer()](#media.createaudioplayer)或[createAudioPlayerAsync()](#media.createaudioplayerasync8)构建一个[AudioPlayer](#audioplayer)实例。 @@ -198,7 +444,7 @@ play(): void **示例:** ```js -audioPlayer.on('play', () => { //设置'play'事件回调 +audioPlayer.on('play', () => { // 设置'play'事件回调 console.log('audio play success'); }); audioPlayer.play(); @@ -213,7 +459,7 @@ pause(): void **示例:** ```js -audioPlayer.on('pause', () => { //设置'pause'事件回调 +audioPlayer.on('pause', () => { // 设置'pause'事件回调 console.log('audio pause success'); }); audioPlayer.pause(); @@ -228,7 +474,7 @@ stop(): void **示例:** ```js -audioPlayer.on('stop', () => { //设置'stop'事件回调 +audioPlayer.on('stop', () => { // 设置'stop'事件回调 console.log('audio stop success'); }); audioPlayer.stop(); @@ -243,7 +489,7 @@ reset(): void **示例:** ```js -audioPlayer.on('reset', () => { //设置'reset'事件回调 +audioPlayer.on('reset', () => { // 设置'reset'事件回调 console.log('audio reset success'); }); audioPlayer.reset(); @@ -264,14 +510,14 @@ seek(timeMs: number): void **示例:** ```js -audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 +audioPlayer.on('timeUpdate', (seekDoneTime) => { // 设置'timeUpdate'事件回调 if (typeof (seekDoneTime) == 'undefined') { console.info('audio seek fail'); return; } console.log('audio seek success. seekDoneTime: ' + seekDoneTime); }); -audioPlayer.seek(30000); //seek到30000ms的位置 +audioPlayer.seek(30000); // seek到30000ms的位置 ``` ### setVolume @@ -289,10 +535,10 @@ setVolume(vol: number): void **示例:** ```js -audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 +audioPlayer.on('volumeChange', () => { // 设置'volumeChange'事件回调 console.log('audio volumeChange success'); }); -audioPlayer.setVolume(1); //设置音量到100% +audioPlayer.setVolume(1); // 设置音量到100% ``` ### release @@ -421,46 +667,46 @@ on(type: 'play' | 'pause' | 'stop' | 'reset' | 'dataLoad' | 'finish' | 'volumeCh **示例:** ```js -let audioPlayer = media.createAudioPlayer(); //创建一个音频播放实例 -audioPlayer.on('dataLoad', () => { //设置'dataLoad'事件回调,src属性设置成功后,触发此回调 +let audioPlayer = media.createAudioPlayer(); // 创建一个音频播放实例 +audioPlayer.on('dataLoad', () => { // 设置'dataLoad'事件回调,src属性设置成功后,触发此回调 console.info('audio set source success'); - audioPlayer.play(); //开始播放,并触发'play'事件回调 + audioPlayer.play(); // 开始播放,并触发'play'事件回调 }); -audioPlayer.on('play', () => { //设置'play'事件回调 +audioPlayer.on('play', () => { // 设置'play'事件回调 console.info('audio play success'); - audioPlayer.seek(30000); //调用seek方法,并触发'timeUpdate'事件回调 + audioPlayer.seek(30000); // 调用seek方法,并触发'timeUpdate'事件回调 }); -audioPlayer.on('pause', () => { //设置'pause'事件回调 +audioPlayer.on('pause', () => { // 设置'pause'事件回调 console.info('audio pause success'); - audioPlayer.stop(); //停止播放,并触发'stop'事件回调 + audioPlayer.stop(); // 停止播放,并触发'stop'事件回调 }); -audioPlayer.on('reset', () => { //设置'reset'事件回调 +audioPlayer.on('reset', () => { // 设置'reset'事件回调 console.info('audio reset success'); - audioPlayer.release(); //释放播放实例资源 + audioPlayer.release(); // 释放播放实例资源 audioPlayer = undefined; }); -audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 +audioPlayer.on('timeUpdate', (seekDoneTime) => { // 设置'timeUpdate'事件回调 if (typeof(seekDoneTime) == "undefined") { console.info('audio seek fail'); return; } console.info('audio seek success, and seek time is ' + seekDoneTime); - audioPlayer.setVolume(0.5); //设置音量为50%,并触发'volumeChange'事件回调 + audioPlayer.setVolume(0.5); // 设置音量为50%,并触发'volumeChange'事件回调 }); -audioPlayer.on('volumeChange', () => { //设置'volumeChange'事件回调 +audioPlayer.on('volumeChange', () => { // 设置'volumeChange'事件回调 console.info('audio volumeChange success'); - audioPlayer.pause(); //暂停播放,并触发'pause'事件回调 + audioPlayer.pause(); // 暂停播放,并触发'pause'事件回调 }); -audioPlayer.on('finish', () => { //设置'finish'事件回调 +audioPlayer.on('finish', () => { // 设置'finish'事件回调 console.info('audio play finish'); - audioPlayer.stop(); //停止播放,并触发'stop'事件回调 + audioPlayer.stop(); // 停止播放,并触发'stop'事件回调 }); -audioPlayer.on('error', (error) => { //设置'error'事件回调 +audioPlayer.on('error', (error) => { // 设置'error'事件回调 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}`); }); -audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp4'; //设置src属性,并触发'dataLoad'事件回调 +audioPlayer.src = 'file:///data/data/ohos.xxx.xxx/files/test.mp4'; // 设置src属性,并触发'dataLoad'事件回调 ``` ### on('timeUpdate') @@ -479,14 +725,14 @@ on(type: 'timeUpdate', callback: Callback\): void **示例:** ```js -audioPlayer.on('timeUpdate', (seekDoneTime) => { //设置'timeUpdate'事件回调 +audioPlayer.on('timeUpdate', (seekDoneTime) => { // 设置'timeUpdate'事件回调 if (typeof (seekDoneTime) == 'undefined') { console.info('audio seek fail'); return; } console.log('audio seek success. seekDoneTime: ' + seekDoneTime); }); -audioPlayer.seek(30000); //seek到30000ms的位置 +audioPlayer.seek(30000); // seek到30000ms的位置 ``` ### on('error') @@ -505,12 +751,12 @@ 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, errCode is ${error.code}`); //打印错误码 - console.info(`audio error called, errMessage is ${error.message}`);//打印错误类型详细描述 +audioPlayer.on('error', (error) => { // 设置'error'事件回调 + 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}`);// 打印错误类型详细描述 }); -audioPlayer.setVolume(3); //设置volume为无效值,触发'error'事件 +audioPlayer.setVolume(3); // 设置volume为无效值,触发'error'事件 ``` ## AudioState @@ -533,7 +779,7 @@ audioPlayer.setVolume(3); //设置volume为无效值,触发'error'事件 | 名称 | 类型 | 说明 | | ----- | ------ | ------------------------------------------------------------ | -| key | string | 通过key值获取对应的value。key值具体可见[MediaDescriptionKey](#mediadescriptionkey8)。 | +| key | string | 通过key值获取对应的value。key值具体可参考[MediaDescriptionKey](#mediadescriptionkey8)。 | | value | any | 对应key值得value。其类型可为任意类型,具体key对应value的类型可参考[MediaDescriptionKey](#mediadescriptionkey8)的描述信息。 | **示例:** @@ -548,7 +794,7 @@ function printfItemDescription(obj, key) { audioPlayer.getTrackDescription((error, arrlist) => { if (typeof (arrlist) != 'undefined') { for (let i = 0; i < arrlist.length; i++) { - printfItemDescription(arrlist[i], MD_KEY_TRACK_TYPE); //打印出每条轨道MD_KEY_TRACK_TYPE的值 + printfItemDescription(arrlist[i], MD_KEY_TRACK_TYPE); // 打印出每条轨道MD_KEY_TRACK_TYPE的值 } } else { console.log(`audio getTrackDescription fail, error:${error.message}`); @@ -703,4 +949,1158 @@ 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音频的传输流格式。 | + +## VideoDecodeProcessor8+ + +视频解码管理类。用于解码视频媒体,在调用VideoDecodeProcessor的方法前,需要先通过[createVideoDecoderByName()](#media.createvideodecoderbyname8)或[createVideoDecoderByMime()](#media.createvideodecoderbymime8)构建一个[VideoDecodeProcessor](#videodecodeprocessor8)实例。 + +视频解码demo可参考:[视频解码开发指导](../../media/video-decoder.md) + +### configure + +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" : 320, + "height" : 240, + "frame_rate" : 60.00, + "pixel_format" : media.VideoPixelformat.NV12, +} +videoDecoder.configure(mediaDescription, (error) => { // 配置媒体信息 + if (typeof(error) != 'undefined') { + console.log('videoDecoder configure success'); + } else { + console.info(`videoDecoder configure fail, errMessage:${error.message}`); + } +}); +``` + +### configure + +configure(desc: [MediaDescription](#mediadescription8)): Promise\ + +配置解码视频的媒体信息。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。
必须设置的视频解码媒体信息:MD_KEY_WIDTH、MD_KEY_HEIGHT、MD_KEY_FRAME_RATE、MD_KEY_PIXEL_FORMAT。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 配置媒体信息Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +let mediaDescription = { + "width" : 320, + "height" : 240, + "frame_rate" : 60.00, + "pixel_format" : media.VideoPixelformat.NV12, +} +await videoDecoder.configure(mediaDescription).then(() => { // 配置媒体信息 + console.log('videoDecoder configure success'); +}, failureCallback).catch(catchCallback); +``` + +### prepare + +prepare(callback: AsyncCallback\): void + +准备视频解码。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 准备视频解码事件回调函数。 | + +**示例:** + +```js +videoDecoder.prepare((error) => { // 准备视频解码 + if (typeof(error) != 'undefined') { + console.log('videoDecoder prepare success'); + } else { + console.info(`videoDecoder prepare fail, errMessage:${error.message}`); + } +}); +``` + +### prepare + +prepare(): Promise\ + +准备视频解码。通过Promise获取执行结果。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 准备视频解码Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.prepare().then(() => { // 准备视频解码 + console.log('videoDecoder prepare success'); +}, failureCallback).catch(catchCallback); +``` + +### start + +start(callback: AsyncCallback\): void + +开始视频解码。通过注册回调函数获取执行结果。在start()方法调用前需完成[inputAvailable](#on('inputavailable'))和[outputAvailable](#on('outputavailable'))两个事件注册。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 开始视频解码事件回调函数。 | + +**示例:** + +```js +videoDecoder.start((error) => { // 开始视频解码 + if (typeof(error) != 'undefined') { + console.log('videoDecoder start success'); + } else { + console.info(`videoDecoder start fail, errMessage:${error.message}`); + } +}); +``` + +### start + +start(): Promise\ + +开始视频解码。通过Promise获取执行结果。在start()方法调用前需完成[inputAvailable](#on('inputavailable'))和[outputAvailable](#on('outputavailable'))两个事件注册。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 开始视频解码Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.start().then(() => { // 开始视频解码 + console.log('videoDecoder start success'); +}, failureCallback).catch(catchCallback); +``` + +### stop + +stop(callback: AsyncCallback\): void + +停止视频解码。通过注册回调函数获取执行结果。stop()后可直接调用[start()](#videodecodeprocessor_start1)继续进行解码。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 停止视频解码事件回调函数。 | + +**示例:** + +```js +videoDecoder.stop((error) => { // 停止视频解码 + if (typeof(error) != 'undefined') { + console.log('videoDecoder stop success'); + } else { + console.info(`videoDecoder stop fail, errMessage:${error.message}`); + } +}); +``` + +### stop + +stop: Promise\ + +停止视频解码。通过Promise获取执行结果。stop()后可直接调用[start()](#videodecodeprocessor_start2)继续进行解码。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 停止视频解码Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.stop().then(() => { // 停止视频解码 + console.log('videoDecoder stop success'); +}, failureCallback).catch(catchCallback); +``` + +### flush + +flush(callback: AsyncCallback\): void + +清空缓存中未完成解码的内存。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | ---------------------- | +| callback | AsyncCallback\ | 是 | 清空缓存事件回调函数。 | + +**示例:** + +```js +videoDecoder.flush((error) => { // 刷新缓存 + if (typeof(error) != 'undefined') { + console.log('videoDecoder flush success'); + } else { + console.info(`videoDecoder flush fail, errMessage:${error.message}`); + } +}); +``` + +### flush + +flush(): Promise\ + +清空缓存中未完成解码的内存。通过Promise获取执行结果。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | ----------------------- | +| Promise\ | 清空缓存Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.flush().then(() => { // 清空缓存 + console.log('videoDecoder flush success'); +}, failureCallback).catch(catchCallback); +``` + +### reset + +reset(callback: AsyncCallback\): void + +重置视频解码。通过注册回调函数获取执行结果。重置后需要重新[configure()](#videodecodeprocessor_configure1)和[prepare()](#videodecodeprocessor_prepare1)才可进行视频解码。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------- | +| callback | AsyncCallback\ | 是 | 重置视频解码事件回调函数。 | + +**示例:** + +```js +videoDecoder.reset((error) => { // 重置视频解码 + if (typeof(error) != 'undefined') { + console.log('videoDecoder reset success'); + } else { + console.info(`videoDecoder reset fail, errMessage:${error.message}`); + } +}); +``` + +### reset + +reset(): Promise\ + +重置视频解码。通过Promise获取执行结果。重置后需要重新[configure()](#videodecodeprocessor_configure2)和[prepare()](#videodecodeprocessor_prepare2)才可进行视频解码。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------- | +| Promise\ | 重置视频解码Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.reset().then(() => { // 重置视频解码 + console.log('videoDecoder reset success'); +}, failureCallback).catch(catchCallback); +``` + +### release + +release(callback: AsyncCallback\): void + +销毁视频解码器资源。通过注册回调函数获取执行结果。应用需手动release,不能依赖内存回收机制。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------- | ---- | -------------------------------- | +| callback | AsyncCallback\ | 是 | 销毁视频解码器资源事件回调函数。 | + +**示例:** + +```js +videoDecoder.release((error) => { // 销毁视频解码器资源 + if (typeof(error) != 'undefined') { + console.log('videoDecoder release success'); + videoDecoder = undefined; // 将视频解码器置空 + } else { + console.info(`videoDecoder release fail, errMessage:${error.message}`); + } +}); +``` + +### release + +release(): Promise\ + +销毁视频解码器资源。通过Promise获取执行结果。应用需手动release,不能依赖内存回收机制。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------- | +| Promise\ | 销毁视频解码器资源Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.release().then(() => { // 销毁视频解码器资源 + console.log('videoDecoder release success'); +}, failureCallback).catch(catchCallback); +videoDecoder = undefined; // 将视频解码器置空 +``` + +### queueInput + +queueInput(buffer: [CodecBuffer](#codecbuffer8), callback: AsyncCallback\): void + +将解码视频帧内存数据输入队列。通过注册回调函数获取执行结果。需在[start()](#videodecodeprocessor_start1)之后才可调用此接口。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | -------------------------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 视频解码原始帧数据。 | +| callback | AsyncCallback\ | 是 | 输入解码视频帧数据进队列事件回调函数。 | + +**示例:** + +```js +videoDecoder.on('inputAvailable', (inputBuffer) => { // 订阅inputAvailable事件 + /* 将需要解码的数据传入inputBuffer中,此处需仅做示例,解码时,需按实际情况将每帧的数据进行赋值 */ + inputBuffer.index = 0; + inputBuffer.timeMs = 0; + inputBuffer.offset = 0; + inputBuffer.length = 100; + inputBuffer.flags = media.FrameFlags.CODEC_DATA; + inputBuffer.data; // 使用零拷贝策略,将数据直接写入data中 + /* 将需要解码的数据推入队列中 */ + videoDecoder.queueInput(inputBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder queueInput success'); + } else { + console.info(`videoDecoder queueInput fail, errMessage:${error.message}`); + } + }); +}); +``` + +### queueInput + +queueInput(buffer: [CodecBuffer](#codecbuffer8)): Promise\ + +将解码视频帧内存数据输入队列。通过Promise获取执行结果。需在[start()](#videodecodeprocessor_start2)之后才可调用此接口。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ---------------------------- | ---- | -------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 视频解码原始帧数据。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------------- | +| Promise\ | 将解码视频帧数据输入队列Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +videoDecoder.on('inputAvailable', (inputBuffer) => { // 订阅inputAvailable事件 + /* 将需要解码的数据传入inputBuffer中,此处仅做示例,解码时,需按实际情况将没帧的数据进行赋值 */ + inputBuffer.index = 0; + inputBuffer.timeMs = 0; + inputBuffer.offset = 0; + inputBuffer.length = 100; + inputBuffer.flags = media.FrameFlags.CODEC_DATA; + inputBuffer.data; // 使用零拷贝策略,将数据直接写入data中 + /* 将需要解码的数据推入队列中 */ + await videoDecoder.queueInput(inputBuffer).then(() => { + console.log('videoDecoder queueInput success'); + }, failureCallback).catch(catchCallback); +}); +``` + +### releaseOutput + +releaseOutput(buffer: [CodecBuffer](#codecbuffer8), isRender: boolean, callback: AsyncCallback\): void + +释放解码输出的视频帧内存。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | -------------------------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 解码完成的视频帧数据。 | +| isRender | boolean | 是 | 是否将解码帧进行渲染送显。 | +| callback | AsyncCallback\ | 是 | 释放解码输出的视频帧内存事件回调函数。 | + +**示例:** + +```js +videoDecoder.on('outputAvailable', (outputBuffer) => { // 订阅outputAvailable事件 + /* 将outputBuffer数据读取后,再将其释放 */ + videoDecoder.releaseOutput(outputBuffer, true, (error) => { // 将解码后的视频帧送显后,释放解码输出的视频帧内存 + if (typeof(error) != 'undefined') { + console.log('videoDecoder releaseOutput success'); + } else { + console.info(`videoDecoder releaseOutput fail, errMessage:${error.message}`); + } + }); +}); +``` + +### releaseOutput + +releaseOutput(buffer: [CodecBuffer](#codecbuffer8), isRender: boolean): Promise\ + +释放解码输出的视频帧内存。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ---------------------------- | ---- | -------------------------- | +| buffer | [CodecBuffer](#codecbuffer8) | 是 | 解码完成的视频帧数据。 | +| isRender | boolean | 是 | 是否将解码帧进行渲染送显。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------------- | +| Promise\ | 释放解码输出的视频帧内存Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +videoDecoder.on('outputAvailable', (outputBuffer) => { // 订阅outputAvailable事件 + /* 将outputBuffer数据读取后,再将其释放 */ + await videoDecoder.releaseOutput(outputBuffer, false).then(() => { // 释放解码输出的视频帧内存 + console.log('videoDecoder releaseOutput success'); + }, failureCallback).catch(catchCallback); +}); +``` + +### setOutputSurface + +setOutputSurface(surfaceId: string, isDisplay: boolean, callback: AsyncCallback\): void + +设置surface id。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------- | -------------------- | ---- | ------------------------------- | +| surfaceId | string | 是 | surface id。 | +| isDisplay | boolean | 是 | 设置的surface是否用于渲染送显。 | +| callback | AsyncCallback\ | 是 | 设置surface id事件回调函数。 | + +**示例:** + +```js +surfaceId = 'Xcomponent'; // 此处surface id仅做为示例 +videoDecoder.setOutputSurface(surfaceId, true, (error) => { // 设置surface id, 此surface用于渲染 + if (typeof(error) != 'undefined') { + console.log('videoDecoder setOutputSurface success'); + } else { + console.info(`videoDecoder setOutputSurface fail, errMessage:${error.message}`); + } +}); +``` + +### setOutputSurface + +setOutputSurface(surfaceId: string, isDisplay: boolean): Promise\ + +设置surface id。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| --------- | ------- | ---- | ------------------------------- | +| surfaceId | string | 是 | surface id。 | +| isDisplay | boolean | 是 | 设置的surface是否用于渲染送显。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------- | +| Promise\ | 设置surface id的Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +surfaceId = 'Xcomponent'; // 此处surface id仅做为示例 +await videoDecoder.setOutputSurface(surfaceId, false).then(() => { // 设置surface id, 此surface不用于渲染 + console.log('videoDecoder setOutputSurface success'); +}, failureCallback).catch(catchCallback); +``` + +### setParameter + +setParameter(desc: [MediaDescription](#mediadescription8), callback: AsyncCallback\): void + +动态设置解码视频的媒体信息。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。 | +| callback | AsyncCallback\ | 是 | 动态设置解码视频的媒体信息事件回调函数。 | + +**示例:** + +```js +let mediaDescription = { // 此处mediaDescription仅做为示例 + "width" : 640, + "height" : 480, +} + +videoDecoder.setParameter(mediaDescription, (error) => { // 动态设置解码视频的媒体信息 + if (typeof(error) != 'undefined') { + console.log('videoDecoder setParameter success'); + } else { + console.info(`videoDecoder setParameter fail, errMessage:${error.message}`); + } +}); +``` + +### setParameter + +setParameter(desc: [MediaDescription](#mediadescription8)): Promise\ + +动态设置解码视频的媒体信息。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | -------------------------------------- | ---- | ------------------------------------------------------------ | +| desc | [MediaDescription](#mediadescription8) | 是 | 媒体信息键值对,key值的范围可参考[MediaDescriptionKey](#mediadescriptionkey8)。 | + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------------------- | +| Promise\ | 动态设置解码视频的媒体信息的Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +let mediaDescription = { // 此处mediaDescription仅做为示例 + "width" : 640, + "height" : 480, +} + +await videoDecoder.setParameter(mediaDescription).then(() => { // 动态设置解码视频的媒体信息 + console.log('videoDecoder setParameter success'); +}, failureCallback).catch(catchCallback); +``` + +### getOutputMediaDescription + +getOutputMediaDescription(callback: AsyncCallback<[MediaDescription](#mediadescription8)>): void + +获取解码视频的当前媒体信息。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------------------- | ---- | ---------------------------------------- | +| callback | AsyncCallback<[MediaDescription](#mediadescription8)> | 是 | 获取解码视频的当前媒体信息事件回调函数。 | + +**示例:** + +```js +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoDecoder key is ' + item); + console.info('videoDecoder value is ' + property); + } +} + +videoDecoder.getOutputMediaDescription((error, mediaDescription) => { + if (typeof(mediaDescription) != 'undefined') { + console.log('videoDecoder getOutputMediaDescription success'); + printfDescription(mediaDescription); + } else { + console.log('videoDecoder getOutputMediaDescription fail'); + } +}); +``` + +### getOutputMediaDescription + +getOutputMediaDescription(): Promise<[MediaDescription](#mediadescription8)> + +获取解码视频的当前媒体信息。通过Promise获取执行结果。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | ------------------------------------------- | +| Promise\ | 获取解码视频的当前媒体信息的Promise返回值。 | + +**示例:** + +```js +/* 将format中的所有内容显示 */ +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoDecoder key is ' + item); + console.info('videoDecoder value is ' + property); + } +} +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.getOutputMediaDescription().then((mediaDescription) => { + console.log('videoDecoder getOutputMediaDescription success'); + printfDescription(mediaDescription); +}, failureCallback).catch(catchCallback); +``` + +### getVideoDecoderCaps + +getVideoDecoderCaps(callback: AsyncCallback<[VideoCaps](#videocaps8)>): void + +获取视频解码能力。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------------------- | ---- | ------------------------------ | +| callback | AsyncCallback<[VideoCaps](#videocaps8)> | 是 | 获取视频解码能力事件回调函数。 | + +**示例:** + +```js +videoDecoder.getVideoDecoderCaps((error, videoCaps) => { + if (typeof(videoCaps) != 'undefined') { + console.log('videoDecoder getVideoDecoderCaps success'); + printfDescription(mediaDescription); + } else { + console.log('videoDecoder getVideoDecoderCaps fail'); + } +}); +``` + +### getVideoDecoderCaps + +getVideoDecoder(): Promise<[VideoCaps](#videocaps8)> + +获取视频解码能力。通过Promise获取执行结果。 + +**返回值:** + +| 类型 | 说明 | +| -------------- | --------------------------------- | +| Promise\ | 获取视频解码能力的Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoDecoder failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoDecoder catchCallback, error:${error.message}`); +} + +await videoDecoder.getVideoDecoderCaps().then((videoCaps) => { + console.log('videoDecoder getVideoDecoderCaps success'); +}, failureCallback).catch(catchCallback); +``` + +### on('error') + +on(type: 'error', callback: ErrorCallback<[CodecError](#codecerror8)>): void + +订阅视频解码错误事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 视频解码错误事件回调类型,支持的事件包括:'error'。
- 'error':视频解码中发生错误,触发该事件。 | +| callback | ErrorCallback<[CodecError](#codecerror8)> | 是 | 视频解码错误事件回调方法。 | + +**示例:** + +```js +videoDecoder.on('error', (error) => { // 设置'error'事件回调 + 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}`);// 打印错误类型详细描述 +}); +/* 系统内存不足或状态切换异常时,触发error事件回调 */ +``` + +### on('outputFormatChanged') + +on(type: 'outputFormatChanged', callback: Callback<[MediaDescription](#mediadescription8)>) + +订阅解码视频第一帧或媒体信息发生变化事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------ | ---- | ------------------------------------------------------------ | +| type | string | 是 | 解码视频第一帧或媒体信息发生变化事件回调类型,支持的事件包括:'outputFormatChanged'。
- 'outputFormatChanged':解码视频第一帧解码完成或媒体信息发生变化时,触发该事件。 | +| callback | Callback<[MediaDescription](#mediadescription8)> | 是 | 解码视频第一帧或媒体信息发生变化事件回调方法。 | + +**示例:** + +```js +/* 将format中的所有内容显示 */ +function printfDescription(obj) { + for (let item in obj) { + let property = obj[item]; + console.info('videoDecoder key is ' + item); + console.info('videoDecoder value is ' + property); + } +} + +videoDecoder.on('outputFormatChanged', (format) => { // 设置解码视频第一帧或媒体信息发生变化事件回调 + if (typeof(format) != 'undefined') { + printfDescription(format); + } +}); +/* 解码视频的媒体信息发生变化时,触发事件 */ +``` + +### on('inputAvailable') + +on(type: 'inputAvailable', callback: Callback<[CodecBuffer](#codecbuffer8)>) + +订阅视频解码输入视频帧内存事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 视频解码输入视频帧内存事件回调类型,支持的事件包括:'inputAvailable'。
- 'inputAvailable':[start()](#videodecodeprocessor_start1)调用之后,触发该事件。 | +| callback | Callback<[CodecBuffer](#codecbuffer8)> | 是 | 视频解码输入视频帧内存事件回调方法。
- 用户需将要解码的视频帧内容填入[CodecBuffer](#codecbuffer8),再调用[queueInput()](#videodecodeprocessor_queueinput1)方法将[CodecBuffer](#codecbuffer8)推入队列中。 | + +**示例:** + +```js +videoDecoder.on('inputAvailable', (inBuffer) => { + console.info('videoDecoder inputAvailable'); + /* 将视频帧内容填入inBuffer后,调用queueInput方法将其推入队列 */ + videoDecoder.queueInput(inBuffer, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder queueInput success'); + } else { + console.info(`videoDecoder queueInput fail, errMessage:${error.message}`); + } + }); +}); +``` + +### on('outputAvailable') + +on(type: 'outputAvailable', callback: Callback<[CodecBuffer](#codecbuffer8)>) + +订阅视频解码输出视频帧解码后内存事件。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------------- | ---- | ------------------------------------------------------------ | +| type | string | 是 | 视频解码输出视频帧解码后内存事件回调类型,支持的事件包括:'outputAvailable'。
- 'outputAvailable':[queueInput()](#videodecodeprocessor_queueinput1)调用之后,触发该事件。 | +| callback | Callback<[CodecBuffer](#codecbuffer8)> | 是 | 视频解码输出视频帧解码后内存事件。
- 媒体服务将视频帧解码后的内容通过[CodecBuffer](#codecbuffer8)返回给用户,用户读取内存后,需调用[releaseOutput()](#videodecodeprocessor_releaseoutput1)方法将该内存从队列中移除。 | + +**示例:** + +```js +videoDecoder.on('outputAvailable', (outBuffer) => { + console.info('videoDecoder outputAvailable'); + /* 获取outBuffer中视频帧解码后的时间戳和index后,调用releaseOutput方法将该帧送显,并将该内存从队列中移除 */ + videoDecoder.releaseOutput(outBuffer, true, (error) => { + if (typeof(error) != 'undefined') { + console.log('videoDecoder releaseOutput success'); + } else { + console.info(`videoDecoder releaseOutput fail, errMessage:${error.message}`); + } + }); +}); +``` + +## CodecBuffer8+ + +音视频编解码数据帧类。用于音视频编解码输入原始数据以及输出编解码后的数据。 + +### 属性 + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------ | -------------------------- | ---- | ---- | -------------------- | +| index | number | 是 | 是 | 帧索引。 | +| data | ArrayBuffer | 是 | 是 | 帧数据内存。 | +| offset | number | 是 | 是 | 帧数据内存的偏移。 | +| length | number | 是 | 是 | 帧数据内存的长度。 | +| flags | [FrameFlags](#frameflags8) | 是 | 是 | 帧标签。 | +| timeMs | number | 是 | 是 | 时间戳。单位:毫秒。 | + +## CodecError8+ + +音视频编解码错误信息类。继承于Error类。 + +### 属性 + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ---- | ---------------------------------- | ---- | ---- | ---------- | +| code | [MediaErrorCode](#mediaerrorcode8) | 是 | 是 | 错误代码。 | + +## VideoCaps8+ + +视频编解码器能力类。用于表示视频编解码器能力范围。 + +### 属性 + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ------------------------ | --------------------------------------------- | ---- | ---- | ------------------------------------------------------------ | +| codecInfo | [AVCodecInfo](#avcodecinfo8) | 是 | 否 | 编解码器描述信息。 | +| supportedBitrate | [Range](#range8) | 是 | 否 | 编解码器支持比特率范围。 | +| supportedFormats | Array<[VideoPixelFormat](#videopixelformat8)> | 是 | 否 | 编解码器支持像素格式数组。 | +| supportedHeightAlignment | number | 是 | 否 | 编解码器支持视频对齐高度。 | +| supportedWidthAlignment | number | 是 | 否 | 编解码器支持视频对齐宽度。 | +| supportedWidth | [Range](#range8) | 是 | 否 | 编解码器支持视频宽度范围。 | +| supportedHeight | [Range](#range8) | 是 | 否 | 编解码器支持视频高度范围。 | +| supportedProfiles | Array\ | 是 | 否 | 编解码器支持profile数组。 | +| supportedLevels | Array\ | 是 | 否 | 编解码器支持level数组。 | +| supportedBitrateMode | Array\ | 是 | 否 | 编码器支持比特率模式数组。可参考[VideoEncodeBitrateMode](#videoencodebitratemode8)。 | +| supportedQuality | [Range](#range8) | 是 | 否 | 编码器支持quality范围。 | +| supportedComplexity | [Range](#range8) | 是 | 否 | 编码器支持complexity范围。 | + +### isSizeSupported + +isSizeSupported(width: number, height: number, callback: AsyncCallback\) + +判断编解码器是否支持给定的视频宽度和高度。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------- | ---- | ------------------------------------------------------------ | +| width | number | 是 | 视频宽度。 | +| height | number | 是 | 视频高度。 | +| callback | AsyncCallback\ | 是 | 判断编解码器是否支持给定的视频宽度和高度事件回调函数。true:支持,false:不支持。 | + +**示例:** + +```js +videoCaps.isSizeSupported(320, 240, (error, result) => { // 判断编解码器是否支持320*240的视频 + if (typeof(result) != 'undefined') { + console.log('videoCaps isSizeSupported success, result: ' + result); + } else { + console.log('videoCaps isSizeSupported fail'); + } +}); +``` + +### isSizeSupported + +isSizeSupported(width: number, height: number): Promise\ + +判断编解码器是否支持给定的视频宽度和高度。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------- | +| width | number | 是 | 视频宽度。 | +| height | number | 是 | 视频高度。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------- | ------------------------------------------------------------ | +| Promise\ | 判断编解码器是否支持给定的视频宽度和高度的Promise返回值。true:支持,false:不支持。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoCaps failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoCaps catchCallback, error:${error.message}`); +} + +await videoCaps.isSizeSupported(320, 240).then((result) => { // 判断编解码器是否支持320*240的视频 + console.log('videoCaps isSizeSupported success, result: ' + result); +}, failureCallback).catch(catchCallback); +``` + +### getSupportedFrameRate + +getSupportedFrameRate(width: number, height: number, callback: AsyncCallback\<[Range](#range8)>) + +获取编解码器对特定视频宽度和高度支持的帧率范围。通过注册回调函数获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | ---- | ------------------------------------------------------------ | +| width | number | 是 | 视频宽度。单位:像素。 | +| height | number | 是 | 视频高度。单位:像素。 | +| callback | AsyncCallback\<[Range](#range8)> | 是 | 获取编解码器对特定视频宽度和高度支持的帧率范围事件回调函数。 | + +**示例:** + +```js +videoCaps.getSupportedFrameRate(320, 240, (frameRate) => { // 获取320*240视频的支持帧率范围 + if (typeof(frameRate) != 'undefined') { + console.log('videoCaps getSupportedFrameRate success'); + console.log('frameRate.min: ' + frameRate.min); + console.log('frameRate.max: ' + frameRate.max); + } else { + console.log('videoCaps getSupportedFrameRate fail'); + } +}); +``` + +### getSupportedFrameRate + +getSupportedFrameRate(width: number, height: number): Promise\<[Range](#range8)> + +获取编解码器对特定视频宽度和高度支持的帧率范围。通过Promise获取执行结果。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------------- | +| width | number | 是 | 视频宽度。单位:像素。 | +| height | number | 是 | 视频高度。单位:像素。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------- | ------------------------------------------------------------ | +| Promise\ | 获取编解码器对特定视频宽度和高度支持的帧率范围的Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoCaps failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoCaps catchCallback, error:${error.message}`); +} + +await videoCaps.getSupportedFrameRate(320, 240).then((frameRate) => { // 获取320*240视频的支持帧率范围 + console.log('videoCaps getSupportedFrameRate success'); + console.log('frameRate.min: ' + frameRate.min); + console.log('frameRate.max: ' + frameRate.max); +}, failureCallback).catch(catchCallback); +``` + +### getPreferredFrameRate + +getPreferredFrameRate(width: number, height: number, callback: AsyncCallback\<[Range](#range8)>) + +获取编解码器对特定视频宽度和高度推荐的帧率范围。通过注册回调函数获取执行结果。相对[getSupportedFrameRate](#videocaps_getsupportedframerate1)方法获取的帧率性能更好。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------------- | ---- | ------------------------------------------------------------ | +| width | number | 是 | 视频宽度。单位:像素。 | +| height | number | 是 | 视频高度。单位:像素。 | +| callback | AsyncCallback\<[Range](#range8)> | 是 | 获取编解码器对特定视频宽度和高度推荐的帧率范围事件回调函数。 | + +**示例:** + +```js +videoCaps.getPreferredFrameRate(320, 240, (frameRate) => { // 获取320*240视频的推荐帧率范围 + if (typeof(frameRate) != 'undefined') { + console.log('videoCaps getPreferredFrameRate success'); + console.log('frameRate.min: ' + frameRate.min); + console.log('frameRate.max: ' + frameRate.max); + } else { + console.log('videoCaps getPreferredFrameRate fail'); + } +}); +``` + +### getPreferredFrameRate + +getPreferredFrameRate(width: number, height: number): Promise\<[Range](#range8)> + +获取编解码器对特定视频宽度和高度推荐的帧率范围。通过Promise获取执行结果。相对[getSupportedFrameRate](#videocaps_getsupportedframerate2)方法获取的帧率性能更好。 + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------ | ------ | ---- | ---------------------- | +| width | number | 是 | 视频宽度。单位:像素。 | +| height | number | 是 | 视频高度。单位:像素。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------- | ------------------------------------------------------------ | +| Promise\ | 获取编解码器对特定视频宽度和高度推荐的帧率范围的Promise返回值。 | + +**示例:** + +```js +function failureCallback(error) { + console.info(`videoCaps failureCallback, error:${error.message}`); +} +function catchCallback(error) { + console.info(`videoCaps catchCallback, error:${error.message}`); +} + +await videoCaps.getPreferredFrameRate(320, 240).then((frameRate) => { // 获取320*240视频的推荐帧率范围 + console.log('videoCaps getPreferredFrameRate success'); + console.log('frameRate.min: ' + frameRate.min); + console.log('frameRate.max: ' + frameRate.max); +}, failureCallback).catch(catchCallback); +``` + +## AVCodecInfo8+ + +编解码器描述信息类。 + +### 属性 + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| --------------------- | ---------------------------- | ---- | ---- | ------------------------------------------------------------ | +| name | string | 是 | 是 | 编解码器名称。 | +| type | [AVCodecType](#avcodectype8) | 是 | 是 | 编解码器类型。 | +| mimeType | string | 是 | 是 | 编解码器的MIME type。具体内容可参考[CodecMimeType](#codecmimetype8)。 | +| isHardwareAccelerated | boolean | 是 | 是 | 编解码器是否硬件加速。此属性由设备生产商提供。 | +| isSoftwareOnly | boolean | 是 | 是 | 编解码器是否纯软件。纯软编解码器更安全,但不保证性能。 | +| isVendor | boolean | 是 | 是 | 编解码器是否由设备生产商提供。 | + +## Range8+ + +数据范围类。 + +### 属性 + +| 名称 | 类型 | 可读 | 可写 | 说明 | +| ---- | ------ | ---- | ---- | ------------ | +| min | number | 是 | 是 | 范围的下限。 | +| max | number | 是 | 是 | 范围的上限。 | \ No newline at end of file