K歌禮物視頻動畫 web 端實踐及性能優化回顧

2021-02-10 騰訊音樂技術團隊

K 歌移動客戶端19年在直播間中上線了視頻禮物資源動畫能力,使用特製的視頻資源加通道導出和混合 (基於企鵝電競vapx方案),支持了細膩的視頻動畫素材播放渲染,同時解決了直接播放視頻背景無法透明的問題。

   

‍‍‍‍‍‍在隨後的新 pc 主播端項目中我們對直播工具進行重構 (主界面 UI 基於 web 完成),禮物動畫部分由於當時沒有 web 版本的 sdk,為了復用線上已有的動畫資源以及和移動端保持對齊的效果,web 端通過 video + canvas/webgl 實現進行了支持。

此文回顧整理一下之前的實現流程與細節。

0. 業務流程

首先基於線上方案,上架一個動畫資源的整體的流程為以下幾步:

將多個不同視頻樣本上傳到配置平臺,同時填寫配置 (類型/方向/尺寸等);

後臺根據配置生成生成禮物編號入庫,將視頻發到 CDN 上架;

前端通過後臺接口可拉到禮物資源所對應的視頻地址與配置參數;

前端觸發播放禮物動畫。

下面主要講解渲染播放方面的實現。

1. 實現邏輯

從方案和動畫資源來看,為了解決背景透明的問題,視頻文件都包含了兩個部分:原動畫部分以及單獨導出的 alpha 通道。只是尺寸和方向不同。

因此逐幀將兩個部分的 rgb 分別取出,進行通道混合,就能實現透明背景的畫面。
具體來講,假設資源在某一幀某一點的 rgb 分別為:
原片部分: rgb(R, G, B)
alpha部分: rgb(A, A, A)
混合後的動畫相應位置就是: rgba(R, G, B, A)

2. 最簡方案

首先視頻一般用 <video> 播放。結合上面這個角度講,自然先想到了使用 canvas:讓 video 隱藏播放,同時在播放過程中逐幀 drawImage 到畫布,讀取 ImageData,按照位置取出兩部分,混合後重新 putImageData 顯示。

共使用到兩個 canvas 畫布,一個用來離屏讀寫 imageData, 計算後放到另一個真實看到的畫布。


這樣第一版就快速實現了。單個 demo 來看是 Ok 的。


但是接下來仔細測試,還有不少優化空間:

3. 加載問題

首先嘗試多個動畫同時渲染,調低網速,會發現動畫跟隨緩衝而卡頓。(這裡為了方便實驗關閉了緩存)


從 network 來看,同時加載播放多個線上視頻,並行佔用帶寬,播放緩衝會導致 video 暫停,實際結果就是 fps下降了。禮物動畫這種場景本身不應該出現播放中的等待。因此需要支持加載完整個視頻後再本地播放。

這裡改為使用 xhr2 將視頻完全下載後轉為 blob 再放到 video 讓其能夠一次順暢播完。

修改後的效果。整體首次播放比剛剛要順暢了。

但也有代價,就是增加了加載準備時間。後續可以通過離線緩存和空閒時預加載來彌補和提升。

視頻動畫資源通常很大,單個在2-5m左右甚至更多,一些高頻禮物如果實時下載延遲會比較大,沒有緩存反覆下載也會導致帶寬消耗浪費。因此也加上了 service worker 進行資源的持久化。策略使用為 CacheFirst (基於workbox)。冷啟動空閒時也可以手動預加載部分資源。

4. CPU消耗

這時繼續再多增加同屏個數來測試,下面翻一倍增加到 8 個,同時反覆多次循環重複播放,發現性能大幅下降了,非常卡頓。

重複播放時資源都有了,這次肯定不是加載問題。這時打開 performance monitor,發現 cpu 消耗非常高,基本都是 100%。


於是通過錄製 performance 來分析,發現瓶頸主要在 canvas 的 getImageData / drawImage 以及 pixelData 的遍歷計算上。這裡對 CPU 的消耗太高了。


