在网上找了很久的资料,大部分都是关于使用AuidoDeviceModule实现自定义音频输入的。试了之后发现有问题,客户端收不到任何音轨,Observer中的OnTrack只会存在视频轨
class AudioCaptureModule
: public webrtc::AudioDeviceModule
, public rtc::RefCountInterface
{
// ...
}
auto adm = new rtc::RefCountedObject<AudioCaptureModule>();
auto pc_factory = webrtc::CreatePeerConnectionFactory(
nullptr,
nullptr,
nullptr,
std::move(adm),
webrtc::CreateBuiltinAudioEncoderFactory(),
webrtc::CreateBuiltinAudioDecoderFactory(),
webrtc::CreateBuiltinVideoEncoderFactory(),
webrtc::CreateBuiltinVideoDecoderFactory(),
nullptr,
nullptr);
我也找到了AudioSourceInterface这个类,但是不知道能不能实现,因为好像是很久以前版本(比如M79)的方式,而我现在用的版本是M110(最新的稳定版本),是否有任何最新的稳定版本实现自定义音频输入并使接收远程音轨工作的方法?
class CustomAudioSource : public rtc::RefCountedObject<webrtc::AudioSourceInterface> {
public:
explicit CustomAudioSource(int sample_rate_hz) : sample_rate_hz_(sample_rate_hz) {}
void AddSink(AudioTrackSinkInterface* sink) override {
sinks_.push_back(sink);
}
void RemoveSink(AudioTrackSinkInterface* sink) override {
auto it = std::find(sinks_.begin(), sinks_.end(), sink);
if (it != sinks_.end()) {
sinks_.erase(it);
}
}
void GenerateAudio(int16_t* audio_data, int sample_rate_hz, size_t num_channels, size_t num_samples) {
for (auto sink : sinks_) {
sink->OnData(audio_data, num_samples, sample_rate_hz, num_channels);
}
}
private:
int sample_rate_hz_;
std::vector<AudioTrackSinkInterface*> sinks_;
};
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory =
webrtc::CreatePeerConnectionFactory();
webrtc::PeerConnectionInterface::RTCConfiguration config;
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection =
peer_connection_factory->CreatePeerConnection(config, nullptr, nullptr, nullptr, nullptr);
auto audio_device_module = webrtc::AudioDeviceModule::Create(0, webrtc::AudioDeviceModule::kPlatformDefaultAudio);
auto audio_source = std::make_unique<MyCustomAudioSource2>();
auto audio_track = peer_connection_factory->CreateAudioTrack("audio_track", audio_device_module->CreateAudioSource(std::move(audio_source)));
peer_connection->AddTrack(audio_track, {"stream"});
ADM
的实现是正确的,这个实现参考了chromium中的WebrtcAudioModule
。
//
// audio_capture_module.h
// rtc
//
// Created by Mr.Panda on 2023/2/22.
//
#ifndef audio_capture_module_h
#define audio_capture_module_h
#pragma once
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "api/peer_connection_interface.h"
class AudioCaptureModule
: public webrtc::AudioDeviceModule
{
public:
static rtc::scoped_refptr<AudioCaptureModule> Create();
int32_t ActiveAudioLayer(AudioLayer* audioLayer) const;
int32_t RegisterAudioCallback(webrtc::AudioTransport* audio_callback);
// Only supported on iOS.
#ifdef WEBRTC_IOS
int GetPlayoutAudioParameters(webrtc::AudioParameters* params) const;
int GetRecordAudioParameters(webrtc::AudioParameters* params) const;
#endif // WEBRTC_IOS
// Main initialization and termination
int32_t Init();
int32_t Terminate();
bool Initialized() const;
// Device enumeration
int16_t PlayoutDevices();
int16_t RecordingDevices();
int32_t PlayoutDeviceName(uint16_t index,
char name[webrtc::kAdmMaxDeviceNameSize],
char guid[webrtc::kAdmMaxGuidSize]);
int32_t RecordingDeviceName(uint16_t index,
char name[webrtc::kAdmMaxDeviceNameSize],
char guid[webrtc::kAdmMaxGuidSize]);
// Device selection
int32_t SetPlayoutDevice(uint16_t index);
int32_t SetPlayoutDevice(WindowsDeviceType device);
int32_t SetRecordingDevice(uint16_t index);
int32_t SetRecordingDevice(WindowsDeviceType device);
// Audio transport initialization
int32_t PlayoutIsAvailable(bool* available);
int32_t InitPlayout();
bool PlayoutIsInitialized() const;
int32_t RecordingIsAvailable(bool* available);
int32_t InitRecording();
bool RecordingIsInitialized() const;
// Audio transport control
int32_t StartPlayout();
int32_t StopPlayout();
// True when audio is being pulled by the instance.
bool Playing() const;
int32_t StartRecording();
int32_t StopRecording();
bool Recording() const;
// Audio mixer initialization
int32_t InitSpeaker();
bool SpeakerIsInitialized() const;
int32_t InitMicrophone();
bool MicrophoneIsInitialized() const;
// Speaker volume controls
int32_t SpeakerVolumeIsAvailable(bool* available);
int32_t SetSpeakerVolume(uint32_t volume);
int32_t SpeakerVolume(uint32_t* volume) const;
int32_t MaxSpeakerVolume(uint32_t* maxVolume) const;
int32_t MinSpeakerVolume(uint32_t* minVolume) const;
// Microphone volume controls
int32_t MicrophoneVolumeIsAvailable(bool* available);
int32_t SetMicrophoneVolume(uint32_t volume);
int32_t MicrophoneVolume(uint32_t* volume) const;
int32_t MaxMicrophoneVolume(uint32_t* max_volume) const;
int32_t MinMicrophoneVolume(uint32_t* min_volume) const;
// Speaker mute control
int32_t SpeakerMuteIsAvailable(bool* available);
int32_t SetSpeakerMute(bool enable);
int32_t SpeakerMute(bool* enabled) const;
// Microphone mute control
int32_t MicrophoneMuteIsAvailable(bool* available);
int32_t SetMicrophoneMute(bool enable);
int32_t MicrophoneMute(bool* enabled) const;
// Stereo support
int32_t StereoPlayoutIsAvailable(bool* available) const;
int32_t SetStereoPlayout(bool enable);
int32_t StereoPlayout(bool* enabled) const;
int32_t StereoRecordingIsAvailable(bool* available) const;
int32_t SetStereoRecording(bool enable);
int32_t StereoRecording(bool* enabled) const;
// Playout delay
int32_t PlayoutDelay(uint16_t* delay_ms) const;
bool BuiltInAECIsAvailable() const;
bool BuiltInAGCIsAvailable() const;
bool BuiltInNSIsAvailable() const;
// Enables the built-in audio effects. Only supported on Android.
int32_t EnableBuiltInAEC(bool enable);
int32_t EnableBuiltInAGC(bool enable);
int32_t EnableBuiltInNS(bool enable);
private:
bool Initialize();
webrtc::AudioTransport* _audio_transport = NULL;
bool _initialized;
bool _playing;
};
#endif /* audio_capture_module_h */
//
// audio_capture_module.cpp
// rtc
//
// Created by Mr.Panda on 2023/2/22.
//
#include "audio_capture_module.h"
rtc::scoped_refptr<AudioCaptureModule> AudioCaptureModule::Create()
{
return rtc::make_ref_counted<AudioCaptureModule>();
}
int32_t AudioCaptureModule::ActiveAudioLayer(AudioLayer* audio_layer) const
{
return -1;
}
int32_t AudioCaptureModule::RegisterAudioCallback(
webrtc::AudioTransport* audio_transport)
{
_audio_transport = audio_transport;
return 0;
}
int32_t AudioCaptureModule::Init()
{
_initialized = true;
return 0;
}
int32_t AudioCaptureModule::Terminate()
{
_initialized = false;
return 0;
}
bool AudioCaptureModule::Initialized() const
{
return _initialized;
}
int16_t AudioCaptureModule::PlayoutDevices()
{
return 0;
}
int16_t AudioCaptureModule::RecordingDevices()
{
return 0;
}
int32_t AudioCaptureModule::PlayoutDeviceName(
uint16_t index,
char name[webrtc::kAdmMaxDeviceNameSize],
char guid[webrtc::kAdmMaxGuidSize])
{
return 0;
}
int32_t AudioCaptureModule::RecordingDeviceName(
uint16_t index,
char name[webrtc::kAdmMaxDeviceNameSize],
char guid[webrtc::kAdmMaxGuidSize])
{
return 0;
}
int32_t AudioCaptureModule::SetPlayoutDevice(uint16_t index)
{
return 0;
}
int32_t AudioCaptureModule::SetPlayoutDevice(WindowsDeviceType device)
{
return 0;
}
int32_t AudioCaptureModule::SetRecordingDevice(uint16_t index)
{
return 0;
}
int32_t AudioCaptureModule::SetRecordingDevice(WindowsDeviceType device)
{
return 0;
}
int32_t AudioCaptureModule::PlayoutIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::InitPlayout()
{
return 0;
}
bool AudioCaptureModule::PlayoutIsInitialized() const
{
return _initialized;
}
int32_t AudioCaptureModule::RecordingIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::InitRecording()
{
return 0;
}
bool AudioCaptureModule::RecordingIsInitialized() const
{
return false;
}
int32_t AudioCaptureModule::StartPlayout()
{
_playing = true;
return 0;
}
int32_t AudioCaptureModule::StopPlayout()
{
_playing = false;
return 0;
}
bool AudioCaptureModule::Playing() const
{
return _playing;
}
int32_t AudioCaptureModule::StartRecording()
{
return 0;
}
int32_t AudioCaptureModule::StopRecording()
{
return 0;
}
bool AudioCaptureModule::Recording() const
{
return false;
}
int32_t AudioCaptureModule::InitSpeaker()
{
return 0;
}
bool AudioCaptureModule::SpeakerIsInitialized() const
{
return false;
}
int32_t AudioCaptureModule::InitMicrophone()
{
return 0;
}
bool AudioCaptureModule::MicrophoneIsInitialized() const
{
return false;
}
int32_t AudioCaptureModule::SpeakerVolumeIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::SetSpeakerVolume(uint32_t volume)
{
return -1;
}
int32_t AudioCaptureModule::SpeakerVolume(uint32_t* volume) const
{
return -1;
}
int32_t AudioCaptureModule::MaxSpeakerVolume(uint32_t* max_volume) const
{
return -1;
}
int32_t AudioCaptureModule::MinSpeakerVolume(uint32_t* min_volume) const
{
return -1;
}
int32_t AudioCaptureModule::MicrophoneVolumeIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::SetMicrophoneVolume(uint32_t volume)
{
return -1;
}
int32_t AudioCaptureModule::MicrophoneVolume(uint32_t* volume) const
{
return -1;
}
int32_t AudioCaptureModule::MaxMicrophoneVolume(uint32_t* max_volume) const
{
return -1;
}
int32_t AudioCaptureModule::MinMicrophoneVolume(uint32_t* min_volume) const
{
return -1;
}
int32_t AudioCaptureModule::SpeakerMuteIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::SetSpeakerMute(bool enable)
{
return -1;
}
int32_t AudioCaptureModule::SpeakerMute(bool* enabled) const
{
return -1;
}
int32_t AudioCaptureModule::MicrophoneMuteIsAvailable(bool* available)
{
return -1;
}
int32_t AudioCaptureModule::SetMicrophoneMute(bool enable)
{
return -1;
}
int32_t AudioCaptureModule::MicrophoneMute(bool* enabled) const
{
return -1;
}
int32_t AudioCaptureModule::StereoPlayoutIsAvailable(bool* available) const
{
*available = true;
return 0;
}
int32_t AudioCaptureModule::SetStereoPlayout(bool enable)
{
return 0;
}
int32_t AudioCaptureModule::StereoPlayout(bool* enabled) const
{
return -1;
}
int32_t AudioCaptureModule::StereoRecordingIsAvailable(bool* available) const
{
*available = false;
return 0;
}
int32_t AudioCaptureModule::SetStereoRecording(bool enable)
{
return 0;
}
int32_t AudioCaptureModule::StereoRecording(bool* enabled) const
{
return -1;
}
int32_t AudioCaptureModule::PlayoutDelay(uint16_t* delay_ms) const
{
*delay_ms = 0;
return 0;
}
bool AudioCaptureModule::BuiltInAECIsAvailable() const
{
return false;
}
bool AudioCaptureModule::BuiltInAGCIsAvailable() const
{
return false;
}
bool AudioCaptureModule::BuiltInNSIsAvailable() const
{
return false;
}
int32_t AudioCaptureModule::EnableBuiltInAEC(bool enable)
{
return -1;
}
int32_t AudioCaptureModule::EnableBuiltInAGC(bool enable)
{
return -1;
}
int32_t AudioCaptureModule::EnableBuiltInNS(bool enable)
{
return -1;
}
#if defined(WEBRTC_IOS)
int AudioCaptureModule::GetPlayoutAudioParameters(
webrtc::AudioParameters* params) const
{
return -1;
}
int AudioCaptureModule::GetRecordAudioParameters(
webrtc::AudioParameters* params) const
{
return -1;
}
#endif // WEBRTC_IOS