音频编码
====

开发者可以调用本模块的Native API接口，完成音频编码，即将音频PCM编码压缩成不同的格式。

接口不限制PCM数据的来源，开发者可以调用麦克风录制获取、也可以导入编辑后的PCM数据，通过音频编码，输出对应格式的码流，最后封装为目标格式文件。

当前支持的编码能力请参考[AVCodec支持的格式](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/avcodec-support-formats#音频编码)。

**适用场景**

*   音频录制
    
    通过录制传入PCM，然后编码出对应格式的码流，最后[封装](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/audio-video-muxer)为所需格式的音频文件。
    
*   音频编辑
    
    编辑PCM后导出音频文件的场景，需要编码成对应音频格式后再[封装](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/audio-video-muxer)成文件。
    

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/9b/v3/N62-ph1TTYWxR4gIqg-LIg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=BF34E3DD07C139B1E3CF6BFF58034BC2CCDC53113083B87C1FED7F2EB7434E63)

*   AAC编码器默认采用的VBR可变码率模式，与配置的预期参数可能存在偏差。
*   AAC编码器默认输出携带ADTS头部，帧数据的前7字节为ADTS头部。

#### 开发指导

详细的API说明请参考[native\_avcodec\_audiocodec.h](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-avcodec-audiocodec-h)。

参考以下示例代码，完成音频编码的全流程，包括：创建编码器、设置编码参数（采样率/码率/声道数等）、开始、刷新、重置、销毁资源。

在应用开发过程中，开发者应按一定顺序调用方法，执行对应操作，否则系统可能会抛出异常或生成其他未定义的行为。具体顺序可参考下列开发步骤及对应说明。

如下为音频编码调用关系图：

*   虚线表示可选。
    
*   实线表示必选。
    

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/23/v3/ijssRkFBSIKQbIn73JQioA/zh-cn_image_0000002664208381.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=9523F48A2C8974EBD67088B0CA9E199DADE0FEC691F4FCF6AA27DC1003917A18)

#### \[h2\]在 CMake 脚本中链接动态库

target\_link\_libraries(sample PUBLIC libnative\_media\_codecbase.so)
target\_link\_libraries(sample PUBLIC libnative\_media\_core.so)
target\_link\_libraries(sample PUBLIC libnative\_media\_acodec.so)

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/92/v3/5jrM0zrPTqCJaWGbMF9w3A/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=656B9EE8C115BCE5D4EA54ADD20397CBB8BB8EC6916D3B9B45AFB26D1DDEBEE5)

上述'sample'字样仅为示例，此处由开发者根据实际工程目录自定义。

#### \[h2\]开发步骤

1.  添加所需的头文件。
    
    #include <multimedia/player\_framework/native\_avcodec\_audiocodec.h>
    #include <multimedia/native\_audio\_channel\_layout.h>
    #include <multimedia/player\_framework/native\_avcapability.h>
    #include <multimedia/player\_framework/native\_avcodec\_base.h>
    #include <multimedia/player\_framework/native\_avformat.h>
    #include <multimedia/player\_framework/native\_avbuffer.h>
    
2.  创建编码器实例对象，OH\_AVCodec\*为编码器实例指针。
    
    应用可以通过媒体类型或编解码器名称创建编码器。
    
    方法一：通过mime type创建编码器。
    
    // 设置判定是否为编码；设置true表示当前是编码。
    bool isEncoder = true;
    // 通过媒体类型创建编码器。
    OH\_AVCodec \*audioEnc\_ = OH\_AudioCodec\_CreateByMime(OH\_AVCODEC\_MIMETYPE\_AUDIO\_AAC, isEncoder);
    
    方法二：通过codec name创建编码器。
    
    // 通过codec name创建编码器。
    OH\_AVCapability \*capability = OH\_AVCodec\_GetCapability(OH\_AVCODEC\_MIMETYPE\_AUDIO\_AAC, true);
    const char \*name = OH\_AVCapability\_GetName(capability);
    OH\_AVCodec \*audioEnc\_ = OH\_AudioCodec\_CreateByName(name);
    
    添加头文件和命名空间:
    
    #include <mutex>
    #include <queue>
    // c++标准库命名空间。
    using namespace std;
    
    示例代码：
    
    // 初始化队列。
    class AEncBufferSignal {
    public:
        std::mutex inMutex\_;
        std::mutex outMutex\_;
        std::mutex startMutex\_;
        std::condition\_variable inCond\_;
        std::condition\_variable outCond\_;
        std::condition\_variable startCond\_;
        std::queue<uint32\_t> inQueue\_;
        std::queue<uint32\_t> outQueue\_;
        std::queue<OH\_AVBuffer \*> inBufferQueue\_;
        std::queue<OH\_AVBuffer \*> outBufferQueue\_;
    };
    AEncBufferSignal \*signal\_;
    
