新版本的WebRTC默認是采用OPUS編碼,OPUS編碼是silk編碼和celt編碼的合成,silk編碼是skype公司開源的一個編碼,
特別適合語音通信,它根據人的聲音做了很多優化,但不是適合傳輸高質量的音樂。celt編碼相反更適合傳輸
高質量的音樂。
OPUS編碼在采樣率很高的情況下,音質還是非常不錯的,以下這個連接地址有很多opus的音頻樣例,大家可以在線聽聽。
http://www.opus-codec.org/examples/
根據閱讀官方文檔知道OPUS編碼支持8000,16000,32000,48000等幾種編碼,支持單聲道,雙聲道,支持6kb-510kb編碼率。如果我們想改變WebRTC的聲音
編碼參數,我們應該如何做呢?
1.首先我會先去看看WebRTC有沒有引出相關的接口,結果查看了PeerConnection,MediaStream,AudioTrack等等相關的類后,根本沒有發現相關接口。
2.根據以往經驗,如果WebRTC沒有提供直接的接口來調,往往還可以通過修改SDP參數和達到我們的目的。我把生成的Offer SDP打印出來后,發現了比較可疑的地
方,
"fmtp:111 minptime=10;useinbandfec=1",這一行是設置opus編碼參數的地方。我再以“
useinbandfec”為關鍵字在WebRTC中代碼中搜索,
在
mediaconstants.cc代碼,找到以下相關代碼
// draft-spittka-payload-rtp-opus-03.txt
const char kCodecParamPTime[] = "ptime";
const char kCodecParamMaxPTime[] = "maxptime";
const char kCodecParamMinPTime[] = "minptime";
const char kCodecParamSPropStereo[] = "sprop-stereo";
const char kCodecParamStereo[] = "stereo";
const char kCodecParamUseInbandFec[] = "useinbandfec";
const char kCodecParamUseDtx[] = "usedtx";
const char kCodecParamMaxAverageBitrate[] = "maxaveragebitrate";
const char kCodecParamMaxPlaybackRate[] = "maxplaybackrate";
3.我依葫蘆畫瓢,在我自己寫的demo代碼中把sdp中的
"fmtp:111 minptime=10;useinbandfec=1" 這一行替換成
"fmtp:111 minptime=10;useinbandfec=1;
maxaveragebitrate =8000
",編譯成功運行后,發現參數生效了,發送一路語音占用的帶寬由於5K變成了3K左右,這就證明參數生效了。
4.在網絡挺別差的情況下,我們可能希望聲音的碼流再變小一點,對音質的要求反而不是哪么高了,音頻采樣率為8000HZ就夠了。要實現這個功能的話把
"fmtp:111 minptime=10;useinbandfec=1" 這一行替換成
"fmtp:111 minptime=10;useinbandfec=1;
maxaveragebitrate =6000;
maxplaybackrate=8000
"就行了
5.如果要傳
音樂,哪我們必需強制OPUS切換到CELT編碼。
要實現這個功能的話把
"fmtp:111 minptime=10;useinbandfec=1" 這一行替換成
"fmtp:111 minptime=10;useinbandfec=1;
maxaveragebitrate =64000;
maxplaybackrate=48000;
stereo=1
"就行了
以下功能在WebRTC56版本中試驗成功,修改SDP的時機在
SetRemoteDescription 之前,把對方傳過來的SDP字符串給替換了,再調用
SetRemoteDescription方法