From 82a1d2a2c92dbfa03ea4de16b25d650188db4193 Mon Sep 17 00:00:00 2001 From: m00472246 Date: Tue, 25 Jan 2022 16:54:03 +0800 Subject: [PATCH] video decoder word Signed-off-by: m00472246 Signed-off-by: m00472246 Change-Id: Ia8112113563539ff8b360b34893baa4fdd7ce344 Signed-off-by: m00472246 --- zh-cn/application-dev/media/Readme-CN.md | 7 + .../zh-ch_image_image_video_decoder.png | Bin 0 -> 123204 bytes ...h-ch_image_image_video_decoder_machine.jpg | Bin 0 -> 27903 bytes zh-cn/application-dev/media/video-decoder.md | 251 +++ .../reference/apis/js-apis-media.md | 1496 ++++++++++++++++- 5 files changed, 1706 insertions(+), 48 deletions(-) create mode 100644 zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder.png create mode 100644 zh-cn/application-dev/media/figures/zh-ch_image_image_video_decoder_machine.jpg create mode 100644 zh-cn/application-dev/media/video-decoder.md diff --git a/zh-cn/application-dev/media/Readme-CN.md b/zh-cn/application-dev/media/Readme-CN.md index f4c1c506f20..230a66423de 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 GIT binary patch literal 123204 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 literal 0 HcmV?d00001 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 GIT binary patch literal 27903 zcmdSBcT`i|*DkuTVFLs!(v+$KK|)bFN;mXsAb|8{z=Ynh(u*L3CMZa6(nD7|grcEI zM?#U_OQ?4TeP4g$e&d{bzB|S}_ufA;WSh0tUTdy7=bH1G&x*gQvK+

t_J~piq#P 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 qefS?u1pnfE@&92l!2`=1uuzq2Gd{ { // 订阅视频解码的输入视频帧内存事件 + 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 718a612763e..2bbacc43a3b 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 -- Gitee