3.  调用OH\_AudioCodec\_RegisterCallback()注册回调函数。
    
    注册回调函数指针集合OH\_AVCodecCallback，包括：
    
    *   OH\_AVCodecOnError：编码器运行错误。
    *   OH\_AVCodecOnStreamChanged：音频编码器暂未支持此回调。
    *   OH\_AVCodecOnNeedInputBuffer：运行过程中需要新的输入数据，即编码器已准备好，可以输入PCM数据。
    *   OH\_AVCodecOnNewOutputBuffer：运行过程中产生了新的输出数据，即编码完成。
    
    开发者可以通过处理该回调报告的信息，确保编码器正常运转。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/90/v3/Rk2B6QaESRu-9l9_twDSKQ/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=1555FA668D80B838EE29D14DABB769DE0EBC9FEB420407089BF385B2E186E577)
    
    请勿在回调中调用编码器的相关接口或进行耗时操作。
    
    // OH\_AVCodecOnError回调函数的实现。
    static void OnError(OH\_AVCodec \*codec, int32\_t errorCode, void \*userData)
    {
        (void)codec;
        (void)errorCode;
        (void)userData;
    }
    // OH\_AVCodecOnStreamChanged回调函数的实现。
    static void OnOutputFormatChanged(OH\_AVCodec \*codec, OH\_AVFormat \*format, void \*userData)
    {
        (void)codec;
        (void)format;
        (void)userData;
    }
    // OH\_AVCodecOnNeedInputBuffer回调函数的实现。
    static void OnInputBufferAvailable(OH\_AVCodec \*codec, uint32\_t index, OH\_AVBuffer \*data, void \*userData)
    {
        (void)codec;
        // 编码输入码流送入InputBuffer队列。
        AEncBufferSignal \*signal = static\_cast<AEncBufferSignal \*>(userData);
        unique\_lock<mutex> lock(signal->inMutex\_);
        signal->inQueue\_.push(index);
        signal->inBufferQueue\_.push(data);
        signal->inCond\_.notify\_all();
    }
    // OH\_AVCodecOnNewOutputBuffer回调函数的实现。
    static void OnOutputBufferAvailable(OH\_AVCodec \*codec, uint32\_t index, OH\_AVBuffer \*data, void \*userData)
    {
        (void)codec;
        // 将对应输出buffer的index送入OutputQueue\_队列。
        // 将对应编码完成的数据data送入outBuffer队列。
        AEncBufferSignal \*signal = static\_cast<AEncBufferSignal \*>(userData);
        unique\_lock<mutex> lock(signal->outMutex\_);
        signal->outQueue\_.push(index);
        signal->outBufferQueue\_.push(data);
        signal->outCond\_.notify\_all();
    }
    
    配置回调：
    
    signal\_ = new AEncBufferSignal();
    OH\_AVCodecCallback cb\_ = {&OnError, &OnOutputFormatChanged, &OnInputBufferAvailable, &OnOutputBufferAvailable};
    // 配置异步回调。
    int32\_t ret = OH\_AudioCodec\_RegisterCallback(audioEnc\_, cb\_, signal\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
4.  调用OH\_AudioCodec\_Configure设置编码器。
    
    配置选项key值说明：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/99/v3/a-QqG-11S0eP0YBnS4ieDQ/zh-cn_image_0000002664328441.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=03FB022324743E390290700B5B1CE30AD2D71F8E5A7FE764D40283C633865571)
    
    各音频编码类型参数范围说明：
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/e1/v3/H8lnoqj_RjKTHyrL9FIG6w/zh-cn_image_0000002633849330.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=F6AD3A1A5B821C4375E25EB6EF6913F044BDF296A302DE2948026A4BC2A2ACB6)
    
    例如对一个44100Hz采样率、2声道立体声、SAMPLE\_S16LE采样格式的PCM音频，以32000bps的码率进行AAC编码的调用流程如下：
    

   int32\_t ret;
   // 配置音频采样率（必须）
   constexpr uint32\_t DEFAULT\_SAMPLERATE = 44100;
   // 配置音频码率（必须）
   constexpr uint64\_t DEFAULT\_BITRATE = 32000;
   // 配置音频声道数（必须）
   constexpr uint32\_t DEFAULT\_CHANNEL\_COUNT = 2;
   // 配置音频声道类型（必须）
   constexpr OH\_AudioChannelLayout CHANNEL\_LAYOUT = OH\_AudioChannelLayout::CH\_LAYOUT\_STEREO;
   // 配置音频位深（必须）
   constexpr OH\_BitsPerSample SAMPLE\_FORMAT = OH\_BitsPerSample::SAMPLE\_S16LE;
   // 配置AAC profile（可选，默认值：AAC\_PROFILE\_LC，其他可选值：AAC\_PROFILE\_HE、AAC\_PROFILE\_HE\_V2）
   constexpr int32\_t AAC\_PROFILE = OH\_AACProfile::AAC\_PROFILE\_LC;

   OH\_AVFormat \*format = OH\_AVFormat\_Create();
   // 写入format
   OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_CHANNEL\_COUNT, DEFAULT\_CHANNEL\_COUNT);
   OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_SAMPLE\_RATE, DEFAULT\_SAMPLERATE);
   OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_BITRATE, DEFAULT\_BITRATE);
   OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUDIO\_SAMPLE\_FORMAT, SAMPLE\_FORMAT);
   OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_CHANNEL\_LAYOUT, CHANNEL\_LAYOUT);
   OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_PROFILE, AAC\_PROFILE);
   // 配置编码器
   ret = OH\_AudioCodec\_Configure(audioEnc\_, format);
   if (ret != AV\_ERR\_OK) {
       // 异常处理
   }

