微信小程序自2017年1月9日正式對外公佈以來,愈來愈受到關注和重視,小程序上的各類技術體驗也愈來愈豐富。而音視頻做爲高速移動網絡時代下增加最快的應用形式之一,在微信小程序中也固然不能錯過。本文來自騰訊視頻雲終端技術總監rexchang(常青)的技術分享,講述的是微信小程序中音視頻技術構思、設計和實現等方方面的內容,但願能爲你的音視頻技術實踐帶來啓發。php
若是您能微信小程序開發沒什麼瞭解,能夠從這篇微信官方的《小程序開發簡易教程》開始。html
學習交流:程序員
- 即時通信開發交流3羣:185926912[推薦]web
- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM》數據庫
(本文同步發佈於:http://www.52im.net/thread-1799-1-1.html)小程序
rexchang(常青):騰訊視頻雲終端技術總監,2008 年畢業加入騰訊,一直從事客戶端研發相關工做,前後參與過 PC QQ、手機QQ、QQ物聯 等產品項目,目前在騰訊視頻雲團隊負責音視頻終端解決方案的優化和落地工做。微信小程序
2016年微信開始啓動小程序內測以前,騰訊內部的各個團隊就已經開始接到消息。咱們每一個人都能預感到小程序將會對移動應用場景產生很大的改變。但在當時,我也是剛加入騰訊視頻雲團隊不久,對於這樣的信息更多的是關注,而並沒有太多細緻的思考。緩存
2017年伊始,隨着大量客戶的諮詢,我以及我所在的騰訊視頻雲團隊都開始意識到這裏的需求特別的旺盛。但因爲精力有限,以「小團隊大成績」著稱的微信工程師團隊很難有精力覆蓋全部的應用場景,在音視頻這裏,小程序僅提供了一些基礎的採集和播放能力,好比你們最爲熟知的 video 標籤就是採用了系統播放器來實現,因此只能支持 HLS 高延時直播和視頻點播功能。安全
而就在此時,騰訊視頻雲的 SDK 產品在通過了一年多的打磨優化以後,已經像是二戰初期的零式戰機,隨時準備「砍瓜切菜」。這裏和合做機會雖然不定,但咱們團隊依然坐上了從深圳總部開往廣州 T.I.T 的班車。服務器
通過屢次的溝通,以及 jianx 的努力幫助下,這個合做雖然偶然且充滿了各類不肯定,但最終達成。
幕後:音視頻小程序誕生在2017年4月一輛從深圳開往廣州的C7172列車上
在音視頻應用場景下,兩個團隊可以達成合做天然是個好事情,可是微信的市場地位也決定了這是一個不容兒戲的戰場。
因此咱們所面臨的挑戰也異常嚴峻:
1)接口必須簡單易用,最好一兩個標籤就能解決問題;
2)知足多種應用場景,既要支持直播又要可以支持實時視頻通話;
3)功能必須可擴展,開發者能夠根據自身的須要構建出各類個性化應用場景;
4)可維護性好,開發者可以自助排查一些技術問題,而不須要自己是個音視頻專家;
5)安裝包體積增量足夠小,否則微信的安裝包體積控住不住。
除了高標準的要求之外,時間也是一個很是不利的因素。整個項目留給咱們能夠證實自身能力的時間只有兩週,在短短兩週的時間裏,咱們須要在一個 G2C 項目落地且成功經過產品演示和方案驗收。
面對這些挑戰,我想到了蘇聯卡拉什尼科夫所設計的名槍 AK-47 :
說 AK-47 是世界上最成功的單兵武器一點也不爲過,這把槍全世界一共生產了約一億支。它具備不俗的殺傷力和極爲優秀的可靠性。從不卡殼,不易損壞,無論是沙漠仍是雨林,都能穩定地傾瀉火力,而且操做還很是簡單。
之因此這麼成功,源於其所貫徹的簡單實用的設計理念:迴轉式閉鎖確保了安全性,杜絕了隨機事故的可能性;結構簡單易拆卸,所以要生產它並不須要特別精密的加工技術,也不須要投資巨大的生產設備,甚至一個普通小做坊就能開工生產。
沒錯,化繁爲簡,追求簡單可靠,這就是咱們須要達成的目標。
達成上述的技術目標並不容易,須要咱們團隊一步一步的攻克技術難關。
首先,咱們要對騰訊視頻雲現有的音視頻體系進行拆解和抽象,也就是把整個體系打散成一個個積木,其中最重要的兩塊就是:音視頻上行(push)和音視頻下行(play)。
就是把本身手機上的聲音和畫面實時的上傳到雲端。咱們將這部分能力用視頻雲 SDK 進行實現,並封裝成一個叫作 的標籤。
SDK 內部實現機制如上圖所示:首先,咱們要對攝像頭的畫面進行捕獲,對麥克風的聲音進行採集。可是,原生採集和捕獲的畫面和聲音是須要進行預處理的,直接採集的畫面可能有不少噪點,因此咱們要進行圖像降噪;好比, 原生採集的人像裏,皮膚可能並不符合人們的預期,因此咱們須要進行磨皮和美顏;直接採集的聲音可能也有不少的環境噪音,因此咱們須要進行前景和後景音的分離而後進行底噪抑制。
通過預處理以後的畫面和聲音相比於原始採集的通常會有較大改善,由於全部的預處理都是以「討好」人類的視聽體驗爲目的,因此這一看似不起眼的部分會吸引不少公司在其上作很多的技術投入。舉個身邊的例子,以 LCD 平板電視爲例,SONY 的 LCD 產品線都沒有自家的液晶面板(以臺灣和大陸液晶面板爲主),卻能在整體效果上一直領先其它公司,其背後的祕密就是在圖像處理(基於圖像數據庫作超分辨率顯示)和背光技術(全部動物的眼睛都是對亮度最爲敏感)上的不間斷的積累和投入。
畫面和聲音都通過「粉飾」以後,就能夠送給編碼器進行編碼壓縮了。編碼器的工做是將一張張的畫面和一段段的聲音壓縮成 0101001... 的二進制數據,而壓縮後的體積要遠小於壓縮前。最後要作的工做就是將編碼後的數據經過網絡模塊發送出去。在在線直播場景中,通常採用的網絡協議都是基於TCP的,而在實時通話場景中,所採用的網絡協議則是 UDP 爲主。
也叫播放,就是從雲端把編碼後的音視頻數據實時下載下來並實時的播放,這樣一來,您就能看到遠程的畫面,聽到遠程的聲音。一樣的,咱們將這部分能力用視頻雲 SDK 進行實現,並封裝成一個叫作 的標籤。
SDK 內部實現機制如上圖所示:來自雲端的數據會直接送給網絡模塊,但網絡不是完美的,總會有時快時慢的波動,甚至會有可能發生阻塞和閃斷。若是服務器來一段數據, SDK 就播一段數據,那麼網絡稍微一波動,畫面和聲音就會表現出卡頓。咱們採用抖動緩衝(VideoJitterBuffer)技術解決這個問題,就像是爲網絡過來的數據準備一個小的蓄水池,音視頻數據先在這裏暫存一小會兒再送去播放,這樣就能夠在網絡不穩定時有必定的「應急」數據可使用。
數據通過緩衝之後,就能夠送給解碼器進行解碼,解碼就是把壓縮後的音視頻數據還原成圖像和聲音,而後進行渲染和播放。咱們採用了 openGL 進行畫面的渲染,使用 iOS 和 Android 的系統接口來播放聲音。
有了這兩個簡單的標籤,咱們就能夠進行初步的組合,構建出第一個最簡單的應用場景:在線直播。
在線直播是一個很是經典的單向音視頻場景,您只須要簡單的將兩個標籤組合在一塊兒便可, 負責將本地畫面和聲音實時上傳到騰訊雲, 則負責從雲端實時拉取音視頻流。
若是是簡單的一路上行 + 一路下行,那麼咱們隨便搭建一箇中轉服務器就能夠解決問題了,但這樣只能在很小的範圍內實現高質量的直播服務,真正要作到高併發和流暢無卡頓,就須要一個強大的視頻雲。
視頻雲在這裏的做用就像一個**信號放大器**,它負責未來自 的一路音視頻進行放大,擴散到全國各地,讓每個 都能在離本身比較近的雲服務器上拉取到實時且流暢的音視頻流。因爲原理簡單、穩定可靠且支持幾百萬同時在線的高併發觀看,因此從在線教育到體育賽事,從遊戲直播到花椒映客,都是基於這種技術實現的。
但在線直播方案只能應用於解決單向音視頻問題,由於它有個明顯的問題,就是延時通常都是在 2秒 - 5秒左右,這是使用 標籤配合騰訊雲視頻雲能夠達到的效果。若是是video標籤,這個延時會更長,能夠到 20 秒以上,那麼在一些對時延要求很苛刻的場景下就再也不適用了。
在安防監控的場景裏,家用 IP 攝像頭通常都帶有云臺旋轉的功能,也就是攝像頭的指向會跟隨遠程的遙控進行轉動,若是畫面延時比較大,那麼觀看端按下操控按鈕到看到畫面運動所須要等待的時間就會比較長,這樣用戶體驗就會特別很差。
再好比 2017 很是流行的在線夾娃娃場景,若是遠程玩家視頻畫面的延時很是高,那麼遠程操控娃娃機就變得不太可能,沒有誰能真正抓到娃娃。
既然要達到這麼低的要求,普通的在線直播技術就再也不適用了,咱們須要新引入兩個新的科技點:**延時控制** 和 **UDP加速**。
延時控制:
網絡不是完美的,網絡是波動的。在有波動的網絡下,服務器上的音視頻數據並非穩穩的來到您的手機上,而是忽快忽慢。慢的時候您可能會看到卡頓,快的時候就會產生堆積,而堆積的後果就是延時的增長。因此,咱們須要採用延遲控制技術,它的原理很簡單,當網絡慢的時候就播的慢一點,當網絡快的時候就播得快一點,這樣就起到必定的緩衝做用。固然,真正實現時就會發現,聲音是個很不聽話的「孩子」,要處理好聲音的效果是一個很是高難度的技術活。
UDP加速:
既然網絡不那麼完美,老是時快時慢,那咱們是否是能夠改善一下呢?在經典的單向音視頻方案中,通常採用的都是 TCP 協議,由於它簡單可靠且兼容性極好。然而 TCP 的擁塞控制特別注重公平,自然就有時快時慢的壞毛病,因此咱們須要用 UDP 協議替代之,相比於設計目標定位於可靠傳輸的 TCP 協議,UDP 能夠作得更穩且更快。
咱們將 延時控制和 UDP 加速技術加入到 標籤裏,能夠將端到端的延時控制在 500ms 左右。這對於操做延時要求比較苛刻的場景,就能夠知足需求了。
有了單向低延時技術,那麼雙向視頻通話天然也就比較簡單了,只須要通話的雙方 A 和 B 各自拉通一路低延時鏈路就能夠了。
好比在車險定損的場景裏,遇險的車主經過小程序呼叫保險公司,這個時候保險公司內部的定損客服只要經過一路低延時的鏈路就能夠看到車子的出險狀況。可是僅僅這樣還不夠,視頻內容跟圖片同樣,都容易被實現僞造和做假。因此定損員就須要有一路視頻一樣到達車主那裏,這樣兩路音視頻同時連通,就構成了一個典型的視頻通話場景。因爲車主和定損員能夠經過視頻進行交流,所以造假騙保的風險就被極大地下降了。
雖然這樣說是沒錯,但實現上可不是那麼簡單的。偏偏相反,它很是困難,由於咱們還須要引入額外的不少科技點:
噪聲消除:噪聲抑制的目的是將用戶所處環境裏的背景噪音去除掉,好的噪聲抑制是迴音消除的前提,不然聲學模塊沒法從採集的聲音辨別出哪些是回聲,哪些是應該被保留的聲音。
迴音抑制:在雙向視頻通話中,用戶本身手機的麥克風會把喇叭裏播放的聲音再次記錄下來,若是不將其抹除掉,這些聲音會被反送給對端的用戶,從而造成回聲。
Qos流控:網絡不可能一直都很完美,尤爲是中國大陸地區的上行網速一直都有政策限制。Qos流控的做用就是預測用戶當前的上行網速,並估算出一個適當的數值反饋給編碼器,這樣一來,編碼器要送出的音視頻數據就不會超過當前網絡的傳輸能力,從而減小卡頓的發生。
丟包恢復:再好的網絡也不免會有丟包的狀況,尤爲是 WiFi 和 4G 等無線網絡,因爲傳輸介質自己就不是能夠獨享的,因此一旦受到干擾,或者高速運動都會產生大量的丟包,這時就須要引入一些丟包恢復技術,將失去的數據儘可能補救回來。
以上四個科技點,咱們也加入到了 和 標籤中,並給他們賦予了一個新的模式 RTC( Real Time Chatting 的 首字母縮寫,有點 Chenglish 的味道),這才真正把實時音視頻通話搞定。
你看,要保持功能到位,又不能跳出標籤這種簡單易用的設計風格,這不容易吧。實際上這裏的四個科技點實在是太難了,須要不少年的技術積累和沉澱,以致於咱們也不是現用現作的。正所謂站在巨人的肩膀上才能看得更遠,這裏的技術能力是由騰訊音視頻實驗室的「天籟」引擎所實現的。
既然雙人視頻通話已經搞定了,是否是多人也就照葫蘆畫瓢就能夠了?您看,咱們只須要將 A 和 B 之間的 url 置換,變成 A、B、C 甚至更多人之間的 url 置換,不就能夠了嗎?
思路依然正確,可是真正要將功能作到好用且成熟,僅依靠簡單的 url 交換是很是粗糙的。咱們須要繼續引入額外的兩個科技點。
房間管理:
以上圖所示的 A B C 之間的多人視頻場景爲例,要讓每個人都很清楚其它人的狀態(好比播放url,以及當前是否有上行等等),這個事情但是很是困難的,搞很差就容易出現各方信息不對齊。對於更復雜一點的狀況,好比當有第四我的 D 進來的時候,或者第五我的 E 進來又出去的時候,這種信息同步幾乎就是一場噩夢。
最好的辦法就是把參會人的狀態和信息都收攏在服務器端,構造一個 **房間** 的概念,這樣就能夠確保參會人都能從服務端得到一樣的信息,而不須要各自去維護。
通知系統:
當有新的參與者進入房間,或者有人離開時,就須要對房間裏的人進行信息廣播,這就須要一個不錯的 IM 系統負責收發消息。好比當 D 進入時,就能夠向房間內的其它成員廣播這個 「I'm coming」 的事件,這樣 A B C 就能夠在本身的 UI 上展現 D 的視頻畫面了。
加入房間管理和 通知系統之後,咱們就能夠將 和 和微信小程序的 websocket 等基礎能力組合在一塊兒,構建各類功能強大、邏輯複雜的小程序應用。
一路走來,你們能夠看到咱們在小程序音視頻的技術體系上所作的種種努力能夠用以下的技術圖譜勾勒出來。
總結一下,咱們的實現思路就是:
1)首先是化繁爲簡,將全部的音視頻解決方案拆解成兩個基礎行爲:上行和下行,並經過兩個標籤 和 的簡單組合,實現最基本的在線直播功能;
2)以後是經過加速線路和延時控制,將一路音視頻的時延縮短到 500ms 之內;
3)再以後,咱們經過引入噪聲抑制和回聲消除等聲學處理模塊,讓一路變兩路成爲了可能,這也就構成一個最簡單的視頻通話能力;
4)最後,咱們又經過加入房間服務和狀態同步通知,將雙路音視頻變成了多路音視頻,從而將應用範圍進一步擴大。
圖中的 UI 截圖使咱們騰訊視頻雲小程序Demo的界面截圖,你們經過在微信小程序裏搜索「騰訊視頻雲」就能夠體驗上述基礎功能了。
若是您但願本身也動手來試一試,不妨看一下咱們的技術文檔:
小程序入門導讀:https://cloud.tencent.com/document/product/454/12517
標籤使用指引:https://cloud.tencent.com/document/product/454/12518
標籤使用指引:https://cloud.tencent.com/document/product/454/12519
雙人或多人音視頻:https://cloud.tencent.com/document/product/454/15364
直播+連麥:https://cloud.tencent.com/document/product/454/15368
WebRTC互通:https://cloud.tencent.com/document/product/454/16914
常見問題:https://cloud.tencent.com/document/product/454/13037
[1] QQ、微信團隊原創技術文章:
《騰訊技術分享:騰訊是如何大幅下降帶寬和網絡流量的(圖片壓縮篇)》
《騰訊技術分享:騰訊是如何大幅下降帶寬和網絡流量的(音視頻技術篇)》
《騰訊技術分享:Android版手機QQ的緩存監控與優化實踐》
《微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐》
《微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?》
《騰訊技術分享:Android手Q的線程死鎖監控系統技術實踐》
《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)》
《QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)》
《騰訊團隊分享 :一次手Q聊天界面中圖片顯示bug的追蹤過程分享》
《微信團隊分享:微信Android版小視頻編碼填過的那些坑》
《微信團隊披露:微信界面卡死超級bug「15。。。。」的前因後果》
《月活8.89億的超級IM微信是如何進行Android端兼容測試的》
《微信客戶端團隊負責人技術訪談:如何着手客戶端性能監控和優化》
《微信團隊原創分享:Android版微信的臃腫之困與模塊化實踐之路》
《微信團隊原創分享:微信客戶端SQLite數據庫損壞修復實踐》
《騰訊原創分享(一):如何大幅提高移動網絡下手機QQ的圖片傳輸速度和成功率》
《騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(下篇)》
《騰訊原創分享(三):如何大幅壓縮移動網絡下APP的流量消耗(上篇)》
《如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源》
《開源libco庫:單機千萬鏈接、支撐微信8億用戶的後臺框架基石 [源碼下載]》
《微信新一代通訊安全解決方案:基於TLS1.3的MMTLS詳解》
《微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》
《微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》
《Android版微信從300KB到30MB的技術演進(PPT講稿) [附件下載]》
《微信團隊原創分享:Android版微信從300KB到30MB的技術演進》
《微信技術總監談架構:微信之道——大道至簡(PPT講稿) [附件下載]》
《微信海量用戶背後的後臺系統存儲架構(視頻+PPT) [附件下載]》
《微信異步化改造實踐:8億月活、單機千萬鏈接背後的後臺解決方案》
《架構之道:3個程序員成就微信朋友圈日均10億發佈量[有視頻]》
《微信團隊原創分享:Android內存泄漏監控和優化技巧總結》
《微信團隊原創Android資源混淆工具:AndResGuard [有源碼]》
《移動端IM實踐:Android版微信如何大幅提高交互性能(一)》
《移動端IM實踐:Android版微信如何大幅提高交互性能(二)》
《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》
《移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)》
《信鴿團隊原創:一塊兒走過 iOS10 上消息推送(APNS)的坑》
《騰訊TEG團隊原創:基於MySQL的分佈式數據庫TDSQL十年鍛造經驗分享》
《微信多媒體團隊訪談:音視頻開發的學習、微信的音視頻技術和挑戰等》
《瞭解iOS消息推送一文就夠:史上最全iOS Push技術詳解》
>> 更多同類文章 ……
[2] 有關QQ、微信的技術故事:
《技術往事:微信估值已超5千億,雷軍曾有機會收編張小龍及其Foxmail》
《2017微信數據報告:日活躍用戶達9億、日發消息380億條》
《技術往事:創業初期的騰訊——16年前的冬天,誰動了馬化騰的代碼》
《技術往事:史上最全QQ圖標變遷過程,追尋IM巨人的演進歷史》
《開發往事:深度講述2010到2015,微信一路風雨的背後》
《開發往事:記錄微信3.0版背後的故事(距微信1.0發佈9個月時)》
《前創始團隊成員分享:盤點微信的前世此生——微信成功的必然和偶然》
《即時通信創業必讀:解密微信的產品定位、創新思惟、設計法則等》
>> 更多同類文章 ……
《即時通信音視頻開發(五):認識主流視頻編碼技術H.264》
《即時通信音視頻開發(九):實時語音通信的迴音及迴音消除概述》
《即時通信音視頻開發(十):實時語音通信的迴音消除技術詳解》
《即時通信音視頻開發(十一):實時語音通信丟包補償技術詳解》
《即時通信音視頻開發(十三):實時視頻編碼H.264的特色與優點》
《即時通信音視頻開發(十五):聊聊P2P與實時音視頻的應用狀況》
《即時通信音視頻開發(十六):移動端實時音視頻開發的幾個建議》
《即時通信音視頻開發(十七):視頻編碼H.26四、VP8的前世此生》
《學習RFC3550:RTP/RTCP實時傳輸協議基礎知識》
《基於RTMP數據傳輸協議的實時流媒體技術研究(論文全文)》
《還在靠「喂喂喂」測試實時語音通話質量?本文教你科學的評測方法!》
《實現延遲低於500毫秒的1080P實時音視頻直播的實踐分享》
《技術揭祕:支持百萬級粉絲互動的Facebook實時視頻直播》
《理論聯繫實際:實現一個簡單地基於HTML5的實時視頻直播》
《首次披露:快手是如何作到百萬觀衆同場看直播仍能秒開且不卡頓的?》
《騰訊音視頻實驗室:使用AI黑科技實現超低碼率的高清實時視頻聊天》
《七牛雲技術分享:使用QUIC協議實現實時視頻直播0卡頓!》
《實時視頻直播客戶端技術盤點:Native、HTML五、WebRTC、微信小程序》
《微信多媒體團隊訪談:音視頻開發的學習、微信的音視頻技術和挑戰等》
>> 更多同類文章 ……
(本文同步發佈於:http://www.52im.net/thread-1799-1-1.html)