这里说下C++原生SDK开发过程遇到一个比较大的坑:在只有publish时,对方(WEB)拉流是可以听到我方的声音的,但是增加了subscribe对方的流后,对方就听不到我方的声音了,这个问题查了比较久,专门写出来供大家参考避坑。
问题产生的原因在于:windows音频部分默认内部开启了AEC功能,但必须要求先初始化Playout再初始化Record.由于目前推流是不需要初始化Playout,导致的Record无法初始化通过。
解决的方法:目前采用的方式是"篡改" sdp 把Playout初始化
void RtcConnection::onJanusPeerSdp(std::string sdptype, std::string sdp)
{
webrtc::SdpParseError error;
rtc::Optional<SdpType> type_maybe = webrtc::SdpTypeFromString(sdptype);
if (!type_maybe) {
RTC_LOG(LS_ERROR) << "Unknown SDP type: " << sdptype;
return;
}
SdpType type = *type_maybe;
if (is_myself()) {
//TODO windows音频部分默认内部开启了AEC功能,但必须要求先初始化Playout再初始化Record.由于目前推流是不需要初始化Playout
//导致的Record无法初始化通过,目前采用的方式是"篡改" sdp 把Playout初始化。
blog(emLOG_INFO," %s is_myself() ==true ",__func__);
webrtc::JsepSessionDescription jdesc(type);
webrtc::SdpDeserialize(sdp, &jdesc, NULL);
auto audio_desc = (jdesc.description())->GetContentByName("audio")->media_description();
audio_desc->as_audio()->set_direction(webrtc::RtpTransceiverDirection::kSendRecv);
cricket::StreamParams stream_;
stream_.add_ssrc(0x12345678);
stream_.cname = rtc::CreateRandomString(8);
std::vector<std::string> vec_;
vec_.push_back("local_fake_audio");
stream_.set_stream_ids(vec_);
stream_.id = "local_fake_stream";
audio_desc->as_audio()->AddStream(stream_);
jdesc.ToString(&sdp);
}
if (!InitializePeerConnection())
{
///onError callback
return;
}
std::unique_ptr<webrtc::SessionDescriptionInterface> session_description = webrtc::CreateSessionDescription(type, sdp, &error);
if (!session_description) {
blog(emLOG_WARNING, "%s Can't parse received session description message. SdpParseError was: %s",__func__ ,error.description.c_str() );
return;
}
peer_connection_->SetRemoteDescription(DummySetSessionDescriptionObserver::Create(), session_description.release());
if (type == SdpType::kOffer) {
peer_connection_->CreateAnswer(this, NULL);
}
}
到这篇文章,webrtc的基础入门Janus原生c++ SDK开发就结束了,后面是如何一步步改造,把整个系统的优化改进,做成一个可实用的实时会议系统。