例FLAC调用流程：

int32\_t ret;
// 配置音频采样率（必须）。
constexpr uint32\_t DEFAULT\_SAMPLERATE = 44100;
// 配置音频码率（必须）。
constexpr uint64\_t DEFAULT\_BITRATE = 261000;
// 配置音频声道数（必须）。
constexpr uint32\_t DEFAULT\_CHANNEL\_COUNT = 2;
// 配置音频声道布局（必须）。
// 值为CH\_LAYOUT\_MONO、CH\_LAYOUT\_STEREO、CH\_LAYOUT\_SURROUND、CH\_LAYOUT\_QUAD、CH\_LAYOUT\_5POINT0、CH\_LAYOUT\_5POINT1、CH\_LAYOUT\_6POINT1或CH\_LAYOUT\_7POINT1其中一项。
constexpr OH\_AudioChannelLayout CHANNEL\_LAYOUT = OH\_AudioChannelLayout::CH\_LAYOUT\_STEREO;
// 配置音频位深（必须） flac只有SAMPLE\_S16LE和SAMPLE\_S32LE。
constexpr OH\_BitsPerSample SAMPLE\_FORMAT = OH\_BitsPerSample::SAMPLE\_S32LE;
// 配置音频compliance level (默认值0，取值范围-2~2)。
constexpr int32\_t COMPLIANCE\_LEVEL = 0;

