音频过滤器框架同视频相似(可参考我的视频框架分析),有一个小小不同是音频在出口过滤器abuffersink前还需要一个接收过滤器aformat。具体见代码。
下面是实例代码,输入2段音频,将音频混合起来。
AudioMixer.h文件
#pragma once
#include<map>
#include<mutex>
#include<cstdio>
#include<cstdint>
#include<string>
#include<memory>
#include<sstream>
#include<iostream>
#include<fstream>
extern "C" {
#include<libavcodec/avcodec.h>
#include<libavformat/avformat.h>
#include<libavfilter/avfilter.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;
}
uint32_t samplerate;
uint32_t channels;
uint32_t bitsPerSample;
AVSampleFormat format;
std::string name;
AVFilterContext* filterCtx;
};
bool initialized_ = false;
std::mutex mutex_;
std::map<uint32_t, AudioInfo> audio_input_info_;
std::shared_ptr<AudioInfo> audio_out_info_;
std::shared_ptr<AudioInfo> audio_mix_info_;
std::shared_ptr<AudioInfo> audio_sink_info_;
AVFilterGraph* filter_graph_ = nullptr;
};
AudioMixer.cpp文件
#include "AudioMixer.h"
AudioMixer::AudioMixer() :initialized_(false), filter_graph_(nullptr), audio_out_info_(nullptr)
{
audio_mix_info_.reset(new AudioInfo);
audio_mix_info_->name = "amix";
audio_sink_info_.reset(new AudioInfo);
audio_sink_info_->name = "sink";
}
AudioMixer::~AudioMixer()
{
if (initialized_) {
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 (initialized_) {
return -1;
}
//判断是否存在当前输入
if (audio_input_info_.find(index) != audio_input_info_.end()) {
return -1;
}
//初始化输入,可以有多个输入流
auto& filterInfo = audio_input_info_[index];
filterInfo.samplerate = samplerate;
filterInfo.channels = channels;
filterInfo.bitsPerSample = bitsPerSample;
filterInfo.format = format;
filterInfo.name = std::string("input") + st