简单记录一下个人做语音聊天时使用的ffmpeg音频编码。
我们可以
1.使用ffmpeg将PCM编码得到想要的格式的数据输出到内存中,然后自己实现流媒体协议或者使用自己的RPC。
2.使用ffmpeg的avio_open直接推流,ffmpeg帮我们实现了http rtmp rtp 协议。
简单说下编码输出到内存的流程:
编码并推流的流程:
直接上代码
#ifndef _IEncode_H
#define _IEncode_H
#include "util.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
};
struct AudioParams {
int sampleRate;
int channels;
enum AVSampleFormat fmt;
long long bitRate;
AVCodecID id;
int64_t channel_layout;
AudioParams() : sampleRate(-1), channels(-1), channel_layout(-1),
fmt(AVSampleFormat::AV_SAMPLE_FMT_NONE), bitRate(-1),
id(AVCodecID::AV_CODEC_ID_NONE)
{
}
AudioParams(const AudioParams& audioParams)
{
*this = audioParams;
}
AudioParams& operator=(const AudioParams& audioParams)
{
this->sampleRate = audioParams.sampleRate;
this->channels = audioParams.channels;
this->fmt = audioParams.fmt;
this->bitRate = audioParams.bitRate;
this->id = audioParams.id;
this->channel_layout = audioParams.channel_layout;
return *this;
}
};
class IEncode
{
public:
explicit IEncode();
virtual int init() = 0;
int inputData(uint8_t* data, size_t size);
int getNextOutPacketData(bool &hasData);
int getBufSize() const;
AudioParams getAudioParams()const;
virtual ~IEncode();
protected:
AudioParams audioParams;
AVCodec* codec;
AVCodecContext* ctx;
AVFrame *frame;
void *samples;
int bufferSize;
AVPacket avpkt;
AVStream *out_stream;
void setFrameParam(AVFrame *frame, AVCodecContext* ctx);
virtual void release() = 0;
virtual int writeFrame(AVPacket avpkt) = 0;
};
#endif // !_IEncode_H
#ifndef _IEncode_MEM_H
#define _IEncode_MEM_H
#include "IEncode.h"
class IEncode_mem : public IEncode
{
public:
typedef void(*writeOutDataF