OH\_AVFormat \*format = OH\_AVFormat\_Create();
// 写入format。
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_CHANNEL\_COUNT, DEFAULT\_CHANNEL\_COUNT);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_SAMPLE\_RATE, DEFAULT\_SAMPLERATE);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_BITRATE, DEFAULT\_BITRATE);
// 配置音频精度。API version 20前，FLAC编码必须设置此参数，设置为1即可；未设置此参数配置FLAC编码器时，调用OH\_AudioCodec\_Configure会返回错误码AV\_ERR\_INVALID\_VAL。该值无实际作   用，不会影响编码结果。从API version 20开始，无需设置此参数。
// constexpr int32\_t BITS\_PER\_CODED\_SAMPLE = 1;
// OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_BITS\_PER\_CODED\_SAMPLE, BITS\_PER\_CODED\_SAMPLE);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUDIO\_SAMPLE\_FORMAT, SAMPLE\_FORMAT);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_CHANNEL\_LAYOUT, CHANNEL\_LAYOUT);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_COMPLIANCE\_LEVEL, COMPLIANCE\_LEVEL);
// 配置编码器。
ret = OH\_AudioCodec\_Configure(audioEnc\_, format);
if (ret != AV\_ERR\_OK) {
    // 异常处理。
}

例AMR编码调用流程：

int32\_t ret;
// 配置音频采样率（必须），amr-nb输入采样率为8000hz的PCM，amr-wb输入采样率为16000hz的PCM
constexpr uint32\_t DEFAULT\_SAMPLERATE = 8000;
// 配置音频码率（必须）
// amr-nb支持码率4750、5150、5900、6700、7400、7950、10200、12200
// amr-wb支持码率6600、8850、12650、14250、15850、18250、19850、23050、23850
constexpr uint64\_t DEFAULT\_BITRATE = 10200;
// 配置音频声道数（必须）
constexpr uint32\_t DEFAULT\_CHANNEL\_COUNT = 1;
// 配置音频声道类型（必须）
constexpr OH\_AudioChannelLayout CHANNEL\_LAYOUT = OH\_AudioChannelLayout::CH\_LAYOUT\_MONO;
// 配置音频位深（必须）
constexpr OH\_BitsPerSample SAMPLE\_FORMAT = OH\_BitsPerSample::SAMPLE\_S16LE;
OH\_AVFormat \*format = OH\_AVFormat\_Create();
// 写入format
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_CHANNEL\_COUNT, DEFAULT\_CHANNEL\_COUNT);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_SAMPLE\_RATE, DEFAULT\_SAMPLERATE);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_BITRATE, DEFAULT\_BITRATE);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUDIO\_SAMPLE\_FORMAT, SAMPLE\_FORMAT);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_CHANNEL\_LAYOUT, CHANNEL\_LAYOUT);
// 配置编码器
ret = OH\_AudioCodec\_Configure(audioEnc\_, format);
if (ret != AV\_ERR\_OK) {
    // 异常处理
}

例opus编码调用流程：

int32\_t ret;
// 配置音频采样率（必须）
// opus编码支持采样率：8000、12000、16000、24000、48000
constexpr uint32\_t DEFAULT\_SAMPLERATE = 8000;
// 配置音频码率（必须）
// opus编码码率范围：\[6000, 510000\]
constexpr uint64\_t DEFAULT\_BITRATE = 6000;
// 配置音频声道数（必须）
// opus编码支持声道数：1、2
constexpr uint32\_t DEFAULT\_CHANNEL\_COUNT = 1;
// 配置音频位深（必须）
// opus编码支持位深：SAMPLE\_S16LE
constexpr OH\_BitsPerSample SAMPLE\_FORMAT = OH\_BitsPerSample::SAMPLE\_S16LE;
OH\_AVFormat \*format = OH\_AVFormat\_Create();
// 写入format
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_CHANNEL\_COUNT, DEFAULT\_CHANNEL\_COUNT);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUD\_SAMPLE\_RATE, DEFAULT\_SAMPLERATE);
OH\_AVFormat\_SetLongValue(format, OH\_MD\_KEY\_BITRATE, DEFAULT\_BITRATE);
OH\_AVFormat\_SetIntValue(format, OH\_MD\_KEY\_AUDIO\_SAMPLE\_FORMAT, SAMPLE\_FORMAT);
// 配置编码器
ret = OH\_AudioCodec\_Configure(audioEnc\_, format);
if (ret != AV\_ERR\_OK) {
    // 异常处理
}

