1# 媒体数据封装 2 3开发者可以调用本模块的Native API接口,完成音视频封装,即将音频、视频等编码后的媒体数据,按一定的格式存储到文件里。 4 5当前支持的封装能力请参考[AVCodec支持的格式](avcodec-support-formats.md#媒体数据封装) 6 7<!--RP2--><!--RP2End--> 8 9**适用场景** 10 11- 录像、录音 12 13 保存录像、录音文件时,需要先对音视频流进行编码,再封装为文件。 14 15- 音视频编辑 16 17 完成编辑后的音视频,需要封装为文件。 18 19- 音视频转码 20 21 转码后,保存文件时需要封装。 22 23## 开发指导 24 25详细的API说明请参考[API文档](../../reference/apis-avcodec-kit/_a_v_muxer.md)。 26 27> **说明:** 28> 29> 如果调用封装模块写本地文件,需要[向用户申请授权](../../security/AccessToken/request-user-authorization.md):ohos.permission.READ_MEDIA, ohos.permission.WRITE_MEDIA 30 31### 在 CMake 脚本中链接动态库 32 33``` cmake 34target_link_libraries(sample PUBLIC libnative_media_avmuxer.so) 35target_link_libraries(sample PUBLIC libnative_media_core.so) 36``` 37 38### 开发步骤 39 40参考以下示例代码,完成音视频封装的全流程。以封装mp4格式的音视频文件为例。 41 42不同的封装格式需要配置的key请参考[AVCodec支持的格式](avcodec-support-formats.md#媒体数据封装)。 43 441. 添加头文件。 45 46 ```c++ 47 #include <multimedia/player_framework/native_avmuxer.h> 48 #include <multimedia/player_framework/native_avcodec_base.h> 49 #include <multimedia/player_framework/native_avformat.h> 50 #include <multimedia/player_framework/native_avbuffer.h> 51 #include <fcntl.h> 52 ``` 53 542. 调用OH_AVMuxer_Create()创建封装器实例对象。 55 56 ```c++ 57 // 设置封装格式为mp4 58 OH_AVOutputFormat format = AV_OUTPUT_FORMAT_MPEG_4; 59 // 以读写方式创建fd 60 int32_t fd = open("test.mp4", O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR); 61 OH_AVMuxer *muxer = OH_AVMuxer_Create(fd, format); 62 ``` 63 643. (可选)调用OH_AVMuxer_SetRotation()设置旋转角度。 65 66 ```c++ 67 // 旋转角度,视频画面需要旋转的时候设置 68 OH_AVMuxer_SetRotation(muxer, 0); 69 ``` 70 714. 添加音频轨。 72 73 **方法一:用OH_AVFormat_Create创建format** 74 75 ```c++ 76 int audioTrackId = -1; 77 uint8_t *buffer = ...; // 编码config data,如果没有可以不传 78 size_t size = ...; // 编码config data的长度,根据实际情况配置 79 OH_AVFormat *formatAudio = OH_AVFormat_Create(); // 用OH_AVFormat_Create创建format, 这里以封装44100Hz采样率、2声道的AAC-LC音频为例。 80 OH_AVFormat_SetStringValue(formatAudio, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_AAC); // 必填 81 OH_AVFormat_SetIntValue(formatAudio, OH_MD_KEY_AUD_SAMPLE_RATE, 44100); // 必填 82 OH_AVFormat_SetIntValue(formatAudio, OH_MD_KEY_AUD_CHANNEL_COUNT, 2); // 必填 83 OH_AVFormat_SetIntValue(formatAudio, OH_MD_KEY_PROFILE, AAC_PROFILE_LC); // 选填 84 OH_AVFormat_SetBuffer(formatAudio, OH_MD_KEY_CODEC_CONFIG, buffer, size); // 选填 85 86 int ret = OH_AVMuxer_AddTrack(muxer, &audioTrackId, formatAudio); 87 if (ret != AV_ERR_OK || audioTrackId < 0) { 88 // 音频轨添加失败 89 } 90 OH_AVFormat_Destroy(formatAudio); // 销毁 91 ``` 92 93 **方法二:用OH_AVFormat_CreateAudioFormat创建format** 94 95 ```c++ 96 int audioTrackId = -1; 97 uint8_t *buffer = ...; // 编码config data,如果没有可以不传 98 size_t size = ...; // 编码config data的长度,根据实际情况配置 99 OH_AVFormat *formatAudio = OH_AVFormat_CreateAudioFormat(OH_AVCODEC_MIMETYPE_AUDIO_AAC, 44100, 2); 100 OH_AVFormat_SetIntValue(formatAudio, OH_MD_KEY_PROFILE, AAC_PROFILE_LC); // 选填 101 OH_AVFormat_SetBuffer(formatAudio, OH_MD_KEY_CODEC_CONFIG, buffer, size); // 选填 102 103 int ret = OH_AVMuxer_AddTrack(muxer, &audioTrackId, formatAudio); 104 if (ret != AV_ERR_OK || audioTrackId < 0) { 105 // 音频轨添加失败 106 } 107 OH_AVFormat_Destroy(formatAudio); // 销毁 108 ``` 109 1105. 添加视频轨。 111 112 **方法一:用OH_AVFormat_Create创建format** 113 114 ```c++ 115 int videoTrackId = -1; 116 uint8_t *buffer = ...; // 编码config data,如果没有可以不传 117 size_t size = ...; // 编码config data的长度,根据实际情况配置 118 OH_AVFormat *formatVideo = OH_AVFormat_Create(); 119 OH_AVFormat_SetStringValue(formatVideo, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_VIDEO_AVC); // 必填 120 OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_WIDTH, 1280); // 必填 121 OH_AVFormat_SetIntValue(formatVideo, OH_MD_KEY_HEIGHT, 720); // 必填 122 OH_AVFormat_SetBuffer(formatVideo, OH_MD_KEY_CODEC_CONFIG, buffer, size); // 非必须 123 124 int ret = OH_AVMuxer_AddTrack(muxer, &videoTrackId, formatVideo); 125 if (ret != AV_ERR_OK || videoTrackId < 0) { 126 // 视频轨添加失败 127 } 128 OH_AVFormat_Destroy(formatVideo); // 销毁 129 ``` 130 131 **方法二:用OH_AVFormat_CreateVideoFormat创建format** 132 133 ```c++ 134 int videoTrackId = -1; 135 uint8_t *buffer = ...; // 编码config data,如果没有可以不传 136 size_t size = ...; // 编码config data的长度,根据实际情况配置 137 OH_AVFormat *formatVideo = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC, 1280, 720); 138 OH_AVFormat_SetBuffer(formatVideo, OH_MD_KEY_CODEC_CONFIG, buffer, size); // 非必须 139 140 int ret = OH_AVMuxer_AddTrack(muxer, &videoTrackId, formatVideo); 141 if (ret != AV_ERR_OK || videoTrackId < 0) { 142 // 视频轨添加失败 143 } 144 OH_AVFormat_Destroy(formatVideo); // 销毁 145 ``` 146 1476. 添加封面轨。 148 149 **方法一:用OH_AVFormat_Create创建format** 150 151 ```c++ 152 int coverTrackId = -1; 153 OH_AVFormat *formatCover = OH_AVFormat_Create(); 154 OH_AVFormat_SetStringValue(formatCover, OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_IMAGE_JPG); 155 OH_AVFormat_SetIntValue(formatCover, OH_MD_KEY_WIDTH, 1280); 156 OH_AVFormat_SetIntValue(formatCover, OH_MD_KEY_HEIGHT, 720); 157 158 int ret = OH_AVMuxer_AddTrack(muxer, &coverTrackId, formatCover); 159 if (ret != AV_ERR_OK || coverTrackId < 0) { 160 // 添加封面失败 161 } 162 OH_AVFormat_Destroy(formatCover); // 销毁 163 ``` 164 165 **方法二:用OH_AVFormat_CreateVideoFormat创建format** 166 167 ```c++ 168 int coverTrackId = -1; 169 OH_AVFormat *formatCover = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_IMAGE_JPG, 1280, 720); 170 171 int ret = OH_AVMuxer_AddTrack(muxer, &coverTrackId, formatCover); 172 if (ret != AV_ERR_OK || coverTrackId < 0) { 173 // 添加封面失败 174 } 175 OH_AVFormat_Destroy(formatCover); // 销毁 176 ``` 177 1787. 调用OH_AVMuxer_Start()开始封装。 179 180 ```c++ 181 // 调用start,写封装文件头。start后,不能设置媒体参数、不能添加音视频轨 182 if (OH_AVMuxer_Start(muxer) != AV_ERR_OK) { 183 // 异常处理 184 } 185 ``` 186 1878. 调用OH_AVMuxer_WriteSampleBuffer(),写入封装数据。封装数据包括视频、音频、封面等数据。 188 189 ```c++ 190 // start后,才能开始写入数据 191 int size = ...; 192 OH_AVBuffer *sample = OH_AVBuffer_Create(size); // 创建AVBuffer 193 // 通过OH_AVBuffer_GetAddr(sample)往sampleBuffer里写入数据参考OH_AVBuffer的使用方法 194 // 封装封面,必须一次写完一张图片 195 196 // 创建buffer info 197 OH_AVCodecBufferAttr info = {0}; 198 info.pts = ...; // 当前数据的开始播放的时间,单位微秒,相对时间 199 info.size = size; // 当前数据的长度 200 info.offset = 0; // 偏移,一般为0 201 info.flags |= AVCODEC_BUFFER_FLAGS_SYNC_FRAME; // 当前数据的标志。具体参考OH_AVCodecBufferFlags 202 info.flags |= AVCODEC_BUFFER_FLAGS_CODEC_DATA; // 当annex-b格式的avc包含codec config的标志。 203 OH_AVBuffer_SetBufferAttr(sample, &info); // 设置buffer的属性. 204 int trackId = audioTrackId; // 选择写的音视频轨 205 206 int ret = OH_AVMuxer_WriteSampleBuffer(muxer, trackId, sample); 207 if (ret != AV_ERR_OK) { 208 // 异常处理 209 } 210 ``` 211 2129. 调用OH_AVMuxer_Stop(),停止封装。 213 214 ```c++ 215 // 调用stop,写封装文件尾。stop后不能写入媒体数据 216 if (OH_AVMuxer_Stop(muxer) != AV_ERR_OK) { 217 // 异常处理 218 } 219 ``` 220 22110. 调用OH_AVMuxer_Destroy()销毁实例,释放资源。注意不能重复销毁,会导致程序崩溃。 222 223 ```c++ 224 if (OH_AVMuxer_Destroy(muxer) != AV_ERR_OK) { 225 // 异常处理 226 } 227 muxer = NULL; 228 close(fd); // 关闭文件描述符 229 ``` 230