| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include "audio_recorder.h"
- #include "capturer/audio/audio_qt_capturer.h"
- #include "capturer/audio/wasapi_loopback_capturer.h"
- #include "qdebug.h"
- AudioRecorder::AudioRecorder() {}
- AudioRecorder::~AudioRecorder()
- {
- Close();
- }
- bool AudioRecorder::Open(const std::vector<AudioCapturer::Type>& deviceTypes,
- Encoder<MediaType::AUDIO>::Param& param,
- const uint32_t sampleRate,
- const uint32_t channels,
- const uint32_t bitsPerSample,
- const AVSampleFormat format)
- {
- qDebug() << "AudioRecorder::Open called, deviceTypes size:" << deviceTypes.size();
- Close();
- Info mixInfo;
- mixInfo.mixer = &_mixer;
- mixInfo.isRecord = &_isRecord;
- mixInfo.streamIndex = &_streamIndex;
- // 清空并重新创建音频捕获器
- m_audioCapturers.clear();
- for (int index = 0; index < deviceTypes.size(); ++index) {
- mixInfo.mixIndex = index;
- _infos.push_back(mixInfo);
- if (deviceTypes[index] == AudioCapturer::Type::Speaker) {
- m_audioCapturers.push_back(new WASAPILoopbackCapturer());
- } else {
- m_audioCapturers.push_back(new QtAudioCapturer());
- }
- }
- // 初始化每个音频捕获器
- for (int index = 0; index < deviceTypes.size(); ++index) {
- if (!m_audioCapturers[index]->Init(deviceTypes[index])) {
- qDebug() << "Failed to initialize audio capturer" << index;
- return false;
- }
-
- // 添加音频格式验证
- const AudioFormat& format = m_audioCapturers[index]->GetFormat();
- qDebug() << "Audio Capturer" << index << "Format:" << "SampleRate:" << format.sampleRate
- << "Channels:" << format.channels << "BitsPerSample:" << format.bitsPerSample
- << "BlockAlign:" << format.blockAlign
- << "AvgBytesPerSec:" << format.avgBytesPerSec;
- // 验证格式是否与预期一致
- if (format.sampleRate != sampleRate) {
- qDebug() << "Warning: Sample rate mismatch. Expected:" << sampleRate
- << "Got:" << format.sampleRate;
- }
- if (format.channels != channels) {
- qDebug() << "Warning: Channel count mismatch. Expected:" << channels
- << "Got:" << format.channels;
- }
-
- __CheckBool(_mixer.AddAudioInput(index,
- format.sampleRate,
- format.channels,
- format.bitsPerSample,
- _GetAVSampleFormat(format.bitsPerSample)));
- }
- __CheckBool(_mixer.AddAudioOutput(sampleRate, channels, bitsPerSample, format));
- _param = param;
- __CheckBool(_mixer.SetOutFrameSize(1024));
- // 启动所有成功初始化的音频捕获器
- for (auto capturer : m_audioCapturers) {
- capturer->Start();
- }
- return true;
- }
- void AudioRecorder::Close()
- {
- StopRecord();
- // 停止并释放所有音频捕获器
- for (auto capturer : m_audioCapturers) {
- if (capturer) {
- capturer->Stop();
- delete capturer;
- }
- }
- m_audioCapturers.clear();
- _mixer.Close();
- _infos.clear();
- }
- void AudioRecorder::SetVolumeScale(float scale, int mixIndex)
- {
- auto info = _mixer.GetInputInfo(mixIndex);
- if (info != nullptr) {
- info->scale = scale;
- }
- }
- bool AudioRecorder::LoadMuxer(AvMuxer& muxer)
- {
- for (auto&& info : _infos) {
- info.muxer = &muxer;
- }
- __CheckBool((_streamIndex = muxer.AddAudioStream(_param)) != -1);
- return true;
- }
- bool AudioRecorder::StartRecord()
- {
- _isRecord = true;
- m_audioTimer.Start(AUDIO_PULL_INTERVAL_MS, [this] {
- this->PullAndProcessAudio();
- });
- return true;
- }
- void AudioRecorder::StopRecord()
- {
- _isRecord = false;
- m_audioTimer.Stop();
- }
- // 新增:主动拉取音频数据的接口
- void AudioRecorder::PullAndProcessAudio()
- {
- for (int index = 0; index < m_audioCapturers.size(); ++index) {
- // 每次多次拉取小块数据,提升音频帧写入频率
- while (true) {
- char buf[1024];
- int bytes = m_audioCapturers[index]->readAudioData(buf, sizeof(buf));
- // static int debugCounter = 0;
- // if (++debugCounter % 100 == 0) { // 每100次打印一次,避免日志过多
- // qDebug() << "Capturer" << index << "read" << bytes << "bytes";
- // }
- if (bytes <= 0) {
- break;
- }
- // 添加调试信息,显示数据大小
- auto frame = _mixer.Convert(index, (uint8_t*) buf, bytes);
- if (frame && _isRecord && _streamIndex != -1) {
- int frameSize = _mixer.GetOutFrameSize();
- if (_mixer.GetOutFrameSize() != frameSize) {
- _mixer.SetOutFrameSize(frameSize);
- continue;
- }
- _infos[index].muxer->Write(frame, _streamIndex);
- }
- }
- }
- }
|