直播、社交、在線教育等行業催生了實時音視頻技術(RTC) 的興起和發展。反過來, RTC 的發展和應用也為這些行業帶來了巨大的增長。随着 RTC 對應用場景的不斷滲透,業務夥伴關于場景體驗的要求也越來越高,比如更低延時、更加順暢、更高畫質。LiveVideoStackCon 2021 北京站,火山引擎視頻雲 RTC 産品負責人 Julian,為大家分享火山引擎視頻雲 RTC 是怎樣在抖音、西瓜、頭條等産品的場景實踐中,不斷地追求極緻的。
文 | 朱利安
整理 | LiveVideoStack
大家好,我是來自火山引擎 RTC 團隊的 Julian,很高興今天能跟大家學習交流。今天我帶來的分享是抖音背後的 RTC 是如何追求極緻的。
1. 簡介
首先,我先簡單介紹一下火山引擎 RTC 團隊。
我們并不是來自抖音,我們來自火山引擎,抖音也是火山引擎服務的一個客戶。我所在的團隊是火山引擎的 RTC 團隊,已經為抖音服務了 4 年時間。在 4 年中,抖音不斷增長,擁有 6 億 DAU,而火山引擎 RTC 團隊的能力也有跨越式的提升。
我們先看一下抖音上的 RTC 應用場景。
最經典的是連麥 PK。兩個抖音主播通過 RTC 進行連麥,轉碼生成兩路音視頻流,推到 CDN,分别給各自直播間的觀衆進行直播。在這個過程中,主播 PK,看誰收到的禮物更多。有些 PK 場景還會有主播和觀衆的互動:這邊,主播和觀衆的互動也是通過 RTC 進行的。
抖音上也有一些很有意思,但是大家可能了解不是特别多的場景,比如一起看和好友私聊。
一起看就是我們在抖音上可以幾個好友連線,一起看同一個視頻,其中有一個人是房主,房主的視頻刷到哪,其他人自動跟着刷到哪,大家還能通過語音實時交流視頻内容。這裡面除了語音聊天是用 RTC 實現之外,短視頻的消息同步也是用 RTC 的低延時消息做的。
一起看就是幾個好友連線,在抖音上同時看同一個視頻。其中有一個房主,房主看到哪,其他人的視頻也自動播放到哪。大家通過語音進行實時交流。這個場景下,除了語音聊天是用 RTC 實現的以外,視頻播放進度的消息同步也是用 RTC 的低延時消息功能實現的。
還有一個場景是好友私聊。一些抖音重度用戶知道,抖音現在也支持視頻和語音通話,體驗也非常不錯。我自己和朋友用其他軟件通話比較卡的時候,就會換抖音。經常換了抖音就不卡了,大家有興趣也可以試一下。抖音上的視頻通話還自帶美顔,因此視頻通話相對語音通話的比例會更高一點。
抖音上的通話效果好是有指标支持的。經過長期的合作,我們打磨出了一套指标體系。這個圖中摘錄了部分核心指标。左邊是 RTC 的技術指标,包括卡頓率、端到端延遲、首幀時長、清晰度。右邊是與 RTC 質量相關的抖音業務指标,包括用戶反饋率、用戶滲透率、用戶使用時長以及業務營收。RTC 的優化都是在數據指标指導下進行的。優化過程中,我們做了很多 AB 實驗和歸因分析,通過優化技術指标,來優化業務指标。全量上線的标準是能夠達成最優的業務指标。
2. 面臨的挑戰
下面說說我們的挑戰是什麼。
如果對 RTC 的核心指标進行歸總的話,可以劃分成清晰、流程、實時三個核心要求。但對 RTC 熟悉的同學都知道:這三個核心要求之間,有時是無法得兼的。網絡好的時候沒什麼問題,網絡比較差的時候,就要犧牲其中一個或兩個指标。
舉個簡單的例子,當網絡不好,視頻有卡頓時,增加緩沖延時是最簡單的優化手段。緩沖延時太高,會引起兩個人搶話,嚴重影響通話體驗。如果同時需要流暢和實時,那隻能降低清晰度。抖音上有很多顔值主播,讓主播的臉能被看清楚,又是一件優先級挺高的事情。
業務面對這樣的選擇題時,通常可以接受一點指标上的妥協,但總是會提出持續優化的要求。換句話說,就是“我全都要”。業務的需求都是合理的。接下來我們就來講一下我們是如何應對這樣的挑戰的。
3. 最佳實踐
3.1 流暢度
首先,講一下流暢度。流暢度對應的指标是卡頓率。卡頓其實對于交流的影響是最大的,即使隻卡掉一個字,你也會明顯感覺到交流不暢。
卡頓是因為弱網。那弱網又是什麼引起的呢?
我們建立一個最簡單的 RTC 傳輸模型,終端 A 到終端 B,中間是 RTC 的雲端傳輸網絡。其實雲端傳輸網絡的傳輸質量現在已經非常好了。我們會監控 QoS 指标。
監控結果可以發現:雲端丢包基本上是不存在的。國内雲端傳輸延遲基本在 50ms 以内,全球範圍基本都在 250ms 以内。
主要的弱網其實是在接入網,也是我們常說的 FirstMile 和 LastMile,也就是用戶自己的客戶端接入 RTC 網絡的這一段。數據統計後發現,大概 30% 的用戶會碰到弱網的情況,其中 26.8% 是輕度弱網,中度和重度都在4%左右。
這邊弱網用戶等級,是按瞬時網絡指标進行區分的,分為好、輕度、中度和嚴重4個等級。
這邊我們找了一個極端的線上 case,看看 RTC 能力的極限如何。
這是一個丢包率和延時參數的示意圖,我們看到,最初比較平穩;突然發生弱網,持續了一段時間,丢包率最高達到了 49%。随着抗丢包策略的接入,延遲從 88ms 升到 700ms。經過優化,抗丢包策略的卡頓時長基本都控制在 1.2 秒以内。
要适應突發的極端弱網情況,我們的算法也會實時自動調節。
針對不同的場景,其實會适用不同的算法。比如 1v1 通信時,除了根據發送端的上下行網絡調整發送策略外,也要關注接收端的下行網絡情況。接收端下行網絡不佳時,發送高規格的音視頻數據并不會帶來什麼收益。多人通信時,我們會采用大小流(Simulcast)的方法。應用大小流時,大家常常會關注接收端。但其實發送端上行可能也會有壓力,上行如果出現弱網的時候,也要考慮發大小流是否合适。
這些場景都在我們的算法考慮範圍内。我們會通過對用戶 QoS 數據的洞察,針對不同場景,自動下發對應的策略。算法的訓練數據來自線上海量的真實用戶網絡環境。上面舉的例子是抗丢包。真實的線上弱網環境非常複雜,純丢包的場景幾乎是不存在的,一定會疊加抖動、延時等網絡問題。我們把線上用戶真實的情況不斷的加到訓練庫裡,不斷優化算法的應對。
另外,應對網絡從好到差的過程要敏感,但恢複的過程要有一定的弛豫。有時候網絡波動發生,消失的過程很快。多等待 3、4 秒,确定網絡真的平穩了,算法才會把用戶的碼率恢複上去。
我們準備了一段視頻進行弱網對抗的演示。是團隊成員自己錄制的,不涉及用戶隐私。
演示中模拟了弱網情況,并且限制了最高可用帶寬,分别降到三個弱網等級。網絡從好的狀态到輕度弱網的情況,碼率和幀率有所下降;中度弱網時,網絡丢包比較嚴重,分辨率也有所下降;重度弱網時,碼率 500fps 都不到了。極差的情況下引入了一個 1 秒的卡頓,然後網絡有所恢複,突然又到了極差的情況,最後恢複。
可以看到在極差的情況下,雖然有1秒的卡頓,但并沒有漏字,在适應弱網之後,會把之前漏掉的音頻用比較小的倍速去追上進度,不會影響内容。
3.2 實時性
實時性有兩個指标,端到端延遲和首幀渲染速度。對通話場景來說,端到端延遲控制在 400ms 以内,用戶體驗都是沒問題的。當然,也有對延遲要求更高的場景,比如雲遊戲,它對延遲要求極高,從用戶觸發指令開始,到收到首幀響應,來回需要在 100ms 以内。本次分享時間有限,就不展開了。
我們主要分享首幀渲染速度。
我們可以思考一下。為什麼 CDN 的延時比 RTC 大很多,反而首幀響應又快更穩定?其實,CDN 會在邊緣節點把命中率高的視頻加入緩存,用戶在拉流的時候可以從邊緣節點直接拉,這樣就比較快。因為業務特性的原因,RTC 不可能去做這樣的緩存策略。但我們會去借鑒這樣的思路。多人場景下,比如剛開始是兩個人通話,後來第三個人進來,之前兩個人的通話就已經在邊緣節點上了。火山引擎 RTC 有一種策略是把最近 1 個 GOP 的音視頻流緩存到邊緣,加快新的音視頻通話參與者打開首幀的速度。
GOP 是兩個視頻關鍵幀之間的時間間隔。大家對視頻處理比較熟悉,就知道這個概念。業内 GOP 采用 1s、2s 的都有。
我們無法預測碼流的請求什麼時候來。如果沒有緩存,隻要不是落在 GOP 剛開始的時候,請求者就必須等到下一個 I 幀時,才能拉到首幀。很顯然,這個等待時間根據 GOP 的大小有一個預期分布。而應用緩存策略之後,不管請求什麼時候到,都可以即時獲取到首幀。
這裡錄了個Demo,主要看的是每進一個房,3個流的加載速度。可以像抖音一樣做上滑下滑的切換房間,最後是一個上麥的速度,這種情況下都是需要更快的首幀。這個 Demo 裡面打開首幀的時長都在100ms 到 200ms 之間。,我們也檢測了線上首幀的速度,基本都在700ms以内,有的業務形态好的,會控制在400ms以内,我們管這個叫瞬開。
3.3 清晰度
第三個優化方向是清晰度,清晰度提升的是用戶體驗的上限。前面的優化,用戶感知起來是非常直接的,而清晰度的感知是潛移默化的。視頻沒有那麼清晰,你一開始并不會有很明顯的感覺,但看的時間長了以後,就可能不想繼續看了。所以這個指标最後會影響用戶使用時長。
清晰度是沒有上限的。RTC 需要解決的問題是如何在有限的帶寬下,讓實時傳輸的視頻質量更高。
這個視頻裡面顯示的是自研的 BVC1 編碼器,和主流的 H.264 和 H.265 在編碼效率的對比。右側的 RD-plot 曲線圖裡顯示 BVC1 編碼器能比主流的 H.265 編碼器再提升 0.6dB。一般我們評價一個 Codec 算法好不好,會看它節省了多少帶寬。但具體到 RTC 中,用戶的帶寬是平穩的,分辨率也是業務上所決定的,不需要把帶寬用足,把分辨率變得更高。所以火山引擎 RTC 選擇在帶寬和分辨率不變的情況下,把編碼效率用到畫質提升上。
重點可以看背景上的粉色條。
ROI(感興趣區域)編碼我們也在廣泛地使用,基本上連麥場景下都會使用。用白話講,就是針對中間的人臉進行編碼。在同樣的幀率和碼率之下,經過 ROI 編碼後的效果,在臉部細節上更清晰。正好前面有同學問到,我們怎麼去評測 ROI 的效果。ISO 提供了一種通過盲測得票比率映射 JND 的方式評測畫質。我們通過内測邀請了 100 同學對比評測,得到了 2.3 分。這是一個比較高的分數了。
最後我們也用到了超分算法。
可以看一下頭發絲的細節。超分提升分辨率。這邊把原本 360P 的視頻超分到 720P。這邊盲測的評分就更高一些,是 2.55 分。
不同場景下的優化策略
有了硬核的算法能力之後。我們也會針對每個場景适配最合适的優化策略。
比如在 PK 場景,運用的是最佳分辨率策略。
先簡單介紹一下這個策略。PK 時,RTC 畫面會占據畫面的四分之一(長、寬各一半)。現在随着用戶的手機越來越好,有些手機能支持 1080P 的音視頻通話,有些隻能支持 540P 等等。比如你作為一個主播,拿着 1080P 的收集和 720P 的主播進行 PK 連麥的話,其實你看到的,對面主播發過來的視頻也就是 540P。對面主播采集 720P 的視頻也沒什麼用;反過來也是一樣的。最佳分辨率策略就是說,RTC 會自動根據對面主播的設備分辨率情況,來選擇最合适的分辨率,而不是無腦用最高清的分辨率。
我們接收另外一個在 PK 連麥場景上應用的轉推 CDN 的策略。大部分 RTC 都是在雲端做轉碼,然後轉推 CDN 的。這其實會引入多一次的編解碼和傳輸。PK 場景是兩個人,對端視頻流一定是從遠端過來的,這個沒辦法。但其實主播自己的畫面轉推 CDN 時,經過服務端轉推的二次編解碼,它的畫質一定會有點受損,所以我們會碰到很多業務方提出要用客戶端轉碼的方案。
但客戶端轉碼也會來其他的問題:雖然減少了一次編解碼傳輸,但是會帶來設備性能消耗的提升。我們提出了端雲一體轉推 CDN 的方案。如果這個主播的設備,其性能和網絡足夠在客戶端做轉碼,我們就在客戶端做;如果不足,就降級到服務端進行。這樣,設備性能高時,能享受到更好的清晰度;設備性能低,我們能保證正常使用。目前這個策略應用于線上超過 60% 的用戶。
這就涉及了怎麼去判斷用戶設備的性能的問題。
火山引擎 RTC 在後台維護了一個很大的機型數據庫,設備總數達到 2w ,并且不斷增加中。這邊是部分截圖。我們會保證每一款機型在對應場景下,都有經過打磨驗證的推薦參數和推薦策略。
3.4 美顔特效
最後單獨提一下 RTC 和美顔特效的結合。美顔特效其實對于 CPU 和内存的消耗是更大的,有這麼大的一個模型在那邊跑,對于 RTC 自适應算法帶來了新的挑戰。
我們在測試過程中碰到過美顔特效影響編碼算法效率的事情。所以我們思考,怎麼盡可能避免這樣的影響?
先看一下現在主流的做法,RTC 和 CV 是分開的,開發者需要先自己采集,送到美顔特效的 SDK 處理,拿到處理後的視頻流,再在本地回顯,并送到 RTC SDK 做編碼,然後傳輸。這個邏輯很順,但缺點在于, RTC 編碼時會考慮弱網和設備性能的降級,如果因為弱網或設備性能不夠,RTC 編碼是會降級的。你想編碼時候編的是一個 360P 的視頻,采集和美顔用 1080P 就沒什麼意義,一點都不低碳。如果 RTC 的降級能夠影響到采集和美顔,整體的性能消耗會更優。
火山引擎 RTC 就把美顔特效的 SDK 和 RTC 統一調度了。采集就用的 RTC SDK 的能力,再通過 RTC SDK 調 CV 相關的接口。這樣,采集和提交到美顔 SDK 的視頻分辨率都是一個分辨率。再也不會出現采集、美顔 1080P,傳輸 360P 的情況了。
總結
雖然今天介紹的是我們為抖音做的優化,但這實際上是一套針對場景特點優化的方法論,不局限于抖音。
目前我們除了服務抖音以外,還服務着字節内外部的其他客戶。現在月均通話分鐘數已經超過了 150億。龐大的基數帶來的巨大的數據,也是我們優化的着力點。
我們的态度是追求極緻,我們的目标是成就合作夥伴。大家有興趣的話可以做進一步的交流。
感謝大家!
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!