ffmpeg进行混音,将两路音频pcm数据合成一路输出

本文介绍了一个使用FFmpeg实现多路音频混音的C++类库。通过该库可以将不同采样率、位深及声道数的音频混合并转换为指定格式输出。示例程序展示了如何添加输入音频流、初始化混音器、添加音频帧及获取输出。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

ffmpeg进行混音,将两路音频pcm数据合成一路输出
audiomixer.h

#ifndef AUDIOMIXER_H
#define AUDIOMIXER_H

#include <map>
#include <mutex>
#include <cstdio>
#include <cstdint>
#include <string>
#include <memory>


extern "C"
{
   
   
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
#include <libavutil/opt.h>
}



class AudioMixer
{
   
   
public:
    AudioMixer();
    virtual ~AudioMixer();

    //添加音频输入通道
    int addAudioInput(uint32_t index, uint32_t samplerate, uint32_t channels, uint32_t bitsPerSample, AVSampleFormat format);
    //添加音频输出通道
    int addAudioOutput(const uint32_t samplerate, const uint32_t channels, const uint32_t bitsPerSample, const AVSampleFormat format);

    //多个通道时,混音持续到时间最长的一个通道为止
    int init(const char* duration = "longest");
    int exit();

    int addFrame(uint32_t index, uint8_t *inBuf, uint32_t size);
    int getFrame(uint8_t *outBuf, uint32_t maxOutBufSize);

private:
    struct AudioInfo
    {
   
   
        AudioInfo()
        {
   
   
            filterCtx = nullptr;
        }

        AVFilterContext *filterCtx;
        uint32_t samplerate;
        uint32_t channels;
        uint32_t bitsPerSample;
        AVSampleFormat format;
        std::string name;
    };

    AVFilterGraph* filterGraph;

    bool inited;
    std::mutex mutex;
    //输入
    std::map<uint32_t, AudioInfo> audio_input_infos;
    //转换格式
    std::shared_ptr<AudioInfo> audio_output_info_ptr;
    //输出
    std::shared_ptr<AudioInfo> audio_sink_info_ptr;
    //混音
    std::shared_ptr<AudioInfo> audio_mix_info_ptr;

};

#endif // AUDIOMIXER_H

audiomixer.cpp

#include "audiomixer.h"
#include <iostream>

AudioMixer::AudioMixer():
    inited(false),
    filterGraph(nullptr),
    audio_output_info_ptr(nullptr)
{
   
   
    //初始化重置智能指针
    audio_mix_info_ptr.reset(new AudioInfo);
    audio_mix_info_ptr->name = "amix";//混音

    audio_sink_info_ptr.reset(new AudioInfo);
    audio_sink_info_ptr->name = "sink";//输出


}

AudioMixer::~AudioMixer()
{
   
   
    if(inited)
    {
   
   
        exit();
    }
}

int AudioMixer::addAudioInput(uint32_t index, uint32_t samplerate, uint32_t channels, uint32_t bitsPerSample, AVSampleFormat format)
{
   
   
    std::lock_guard<std::mutex> locker(mutex);

    if(inited)
    {
   
   
        std::cout<< __PRETTY_FUNCTION__ << "inited return -1!" << std::endl;
        return -1;
    }

    //根据index保存是否已经存在
    if(audio_input_infos.find(index) != audio_input_infos.end())
    {
   
   
        return -1;
    }

    //
    auto& filterInfo = audio_input_infos[index];
    //设置音频相关参数
    filterInfo.samplerate = samplerate;
    filterInfo.channels = channels;
    filterInfo.bitsPerSample = bitsPerSample;
    filterInfo.format = format;
    filterInfo.name = std::string("input") + std::to_string(index);

    return 0;

}

int AudioMixer::addAudioOutput(const uint32_t samplerate, const uint32_t chann

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值