当建立连接并准备就绪后,我的webrtc::PeerConnectionObserver
实现会收到对
void OnAddStream(webrtc::MediaStreamInterface* stream);
我将webrtc::AudioTrackInterface
拉出webrtc::MediaStreamInterface
。
我从中得到一个有效的(非空)指针,称之为track
webrtc::AudioTrackInterface* track;
然后我继续致电track->AddSink(sink)
,其中sink
是我继承自webrtc::AudioTrackSinkInterface
的类的实例并实现
virtual void OnData(const void* audio_data,
int bits_per_sample,
int sample_rate,
int number_of_channels,
int number_of_frames) = 0;
此时我希望通过解码后的音频数据接收定期回调到我的具体课程,就像我在视频数据可用时通过webrtc::VideoRendererInterface
接到cricket::VideoFrame*
的电话一样,但是我做了不
我做错了什么?
答案 0 :(得分:4)
除了使用尚未实现的接口之外,您没有做错任何事情。好吧,实现了接口,但实际调用OnData()
方法后面没有代码!
相关界面位于WebRTC的mediastreaminterface.h中。文件中有一个注释,暗示AddSink()
和OnData()
的未实现状态:
// Get a pointer to the audio renderer of this AudioTrack.
// The pointer is valid for the lifetime of this AudioTrack.
// TODO(xians): Remove the following interface after Chrome switches to
// AddSink() and RemoveSink() interfaces.
virtual cricket::AudioRenderer* GetRenderer() { return NULL; }
不幸的是,这里引用的AudioRenderer
类看起来不太容易使用。它在Chromium的audio_renderer.h中定义,并使用各种Chromium内部类型。如果你弄清楚如何处理它,请告诉我,因为我正试图自己解决同样的问题。
我确实注意到WebRTC的mediastreamhandler.cc中的某些代码使用OnData()
的方式与您和我尝试的方式相同。有一个LocalAudioTrackHandler
构造函数在音轨上调用track->AddSink()
并向其传递LocalAudioSinkAdapter
类的实例。此类有一个OnData()
方法,可以转发到sink_->OnData()
。 track->AddSink()
调用确实已执行,但OnData()
方法永远不会被调用!
我认为这个AddSink()
/ OnData()
代码是为了预期Chromium在内部实现这些调用而添加的,因此当他们切换时会开始使用此代码而不是AudioRenderer
代码。这样就无需更新两个代码库完全同步。
所以我建议的是等到调用OnData()
的代码在Chromium中实现。