1.  调用OH\_AudioCodec\_Prepare()，编码器就绪。
    
    int32\_t ret = OH\_AudioCodec\_Prepare(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
2.  调用OH\_AudioCodec\_Start()启动编码器，进入运行态。
    
    添加头文件：
    
    #include <fstream>
    
    使用示例：
    
    ifstream inputFile\_;
    ofstream outFile\_;
    
    // 根据实际使用情况填写输入文件路径。
    const char\* inputFilePath = "/";
    // 根据实际使用情况填写输出文件路径。
    const char\* outputFilePath = "/";
    // 打开待编码二进制文件路径（此处以输入为PCM文件为例）。
    inputFile\_.open(inputFilePath, ios::in | ios::binary);
    // 配置编码文件输出路径（此处以输出为编码码流文件为例）。
    outFile\_.open(outputFilePath, ios::out | ios::binary);
    // 开始编码。
    int32\_t ret = OH\_AudioCodec\_Start(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
3.  调用OH\_AudioCodec\_PushInputBuffer()，写入待编码的数据。需开发者填充完整的输入数据后调用。
    
    每次输入的采样点数（SAMPLES\_PER\_FRAME）取值方法如下：
    
    AAC-LC编码每帧包含1024个PCM样点，建议单次输入1024个样点的数据量。
    
    HE-AAC编码每帧包含2048个PCM样点，建议单次输入2048个样点的数据量。
    
    flac比较特殊，需要根据如下表格进行设置。
    
    | 采样率 | 样点数 |
    | :-- | :-- |
    | 8000 | 576 |
    | 16000 | 1152 |
    | 22050 | 2304 |
    | 24000 | 2304 |
    | 32000 | 2304 |
    | 44100 | 4608 |
    | 48000 | 4608 |
    | 88200 | 8192 |
    | 96000 | 8192 |
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/dd/v3/W3bYPVUhRJ27FZH93TkH6g/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=944220026BC4EF0908D10D1EB77837D9CF0C0744E9AA05A4BD6B6B83A6D7B605)
    
    单次编码输入的数据量（单位：字节）为：采样点数（SAMPLES\_PER\_FRAME） \* 声道数 \* 单个采样点的占用字节。
    
    flac编码的样点数建议参考表格根据采样率对应的样点数进行设置，否则可能出现编码文件损坏问题。
    
    // 声道数。
    constexpr int32\_t DEFAULT\_CHANNEL\_COUNT = 2;
    // 采样点数，这里以AAC-LC为例，采样点数为1024。
    constexpr int32\_t SAMPLES\_PER\_FRAME = 1024;
    // 单次编码输入的数据量（单位：字节）为：采样点数 \* 声道数 \* 单个采样点的占用字节（以采样格式SAMPLE\_S16LE为例）。
    // 如果最后一帧数据不满足长度，建议进行丢弃或填充处理。
    constexpr int32\_t INPUT\_FRAME\_BYTES = SAMPLES\_PER\_FRAME \* DEFAULT\_CHANNEL\_COUNT \* sizeof(short);
    uint32\_t index = signal\_->inQueue\_.front();
    auto buffer = signal\_->inBufferQueue\_.front();
    OH\_AVCodecBufferAttr attr = {0};
    if (!inputFile\_.eof()) {
        inputFile\_.read((char \*)OH\_AVBuffer\_GetAddr(buffer), INPUT\_FRAME\_BYTES);
        attr.size = INPUT\_FRAME\_BYTES;
        attr.flags = AVCODEC\_BUFFER\_FLAGS\_NONE;
    } else {
        attr.size = 0;
        attr.flags = AVCODEC\_BUFFER\_FLAGS\_EOS;
    }
    OH\_AVBuffer\_SetBufferAttr(buffer, &attr);
    // 送入编码输入队列进行编码, index为对应队列下标。
    int32\_t ret = OH\_AudioCodec\_PushInputBuffer(audioEnc\_, index);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
    在上方案例中，attr.flags代表缓冲区标记的类别。
    
    结束时需要将flags标识为AVCODEC\_BUFFER\_FLAGS\_EOS。
    
    | 枚举值 | 描述 |
    | :-- | :-- |
    | AVCODEC\_BUFFER\_FLAGS\_NONE | 表示为普通帧。 |
    | AVCODEC\_BUFFER\_FLAGS\_EOS | 表示缓冲区是流结束帧。 |
    | AVCODEC\_BUFFER\_FLAGS\_CODEC\_DATA | 表示缓冲区包含编解码特定数据。 |
    
4.  调用OH\_AudioCodec\_FreeOutputBuffer()，释放编码后的数据。
    
    在取走编码码流后，就应及时调用OH\_AudioCodec\_FreeOutputBuffer()进行释放。
    
    uint32\_t index = signal\_->outQueue\_.front();
    OH\_AVBuffer \*avBuffer = signal\_->outBufferQueue\_.front();
    if (avBuffer == nullptr) {
        // 异常处理
    }
    // 获取buffer attributes。
    OH\_AVCodecBufferAttr attr = {0};
    int32\_t ret = OH\_AVBuffer\_GetBufferAttr(avBuffer, &attr);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    // 将编码完成数据data写入到对应输出文件中。
    outFile\_.write(reinterpret\_cast<char \*>(OH\_AVBuffer\_GetAddr(avBuffer)), attr.size);
    // 释放已完成写入的数据。
    ret = OH\_AudioCodec\_FreeOutputBuffer(audioEnc\_, index);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    if (attr.flags == AVCODEC\_BUFFER\_FLAGS\_EOS) {
        // 结束。
    }
    
5.  （可选）调用OH\_AudioCodec\_Flush()刷新编码器。
    
    调用OH\_AudioCodec\_Flush()后，编码器处于Flush状态，会将当前编码队列清空。
    
    此时需要调用OH\_AudioCodec\_Start()重新开始编码。
    
    使用情况：
    
    *   在编码输出buffer属性为AVCODEC\_BUFFER\_FLAGS\_EOS后，若想重新使用相同配置进行编码时，需要调用刷新。
    *   在执行过程中遇到可继续执行的错误时（即OH\_AudioCodec\_IsValid()为true）可以调用刷新，然后调用OH\_AudioCodec\_Start()重新开始编码。
    
    // 刷新编码器 audioEnc\_。
    int32\_t ret = OH\_AudioCodec\_Flush(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    // 重新开始编码。
    ret = OH\_AudioCodec\_Start(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
6.  （可选）调用OH\_AudioCodec\_Reset()重置编码器。
    
    调用OH\_AudioCodec\_Reset()后，编码器回到初始化状态，重置前获取到的输入/输出buffer都无法继续使用，需先调用OH\_AudioCodec\_Configure()重新配置，再调用OH\_AudioCodec\_Start()重新开始编码。启动后重新获取输入/输出buffer。
    
    // 重置编码器 audioEnc\_。
    int32\_t ret = OH\_AudioCodec\_Reset(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    // 重新配置编码器参数。
    ret = OH\_AudioCodec\_Configure(audioEnc\_, format);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
7.  调用OH\_AudioCodec\_Stop()停止编码器。
    
    停止后，可以通过调用OH\_AudioCodec\_Start()重新进入已启动状态（started）。停止前获取到的输入/输出buffer都无法继续使用，需要在启动后重新获取输入/输出buffer。
    
    // 终止编码器 audioEnc\_。
    int32\_t ret = OH\_AudioCodec\_Stop(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    }
    
8.  调用OH\_AudioCodec\_Destroy()销毁编码器实例，释放资源。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/79/v3/ZDxseYzVRVeWuQZzilNbVQ/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132515Z&HW-CC-Expire=86400&HW-CC-Sign=F91E8F600DDE4FA08E0347F21CDA67BCF6795EC31E8090F1279D27D0AD5D3706)
    
    禁止重复销毁编码器。
    
    // 调用OH\_AudioCodec\_Destroy, 销毁编码器。
    int32\_t ret = OH\_AudioCodec\_Destroy(audioEnc\_);
    if (ret != AV\_ERR\_OK) {
        // 异常处理。
    } else {
        audioEnc\_ = NULL; // 不可重复destroy。
    }