【问题标题】:WebRTC Native, AudioTrackSinkInterface added to track, but OnData is never calledWebRTC Native,AudioTrackSinkInterface 添加到轨道,但 OnData 从未被调用
【发布时间】:2018-02-09 09:18:40
【问题描述】:

我一直在开发一种产品,它使用 WebRTC 在浏览器和本地客户端之间交换音频,本地端是用 C++ 实现的。目前我已经构建了 webRtc 的最新稳定版本(分支:branch-heads/65)。

到目前为止,我能够让连接对等方进行连接,在浏览器上接收并正确呈现音频。然而,尽管 chrome 调试工具提示数据正在从浏览器发送到本机客户端,但本机客户端似乎从未通过其音轨接收器接收任何数据。

下面的代码肯定被调用了,并且按预期添加了频道。

void Conductor::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream)
{

    webrtc::AudioTrackVector atracks = stream->GetAudioTracks();
    for (auto track : atracks)
    {
        remote_audio.reset(new Native::AudioRenderer(this, track));
        track->set_enabled(true);
    }
}

// Audio renderer derived from webrtc::AudioTrackSinkInterface
// In the audio renderer constructor, AddSink is called on the track.
AudioRenderer::AudioRenderer(AudioCallback* callback, webrtc::AudioTrackInterface* track) : track_(track), callback_(callback)
{
// Can confirm this point is reached.
    track_->AddSink(this);
}

AudioRenderer::~AudioRenderer()
{
    track_->RemoveSink(this);
}

void AudioRenderer::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels,
        size_t number_of_frames)
{
// This is never hit, despite the connection starting and streams being added.
    if (callback_ != nullptr)
    {
        callback_->OnAudioData(audio_data, bits_per_sample, sample_rate, number_of_channels, number_of_frames);
    }
}

我还可以确认,这两个优惠都包含接收音频的选项:

浏览器客户端报价:

// Create offer
var offerOptions = {
    offerToReceiveAudio: 1,
    offerToReceiveVideo: 0
};
pc.createOffer(offerOptions)
    .then(offerCreated);

本地客户回答:

webrtc::PeerConnectionInterface::RTCOfferAnswerOptions o;
{
    o.voice_activity_detection = false;
    o.offer_to_receive_audio = webrtc::PeerConnectionInterface::RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
    o.offer_to_receive_video = webrtc::PeerConnectionInterface::RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
}
peer_connection_->CreateAnswer(this, o);

我无法找到有关此问题的任何最新信息,框架的一个常见用例似乎是能够在客户端应用程序中使用接收到的音频。关于我在收听入站音频时可能出错的地方有什么想法,或者我可以采取哪些策略来调查为什么这不起作用?

非常感谢

【问题讨论】:

  • 有同样的问题。令人沮丧的是,没有人能回答为什么 OnData 从未被解雇,但感谢您的解决方法并会尝试一下。谢谢!

标签: c++ webrtc


【解决方案1】:

我设法找到了一种从 WebRTC 获取音频数据的替代方法,可以解决这个问题。

  1. 实现自定义webrtc::AudioDeviceModule 实现。查看 webrtc 源代码,了解如何做到这一点。
  2. RegisterAudioCallback 方法中捕获音频传输,该方法在建立呼叫时调用。

片段:

int32_t AudioDevice::RegisterAudioCallback(webrtc::AudioTransport * transport)
{
    transport_ = transport;
    return 0;
}
  1. 向设备类添加自定义方法,使用NeedMorePlayData 方法从音频传输中提取音频。 (注意:这似乎适用于 ntp_time_ms 作为 0 传入,似乎不是必需的)。

片段:

int32_t AudioDevice::NeedMorePlayData(
    const size_t nSamples,
    const size_t nBytesPerSample,
    const size_t nChannels,
    const uint32_t samplesPerSec,
    void* audioSamples,
    size_t& nSamplesOut,
    int64_t* elapsed_time_ms,
    int64_t* ntp_time_ms) const
    {
        return transport_->NeedMorePlayData(nSamples,
            nBytesPerSample,
            nChannels,
            samplesPerSec,
            audioSamples,
            nSamplesOut,
            elapsed_time_ms,
            ntp_time_ms);
    }

【讨论】:

  • NeedMorePlayData 何时调用以及由谁调用?
  • 关于如何将自定义 AudioDeviceModule 挂钩到 WebRTC 的任何指示?我发现有人说我们可以通过PeerConnectionFactory 连接,但我还没有找到任何方法。你能帮忙吗?
  • 您可以使用CreatePeerConnectionFactory 并将您的自定义AudioDeviceModule 作为参数传递
猜你喜欢
  • 2022-11-02
  • 2018-10-12
  • 2017-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2019-12-06
  • 2015-01-05
相关资源
最近更新 更多