#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& deviceTypes, Encoder::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); } } } }