這裡 demo 單個視頻是 1440x1152,等於每一幀要 get 出 6635520 個 pixelData (pixel * rgba)。遍歷計算 1658880 次結果色值。n個動畫再乘以n,計算量非常大,導致高負載,fps也相應降低。

另外這裡高頻的繪圖場景,直覺上應該是 GPU 的長項才對。但通過系統監控看到GPU在打開前後負載沒太大的變化 (在20-30%間波動)。能否想辦法發揮 GPU 的能力?

因此重新思考方案,看能否找到其他合適的方案可以代替 ImageData 操作和計算。

5. 更換 WebGL

按照前面的設想 (嘗試將消耗轉移和利用 GPU),於是考慮使用 WebGL 來看看能否實現。


理論上就是每幀兩個部分的對應區域疊加混合。剛開始憑直覺找了一圈 Blend 和 composite 的方案不合適。後來想起 ImageData、 <image /> 這些是可以作為 texture 紋理在 WebGL 中使用的。

那 <video /> 能否當做紋理?查閱文檔果然也可以。然後思路就來了:我們知道紋理是可以互相疊加的,在渲染過程中著色器可以清楚的表達如何去處理最後的色值。那理論上我們就可以直接把整個 video 作為紋理,取不同的區域去參與渲染計算和疊加。

根據這個邏輯,梳理一下代碼實現。首先創建程序和掛載著色器:

頂點著色器 (上面的Shaders.vertex) 裡把坐標和變量聲明:

創建兩個坐標變量 AlphaCoord 和 ColorCoord,分別代表兩個區域的位置 (gl很囉嗦,已省略部分非關鍵代碼):

再來看看片段著色器 (前面傳入的Shaders.fragment) 。根據前文的邏輯,帶入坐標,分別從兩個區域各取出 rgb 和 alpha,合成新的color:

三行就搞定了。就和我們自己計算 rgb 一樣,只不過是手動 CPU 計算變成了編譯到 GPU 運算。

最後逐幀使用 video 創建紋理並渲染:




經過編碼和調試,成功跑起來後,再次打開 performance,cpu 峰值和均值都下降了(90-100% 到 20-30%):

fps也提升了3-4倍(4-5 到 20左右)。證明思路是ok的。


對比此時的系統負載 GPU 比原先增加15%(從30%到45%)。CPU從60%左右下降到20-30%。



再降到同屏 4-5 個的情況下,可以穩定在60fps,足夠承載業務場景。

6. 總結

打開了 WebGL 的寶盒,到此後續還有沒有更多優化空間?比如冷啟動預緩衝時間的縮短;移動端的適配,卡頓檢測等等。另外還有沒有比 video 紋理疊加更高效率的方式,或者更大膽的想法,能否 MSE 或 WASM 跳過 video 直接到 WebGL?更多細節還有待後續研究。

騰訊音樂全民k歌招聘客戶端、web前端、後臺開發,點擊查看原文投遞簡歷!或郵箱聯繫: godjliu@tencent.com

