您當(dāng)前的位置是:  首頁(yè) > 新聞 > 專家觀點(diǎn) >
 首頁(yè) > 新聞 > 專家觀點(diǎn) >

HTML5進(jìn)階手冊(cè):音視頻功能開(kāi)發(fā)探索

2016-11-28 10:17:36   作者:容聯(lián)云通訊 張文博   來(lái)源:CTI論壇   評(píng)論:0  點(diǎn)擊:


  自從 2014 年 HTML5 標(biāo)準(zhǔn)正式發(fā)布以后,各項(xiàng)功能如雨后春筍般出現(xiàn),新的 標(biāo)準(zhǔn)也提供了很多新的特性,諸如三維圖形特效、多媒體特性等。得益于 H5 新 特性,網(wǎng)頁(yè)也可以調(diào)用攝像頭以及麥克風(fēng)等媒體輸入設(shè)備了,于是 IM Plus 的第 一版 H5 SDK 就推出了相應(yīng)的功能。對(duì)客戶而言,這無(wú)異于又拓展了一個(gè)很大的 平臺(tái),用電腦只需要打開(kāi)瀏覽器就可以使用視頻通話的功能,甚至借助公司的平 臺(tái)可以實(shí)現(xiàn)打電話的功能,卻什么都不需要下載,甚至一個(gè)插件都不需要安裝, 提供了一個(gè)非常便利的平臺(tái)去拓展自己的業(yè)務(wù),這無(wú)疑對(duì)用戶來(lái)講是極大的便捷。 H5 音視頻功能經(jīng)過(guò) 1 年的發(fā)展,已經(jīng)逐步成為語(yǔ)音及 DID 平臺(tái)客戶開(kāi)發(fā)特定場(chǎng) 景應(yīng)用的首選方案。而實(shí)現(xiàn)這一功能的,正是 H5 新特性之一的 WebRTC。
  WebRTC 是一個(gè)支持網(wǎng)頁(yè)瀏覽器進(jìn)行實(shí)時(shí)語(yǔ)音對(duì)話或視頻對(duì)話的技術(shù),谷歌 2010 年以 6820 萬(wàn)美元收購(gòu) Global IP Solutions 公司而獲得的一項(xiàng)技術(shù)。2011 年 5 月開(kāi)放了工程的源代碼,在行業(yè)內(nèi)得到了廣泛的支持和應(yīng)用,成為下一代視頻通話的標(biāo)準(zhǔn),該項(xiàng)目的最終目的主要是讓 Web 開(kāi)發(fā)者能夠基于瀏覽器 (Chrome\FireFox\…)輕易快捷開(kāi)發(fā)出豐富的實(shí)時(shí)多媒體應(yīng)用,而無(wú)需下載安裝 任何插件,Web 開(kāi)發(fā)者也無(wú)需關(guān) s 注多媒體的數(shù)字信號(hào)處理過(guò)程,只需編寫(xiě)簡(jiǎn)單 的 Javascript 程序即可實(shí)現(xiàn),W3C 等組織正在制定 Javascript 標(biāo)準(zhǔn) API,目前是 WebRTC 1.0 版本,Draft 狀態(tài);另外,WebRTC 還希望能夠建立一個(gè)多互聯(lián)網(wǎng)瀏 覽器間健壯的實(shí)時(shí)通信的平臺(tái),形成開(kāi)發(fā)者與瀏覽器廠商良好的生態(tài)環(huán)境。同時(shí), Google 也希望和致力于讓 WebRTC 的技術(shù)成為 HTML5 標(biāo)準(zhǔn)之一。
  介紹完 webRTC 的歷史,那么我們?nèi)绾卧?HTML 頁(yè)面中建立一個(gè) RTC 應(yīng)用呢?
  首先,向?yàn)g覽器申請(qǐng)調(diào)用瀏覽器的權(quán)限,使用navigator.webkitGetUserMedia()或 MediaDevices.getUserMedia()。比較尷尬的一點(diǎn)是,javascript 接口由 Mozilla 社區(qū)開(kāi)發(fā)的,所以火狐瀏覽器跟進(jìn)的比較快,而谷歌還在沿用上一套接口,前者 在 Mozilla 社區(qū)已經(jīng)標(biāo)記為不建議使用的接口,不過(guò)鑒于目前 webkit 內(nèi)核的瀏覽 器比較多,所以本文以前者的接口為主,并且 webkit 內(nèi)核版本要在 36 以上,但 在 webkit47 以上的版本調(diào)用媒體設(shè)備的時(shí)候必須用 https 協(xié)議,用來(lái)保證安全, 而 firefox 要求相對(duì)沒(méi)有那么嚴(yán)格,由于 firefox 瀏覽器在國(guó)內(nèi)是不需要翻墻更新 的,所以只需要更新到最新版本,那么支持就沒(méi)有什么問(wèn)題。
  navigator.webkitGetUserMedia()方法需要四個(gè)參數(shù),第一個(gè)參數(shù)直接傳入 navigator 對(duì)象,第二個(gè)參數(shù)為調(diào)用的硬件{audio: true,video:true},如果不需要調(diào)用 攝像頭,則 video 為 false,不寫(xiě)則默認(rèn)為 false。第三第四個(gè)為正確和錯(cuò)誤回調(diào)函數(shù)。
  如: getUserMedia.call(navigator, {audio: true,video:true}, resolve, reject);
  第二個(gè)參數(shù)為成功回調(diào)函數(shù),第三個(gè)參數(shù)為失敗回調(diào)函數(shù)。失敗回調(diào)會(huì)傳入 一個(gè)參數(shù),為失敗信息。
  成功回調(diào)函數(shù)會(huì)將一個(gè)媒體流作為參數(shù)傳入進(jìn)來(lái),此時(shí)創(chuàng)建一個(gè) RTCPeerConnection 來(lái)存放流傳輸?shù)耐ǖ溃瑒?chuàng)建 RTCPeerConnection 時(shí)需要兩個(gè)參數(shù),一個(gè)是 iceServer,即視頻流傳輸?shù)刂,若沒(méi)有特殊的代理則設(shè)置為空就可以。 另一個(gè)為可選項(xiàng)數(shù)組,這里只需要一個(gè) DtlsSrtpKeyAgreement:true,將這兩個(gè)參 數(shù)傳入到 RTCPeerConnection 中,即可得到一個(gè) peerConnection 對(duì)象
  var pc = new peerConnection({"iceServers": []}, {optional:[{DtlsSrtpKeyAgreemen t:true}]});
  然后,需要一個(gè)來(lái)播放此媒體流,
  如:document.getElementById("myVideo").src = windowUrl.createObjectURL(stre am);,用來(lái)看到自己的視頻,但同時(shí)還需要將媒體流通過(guò) pc.addStrem(stream)傳 給 peerConnection 對(duì)象,然后用 pc.createOffer(callback,error)創(chuàng)建一個(gè) offer,創(chuàng) 建成功后,觸發(fā)成功回調(diào),傳入一個(gè) description(簡(jiǎn)寫(xiě)為 desc),將這個(gè) desc 作 為參數(shù)設(shè)置為本地描述,此外這個(gè) desc 還有一個(gè)作用,它有一個(gè) sdp 對(duì)象,存 放的 sdp 串,需要將這個(gè)傳發(fā)送到接收方用以作為溝通的協(xié)議。
  如:pc.setLocalDescription(desc,callback,error);
  當(dāng) pc.iceGatheringState == "complete"時(shí),設(shè)置成功,至此,發(fā)送方的已經(jīng)完成。
  var pc = new peerConnection({"iceServers": []}, {optional:[{DtlsSrtpKeyAgreement:true}]}); getUserMedia.call(navigator,{audio: true,video:true},function(stream){pc.createOffer(function(desc){ pc.setLocalDescription(desc, function() {if(pc.iceGatheringState == "complete") {// 建立成功 }}, error);
  }, error);},error);
  接下來(lái)為應(yīng)答方。
  應(yīng)答則是需要拿到對(duì)方使用的 SDP 串作為協(xié)議,設(shè)置遠(yuǎn)程描述,也就是發(fā)送 方的信息,需要的參數(shù)則是 RTCSessionDescription 對(duì)象,RTCSessionDescription 對(duì)象需要一個(gè)對(duì)象參數(shù),對(duì)象包含 type 類型“offer”,另一個(gè)就是發(fā)送方發(fā)來(lái)的 sdp 串。
  即:var sessionDescription = new RTCSessionDescription({type: "offer",sdp: receiveSdp} pc.setRemoteDescription(sessionDescription,callback,error); 設(shè)置完遠(yuǎn)程描述后,需要將此消息告訴發(fā)送方,所以在成功回調(diào)中發(fā)送一個(gè)answer 請(qǐng)求,有些不同的是,pc.createAnswer 的前兩個(gè)參數(shù)都是回調(diào)函數(shù),第 三個(gè)才是參數(shù):{mandatory: {OfferToReceiveAudio: true,OfferToReceiveVideo: isVideo}};表示回復(fù)發(fā)送方,接受你的 audio 和 video 流。
  pc.setRemoteDescription(new  sessionDescription({type:  "offer",sdp:  receiveSdp}),  function()  {
  pc.createAnswer(function()  {if(pc.iceGatheringState  ==  "complete"){// 建立功}},error,constraints)},  remoteError)
  至此,一次單程的 webrtc 就完成了,但是作為視頻應(yīng)用,單方面接通是不行 的,雙方都看到對(duì)方的畫(huà)面的話,就讓被叫方也完成一次完整的視頻呼叫就可以 了。
  最后關(guān)于瀏覽器的兼容性,我們看兩組數(shù)據(jù):
\

\
  從市場(chǎng)占有率和技術(shù)成熟度來(lái)看,前兩名還是分屬 Chrome 和Firefox。因此,基于 H5 規(guī)范的的 RTC 應(yīng)用目前重點(diǎn)還是以適配這 2 款瀏覽器為主。

專題