audio_recorder.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "audio_recorder.h"
  2. #include "capturer/audio/audio_qt_capturer.h"
  3. #include "capturer/audio/wasapi_loopback_capturer.h"
  4. #include "qdebug.h"
  5. #include <algorithm>
  6. #include <mutex>
  7. AudioRecorder::AudioRecorder() {}
  8. AudioRecorder::~AudioRecorder()
  9. {
  10. Close();
  11. }
  12. bool AudioRecorder::Open(const std::vector<AudioCapturer::Type>& deviceTypes,
  13. Encoder<MediaType::AUDIO>::Param& param,
  14. const uint32_t sampleRate,
  15. const uint32_t channels,
  16. const uint32_t bitsPerSample,
  17. const AVSampleFormat format)
  18. {
  19. qDebug() << "AudioRecorder::Open called, deviceTypes size:" << deviceTypes.size();
  20. Close();
  21. Info mixInfo;
  22. mixInfo.mixer = &_mixer;
  23. mixInfo.isRecord = &_isRecord;
  24. mixInfo.streamIndex = &_streamIndex;
  25. // 清空并重新创建音频捕获器
  26. m_audioCapturers.clear();
  27. for (int index = 0; index < deviceTypes.size(); ++index) {
  28. mixInfo.mixIndex = index;
  29. _infos.push_back(mixInfo);
  30. if (deviceTypes[index] == AudioCapturer::Type::Speaker) {
  31. m_audioCapturers.push_back(new WASAPILoopbackCapturer());
  32. } else {
  33. m_audioCapturers.push_back(new WASAPILoopbackCapturer());
  34. }
  35. }
  36. // 初始化每个音频捕获器
  37. for (int index = 0; index < deviceTypes.size(); ++index) {
  38. if (!m_audioCapturers[index]->Init(deviceTypes[index])) {
  39. qDebug() << "Failed to initialize audio capturer" << index;
  40. return false;
  41. }
  42. // 添加音频格式验证
  43. const AudioFormat& format = m_audioCapturers[index]->GetFormat();
  44. qDebug() << "Audio Capturer" << index << "Format:" << "SampleRate:" << format.sampleRate
  45. << "Channels:" << format.channels << "BitsPerSample:" << format.bitsPerSample
  46. << "BlockAlign:" << format.blockAlign
  47. << "AvgBytesPerSec:" << format.avgBytesPerSec;
  48. // 验证格式是否与预期一致
  49. if (format.sampleRate != sampleRate) {
  50. qDebug() << "Warning: Sample rate mismatch. Expected:" << sampleRate
  51. << "Got:" << format.sampleRate;
  52. }
  53. if (format.channels != channels) {
  54. qDebug() << "Warning: Channel count mismatch. Expected:" << channels
  55. << "Got:" << format.channels;
  56. }
  57. __CheckBool(_mixer.AddAudioInput(index,
  58. format.sampleRate,
  59. format.channels,
  60. format.bitsPerSample,
  61. _GetAVSampleFormat(format.bitsPerSample)));
  62. }
  63. __CheckBool(_mixer.AddAudioOutput(sampleRate, channels, bitsPerSample, format));
  64. _param = param;
  65. __CheckBool(_mixer.SetOutFrameSize(1024));
  66. // 启动所有成功初始化的音频捕获器
  67. for (auto capturer : m_audioCapturers) {
  68. capturer->Start();
  69. }
  70. return true;
  71. }
  72. void AudioRecorder::Close()
  73. {
  74. StopRecord();
  75. // 停止并释放所有音频捕获器
  76. for (auto capturer : m_audioCapturers) {
  77. if (capturer) {
  78. capturer->Stop();
  79. delete capturer;
  80. }
  81. }
  82. m_audioCapturers.clear();
  83. _mixer.Close();
  84. _infos.clear();
  85. }
  86. void AudioRecorder::SetVolumeScale(float scale, int mixIndex)
  87. {
  88. auto info = _mixer.GetInputInfo(mixIndex);
  89. if (info != nullptr) {
  90. info->scale = scale;
  91. }
  92. }
  93. bool AudioRecorder::LoadMuxer(AvMuxer& muxer)
  94. {
  95. std::lock_guard<std::mutex> lock(_muxersMtx);
  96. // 检查是否已经加载过这个muxer
  97. for (const auto& info : _muxers) {
  98. if (info.muxer == &muxer) {
  99. return true; // 已经加载过,直接返回成功
  100. }
  101. }
  102. int streamIndex = muxer.AddAudioStream(_param);
  103. __CheckBool(streamIndex != -1);
  104. _muxers.emplace_back(&muxer, streamIndex);
  105. // 为了兼容性,保留原有的_infos逻辑(如果需要的话)
  106. for (auto&& info : _infos) {
  107. if (info.muxer == nullptr) {
  108. info.muxer = &muxer;
  109. break;
  110. }
  111. }
  112. return true;
  113. }
  114. bool AudioRecorder::UnloadMuxer(AvMuxer& muxer)
  115. {
  116. std::lock_guard<std::mutex> lock(_muxersMtx);
  117. auto it = std::find_if(_muxers.begin(), _muxers.end(),
  118. [&muxer](const MuxerInfo& info) {
  119. return info.muxer == &muxer;
  120. });
  121. if (it != _muxers.end()) {
  122. _muxers.erase(it);
  123. // 清理_infos中对应的muxer引用
  124. for (auto&& info : _infos) {
  125. if (info.muxer == &muxer) {
  126. info.muxer = nullptr;
  127. }
  128. }
  129. return true;
  130. }
  131. return false; // 没有找到对应的muxer
  132. }
  133. bool AudioRecorder::StartRecord()
  134. {
  135. _isRecord = true;
  136. m_audioTimer.Start(AUDIO_PULL_INTERVAL_MS, [this] {
  137. this->PullAndProcessAudio();
  138. });
  139. return true;
  140. }
  141. void AudioRecorder::StopRecord()
  142. {
  143. _isRecord = false;
  144. m_audioTimer.Stop();
  145. }
  146. // 新增:主动拉取音频数据的接口
  147. void AudioRecorder::PullAndProcessAudio()
  148. {
  149. for (int index = 0; index < m_audioCapturers.size(); ++index) {
  150. // 每次多次拉取小块数据,提升音频帧写入频率
  151. while (true) {
  152. char buf[1024];
  153. int bytes = m_audioCapturers[index]->readAudioData(buf, sizeof(buf));
  154. // static int debugCounter = 0;
  155. // if (++debugCounter % 100 == 0) { // 每100次打印一次,避免日志过多
  156. // qDebug() << "Capturer" << index << "read" << bytes << "bytes";
  157. // }
  158. if (bytes <= 0) {
  159. break;
  160. }
  161. // 添加调试信息,显示数据大小
  162. auto frame = _mixer.Convert(index, (uint8_t*) buf, bytes);
  163. if (frame && _isRecord) {
  164. int frameSize = _mixer.GetOutFrameSize();
  165. if (_mixer.GetOutFrameSize() != frameSize) {
  166. _mixer.SetOutFrameSize(frameSize);
  167. continue;
  168. }
  169. // 向所有已加载的muxer写入音频数据
  170. {
  171. std::lock_guard<std::mutex> muxerLock(_muxersMtx);
  172. for (const auto& muxerInfo : _muxers) {
  173. muxerInfo.muxer->Write(frame, muxerInfo.streamIndex);
  174. }
  175. }
  176. }
  177. }
  178. }
  179. }
  180. std::string AudioRecorder::GetEncoderNameForMuxer(AvMuxer& muxer)
  181. {
  182. std::lock_guard<std::mutex> lock(_muxersMtx);
  183. auto it = std::find_if(_muxers.begin(), _muxers.end(), [&](const MuxerInfo& info){
  184. return info.muxer == &muxer;
  185. });
  186. if (it == _muxers.end()) return {};
  187. AVCodecContext* ctx = muxer.GetCodecCtx(it->streamIndex);
  188. if (!ctx || !ctx->codec || !ctx->codec->name) return {};
  189. return std::string(ctx->codec->name);
  190. }