相關焦點

  • 全民K歌推流直播Web實踐
    為此,K歌web團隊封裝了一套同時支持hls和flv視頻流播放的kg-player SDK。kg-player SDK我們對WXInlinePlayer 以及騰訊自研的TCPlayer進行了源碼優化,解決了iOS端畫音不同步、移動端系統適配以及webgl渲染旋轉等問題,將其封裝成kg-player SDK。
  • 【第2034期】全民K歌推流直播Web實踐
    例如,WXInlinePlayer使用的OpenH264解碼模塊,在iOS端和Android端有差異化的表現,在iOS端會對首幀進行額外解碼,導致第二段音頻每次都會包含第一段音頻,從而使得畫音不同步。對此,我們在邏輯層對iOS端的第一段音頻進行記錄,在audioSrc.start播放時減去第一段時長,使音頻時間軸整體前偏移首段音頻的長度,最終使音視頻保持同步。
  • 裴琳 · 微成長--web性能優化與前端工程
    ....任性的分割線web性能優化與前端工程 每個參與過開發企業級web應用的前端工程師或許都曾思考過前端性能優化方面的問題。我們有雅虎14條性能優化原則,還有兩本很經典的性能優化指導書:《高性能網站建設指南》、《高性能網站建設進階指南》。這些性能優化原則大概是在7年前提出的,對於web性能優化至今都有非常重要的指導意義。
  • 麼麼直播的音視頻技術實踐和優化
    2018年3月31日,「ZEGO Meetup 視頻直播+的技術實踐之道」第三期在上海成功舉辦,現場吸引了滿堂的直播行業從業者到場聆聽。會上,如預期一樣,麼麼直播前端團隊負責人黃銘新、即構科技資深技術專家和架構師冼牛、滬江CCTalk 音視頻架構師武海濱和塗圖TuSDK 研發技術總監王勝,這4位直播行業大咖給大家做了精彩分享。
  • 騰訊Web前端大會精彩回顧
    淘寶的Winter本來安排在接下來的開場發言,不過由於航班延誤,推遲到了最後。他其中提到的理念,Web與客戶端其實不是競爭,更多是融合合作,蠻有啟發性。技術總是大家追捧的,老師細心通俗的講解了PWA的核心技術,並用代碼展示了具體是如何操作實現的。通過實例向大家演示了如何從無到有創建一個PWA應用。最後介紹了PWA的一些限制。1.4 騰訊-盧嘉輝-QQ空間AMP 實戰
  • 蘑菇街直播實踐 架構師實踐日
    2.性能優化1)進房速度慢最開始都是收到消息後立即刷新視圖,在高並發下,這樣做會導致刷新過於頻繁,嚴重時會佔用一半的 CPU 資源,使得直播間非常卡頓;優化之後的做法是,定時輪詢消息池內部的消息,存在消息時才將消息從消息池取出,做相應的業務處理後再進行視圖刷新。對消息進行這樣四個流程的設計,是比較清晰合理的,既減少了直播間 VC 的耦合性,同時也提升了消息的性能。3)動畫
  • 酷我k歌2013官方免費下載|酷我K歌 3.2.0.6 官方正式版下載_太平洋...
    ,操控更流暢便捷3.海量伴奏資源,k歌更爽更盡興4.解決軟體崩潰bug,性能更穩定酷我K歌 2.4.0.0 更新說明:·全新界面升級,操控流暢便捷·新增引導動畫,新手上手更容易·支持伴奏升降調,高低音無所不能·播放、錄製模塊全新重構,性能更穩定酷我K歌2.3.0.6更新信息
  • Web 動畫幀率(FPS)計算
    (點擊上方公眾號,可快速關注)作者: 伯樂在線/chokcoco http://web.jobbole.com/93325
  • ZEGO Meetup 上海站 | 視頻直播+的技術實踐之道
    起起伏伏的是行業的風口和趨勢,穩步前進的是技術的實踐之道。在剛剛結束了ZEGO Meetup 北京站後,我們決定繼續前往上海,與上海的夥伴們一起探討視頻直播的技術與最佳實踐。本期活動,我們邀請了即構科技、麼麼直播、滬江CCtalk、塗圖TuSDK的4位音視頻技術大咖,他們將帶來:《麼麼直播音視頻實踐和優化》《連麥互動直播 X WebRTC》《使用RTC技術,搭建優秀的在線教育平臺》《深度學習和視頻特效的技術融合
  • 前端逐幀動畫性能探究和比較
    什麼是逐幀動畫?首先看一下 維基百科 中的定義:定格動畫,又名逐幀動畫,是一種動畫技術,其原理即將每幀不同的圖像連續播放,從而產生動畫效果。簡單的來說就是:以一定的速度切換幾張連續圖像,讓它動起來。人眼的物理性能能識別多少幀?
  • Web動畫
    因此,例如,與改變元素的文本顏色相比,改變元素的box-shadow將需要開銷大很多的繪圖操作。 改變元素的width可能比改變其transform要多一些開銷。您可以在動畫和性能指南中閱讀有關動畫性能考慮事項的更多內容,但是如果想要TL;DR,則堅持使用轉換和透明度改變,以及利用will-change。 如果想確切知道給指定的屬性設置動畫會觸發什麼效果,請查閱CSS 觸發器。
  • 直播中「周邊」系統的最佳實踐|架構師實踐日
    如果是禮物類型的消息,就可以進入支付邏輯,比如判斷餘額是否充足。如果足夠支付,就向聊天室裡送達一個禮物贈送成功的消息,客戶端隨機進行 UI 展現;如果不充足,則返回結算失敗的消息,然後引導客戶端調用支付寶或者微信的 sso 充值支付。打賞消息也可以理解為一種自定義類型的消息,只是相對於其他的消息多了一層支付的結算過程,而這些都可以在自定義服務端邏輯裡面完成。
  • 動畫行業新晉大殺器 還得看騰訊移動端動畫組件PAG!
    如今,短視頻應用百花齊放,為了吸引更多流量,動畫設計師和開發工程師往往為了製作奪人眼球,極具創意的動畫特效花費大量心血,但最終動畫需求交付上線的效率和質量,仍舊不盡如人意。問題出在哪裡?主要還是工具沒有選對!
  • 產品分析 | 面對新風口,全民k歌將如何構建自己的K歌生態
    其中全民k歌遙遙領先的原因,筆者認為主要如下:一是全民k歌注重用戶體驗,在k歌細節上不斷進行優化 不斷豐富功能和創新玩法,吸引大量用戶。二是背靠騰訊社交體系支持,用戶熟人留存性強。三是騰訊音樂旗下產品,其音樂版權數遠超唱吧。
  • lottie-web 動畫實現原理
    設計師使用 AE 製作動畫。通過 Lottie 提供的 AE 插件 Bodymovin 把動畫導出 JSON 數據文件。加載 Lottie 庫結合 JSON 文件和下面幾行代碼就可以實現一個 Lottie 動畫。<!
  • IVWEB玩轉wasm系列-純web視頻剪輯/轉換工具
    它利用web worker執行ffmpeg的js版,將本地的input.webm讀入後實現轉碼/裁剪的體驗還是比較流暢的。/ffmpeg_post.js-O3是編譯的優化等級,參數TOTAL_MEMORY和ALLOW_MEMORY_GROWTH設定了wasm需要開闢的內存和執行時內存超過TOTAL_MEMORY時允許自動擴容。
  • 螞蟻實時視頻通話技術和實踐
    ARTVCS:螞蟻實時視頻通話系統,從P2P的雙人視頻通話開始向多人視頻通話和連麥直播方向融合、演進。技術選型場景和核心需求基本明確,該選擇什麼技術路線呢?我們先回顧連麥互動直播場景,主播在直播過程中,(可能多位)嘉賓連線主播,進入聊天室,與主播進行視頻通話,其他粉絲觀看主播和嘉賓實時互動的視頻畫面。
  • 聊一聊前端性能與體驗的優化
    前言性能優化 ,每個工程師跑不掉的一個話題。這裡是本人總結的一些優化手法,希望對大家有所幫助,後續也會繼續更新。演示源碼和 PPT 無條件分享。演示 PPT (一定要看,超帥)橫屏觀看更佳:http://118.25.49.69:8086前端性能的影響前端性能的一個重要指標是頁面加載時間,不僅事關用戶體驗,也是搜尋引擎排名考慮的一個因素。
  • VUE項目性能優化實踐——通過懶加載提升頁面響應速度
    既然找到了原因,我們就開始著手優化,在前端對於需加載較大資源時,我們一般都採用懶加載的方式來優化效率。什麼是懶加載?懶加載也叫做延時加載,在網頁響應時不立刻請求資源,待頁面加載完畢或者按需響應時再加載資源,以達到提高頁面響應速度以及節省伺服器資源的謎底。
  • 為什麼2017年Web前端開發工程師薪資越來越高?
    事實上,前端工程師在做的是:1、在設計師和工程師之間創建可視化的語言;2、根據設計稿定義一組代表內容、品牌和功能的組件;3、為Web應用程式的框架、需求、可視化的語言和規格設定基準;4、根據設備、瀏覽器、屏幕、動畫來劃分web應用的工作劃分;5、用QA基準來保證指南來確保品牌忠誠度