代码拉取完成,页面将自动刷新
#include <QEventLoop>
#include <QThread>
#include <QDebug>
#include "common/AVAudioConvert.h"
#include "encode/AVFileStoreAAC.h"
#include "encode/AVFileStoreMP3.h"
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
#include <libavutil/time.h>
}
#include "AudioDataDispatcher.h"
AudioDataDispatcher::AudioDataDispatcher(QObject *parent):QObject(parent),
m_micBuffer(16 * 1024,false),m_spkBuffer(16 * 1024,false)/* 16k的buffer足够了 */
{
m_micBuffer.setWriteMode(LoopBuffer::WriteTotalUnlimited);
m_micBuffer.open(QIODevice::ReadWrite);
m_spkBuffer.setWriteMode(LoopBuffer::WriteTotalUnlimited);
m_spkBuffer.open(QIODevice::ReadWrite);
av_register_all();
m_aac = new AVFileStoreAAC("test.aac");
m_aac->init();
m_mp3 = new AVFileStoreMP3("test.mp3");
m_mp3->init();
}
AudioDataDispatcher::~AudioDataDispatcher()
{}
void AudioDataDispatcher::acceptMicData(AVFrame *frame)
{
// m_micList.push_back(frame);
int writeBytes = av_samples_get_buffer_size(NULL,frame->channels,frame->nb_samples,(AVSampleFormat)frame->format,1);
m_micBuffer.writeData((const char*)frame->data[0],writeBytes);
av_frame_unref(frame);
av_frame_free(&frame);
}
void AudioDataDispatcher::acceptSpeakerData(AVFrame *frame)
{
// m_speakList.push_back(frame);
int writeBytes = av_samples_get_buffer_size(NULL,frame->channels,frame->nb_samples,(AVSampleFormat)frame->format,1);
m_spkBuffer.writeData((const char*)frame->data[0],writeBytes);
av_frame_unref(frame);
av_frame_free(&frame);
}
void AudioDataDispatcher::acceptMacMicData(AVFrame *frame)
{
int writeBytes = av_samples_get_buffer_size(NULL,frame->channels,frame->nb_samples,(AVSampleFormat)frame->format,1);
m_micBuffer.writeData((const char*)frame->data[0],writeBytes);
m_spkBuffer.writeData((const char*)frame->data[0],writeBytes);
}
void AudioDataDispatcher::run()
{
QEventLoop loop;
while (true) {
loop.processEvents(QEventLoop::AllEvents);
/* list暂时不用了,用了buffer */
if (!m_micList.isEmpty()) {
AVFrame *tempFrame = m_micList.first();
av_frame_unref(tempFrame);
av_frame_free(&tempFrame);
m_micList.pop_front();
}
if (!m_speakList.isEmpty()) {
AVFrame *tempFrame = m_speakList.first();
av_frame_unref(tempFrame);
av_frame_free(&tempFrame);
m_speakList.pop_front();
}
const int nbsamples = 1024;
int samples = 44100;
int channels = 2;
const int singleChannelSize = nbsamples * 1 * 2;
char micBuf[singleChannelSize] = {0};
char spkBuf[singleChannelSize] = {0};
/* 关于数据回调不一致,读取的数据不一致的处理情况。 */
if (m_spkBuffer.usedSize() >= singleChannelSize && m_micBuffer.usedSize() >= singleChannelSize) {
AVFrame * dstFrame = av_frame_alloc();
dstFrame->format = AV_SAMPLE_FMT_S16P;
dstFrame->sample_rate = samples;
dstFrame->nb_samples = nbsamples;
dstFrame->channels = channels;
dstFrame->channel_layout = av_get_default_channel_layout(dstFrame->channels);
int dstSize = av_samples_get_buffer_size(NULL,dstFrame->channels,dstFrame->nb_samples,(AVSampleFormat)dstFrame->format,1);
QByteArray bytes(dstSize,0);
m_spkBuffer.readData(spkBuf,singleChannelSize);
m_micBuffer.readData(micBuf,singleChannelSize);
memcpy(bytes.data(),micBuf,singleChannelSize);
memcpy(bytes.data() + singleChannelSize,spkBuf,singleChannelSize);
int ret = avcodec_fill_audio_frame(dstFrame,dstFrame->channels,(AVSampleFormat)dstFrame->format,(uint8_t*)bytes.data(),dstSize,1);
if (ret >= 0) {
m_mp3->fillFrame(dstFrame);
m_aac->fillFrame(dstFrame);
} else {
char buf[1024] = { 0 };
av_strerror(ret, buf, sizeof(buf) - 1);
qDebug() << "fill audio error" << ret << buf;
}
// static int i = 0;
// i++;
// if (i > 500) {
// m_aac->destory();
// exit(0);
// }
av_frame_unref(dstFrame);
av_frame_free(&dstFrame);
} else {
QThread::msleep(20);
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。