audio_recorder.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. if (!_mixer.AddAudioInput(index,
  58. format.sampleRate,
  59. format.channels,
  60. format.bitsPerSample,
  61. _GetAVSampleFormat(format.bitsPerSample))) {
  62. qDebug() << "AddAudioInput failed for index" << index;
  63. return false;
  64. }
  65. }
  66. if (!_mixer.AddAudioOutput(sampleRate, channels, bitsPerSample, format)) {
  67. qDebug() << "AddAudioOutput failed";
  68. return false;
  69. }
  70. _param = param;
  71. if (!_mixer.SetOutFrameSize(1024)) {
  72. qDebug() << "SetOutFrameSize failed";
  73. return false;
  74. }
  75. // 启动所有成功初始化的音频捕获器
  76. for (auto capturer : m_audioCapturers) {
  77. capturer->Start();
  78. }
  79. return true;
  80. }
  81. void AudioRecorder::Close()
  82. {
  83. StopRecord();
  84. // 停止并释放所有音频捕获器
  85. for (auto capturer : m_audioCapturers) {
  86. if (capturer) {
  87. capturer->Stop();
  88. delete capturer;
  89. }
  90. }
  91. m_audioCapturers.clear();
  92. _mixer.Close();
  93. _infos.clear();
  94. }
  95. void AudioRecorder::SetVolumeScale(float scale, int mixIndex)
  96. {
  97. auto info = _mixer.GetInputInfo(mixIndex);
  98. if (info != nullptr) {
  99. info->scale = scale;
  100. }
  101. }
  102. bool AudioRecorder::LoadMuxer(AvMuxer& muxer)
  103. {
  104. std::lock_guard<std::mutex> lock(_muxersMtx);
  105. // 检查是否已经加载过这个muxer
  106. for (const auto& info : _muxers) {
  107. if (info.muxer == &muxer) {
  108. return true; // 已经加载过,直接返回成功
  109. }
  110. }
  111. int streamIndex = muxer.AddAudioStream(_param);
  112. if (streamIndex == -1) {
  113. qDebug() << "AddAudioStream failed";
  114. return false;
  115. }
  116. _muxers.emplace_back(&muxer, streamIndex);
  117. // 为了兼容性,保留原有的_infos逻辑(如果需要的话)
  118. for (auto&& info : _infos) {
  119. if (info.muxer == nullptr) {
  120. info.muxer = &muxer;
  121. break;
  122. }
  123. }
  124. return true;
  125. }
  126. bool AudioRecorder::UnloadMuxer(AvMuxer& muxer)
  127. {
  128. std::lock_guard<std::mutex> lock(_muxersMtx);
  129. auto it = std::find_if(_muxers.begin(), _muxers.end(),
  130. [&muxer](const MuxerInfo& info) {
  131. return info.muxer == &muxer;
  132. });
  133. if (it != _muxers.end()) {
  134. _muxers.erase(it);
  135. // 清理_infos中对应的muxer引用
  136. for (auto&& info : _infos) {
  137. if (info.muxer == &muxer) {
  138. info.muxer = nullptr;
  139. }
  140. }
  141. return true;
  142. }
  143. return false; // 没有找到对应的muxer
  144. }
  145. bool AudioRecorder::StartRecord()
  146. {
  147. _isRecord = true;
  148. m_audioTimer.Start(AUDIO_PULL_INTERVAL_MS, [this] {
  149. this->PullAndProcessAudio();
  150. });
  151. return true;
  152. }
  153. void AudioRecorder::StopRecord()
  154. {
  155. _isRecord = false;
  156. m_audioTimer.Stop();
  157. }
  158. // 新增:主动拉取音频数据的接口
  159. void AudioRecorder::PullAndProcessAudio()
  160. {
  161. for (int index = 0; index < m_audioCapturers.size(); ++index) {
  162. // 每次多次拉取小块数据,提升音频帧写入频率
  163. while (true) {
  164. char buf[1024];
  165. int bytes = m_audioCapturers[index]->readAudioData(buf, sizeof(buf));
  166. // static int debugCounter = 0;
  167. // if (++debugCounter % 100 == 0) { // 每100次打印一次,避免日志过多
  168. // qDebug() << "Capturer" << index << "read" << bytes << "bytes";
  169. // }
  170. if (bytes <= 0) {
  171. break;
  172. }
  173. // 添加调试信息,显示数据大小
  174. auto frame = _mixer.Convert(index, (uint8_t*) buf, bytes);
  175. if (frame && _isRecord) {
  176. int frameSize = _mixer.GetOutFrameSize();
  177. if (_mixer.GetOutFrameSize() != frameSize) {
  178. _mixer.SetOutFrameSize(frameSize);
  179. continue;
  180. }
  181. // 向所有已加载的muxer写入音频数据
  182. {
  183. std::lock_guard<std::mutex> muxerLock(_muxersMtx);
  184. for (const auto& muxerInfo : _muxers) {
  185. muxerInfo.muxer->Write(frame, muxerInfo.streamIndex);
  186. }
  187. }
  188. }
  189. }
  190. }
  191. }
  192. std::string AudioRecorder::GetEncoderNameForMuxer(AvMuxer& muxer)
  193. {
  194. std::lock_guard<std::mutex> lock(_muxersMtx);
  195. auto it = std::find_if(_muxers.begin(), _muxers.end(), [&](const MuxerInfo& info){
  196. return info.muxer == &muxer;
  197. });
  198. if (it == _muxers.end()) return {};
  199. AVCodecContext* ctx = muxer.GetCodecCtx(it->streamIndex);
  200. if (!ctx || !ctx->codec || !ctx->codec->name) return {};
  201. return std::string(ctx->codec->name);
  202. }