从Flash到MP4,爱奇艺奇秀直播礼物特效精进之路
虛擬禮物是主播和觀眾互動的重要道具,也是主播很大一部分的收入來源。當(dāng)刷滿足夠禮物數(shù)量時(shí),直播間就會飛出炫酷的禮物動效,它既能刺激主播更好地直播,也能滿足用戶在虛擬世界的榮譽(yù)感,越有誠意的禮物會觸發(fā)越精彩的禮物動效,這也加深了主播和用戶之間的羈絆。
隨著直播平臺的發(fā)展,設(shè)計(jì)人員不斷創(chuàng)作出精美的禮物動效,相應(yīng)的,動效加載時(shí)長和文件體積逐漸變大,而開發(fā)人員要需要能夠吃下這些負(fù)擔(dān),在保證動效播放的高效和順滑的同時(shí),不給用戶機(jī)器帶來負(fù)擔(dān)也不給設(shè)計(jì)人員的創(chuàng)作帶去局限,這便是我們本文需要考慮的幾個(gè)難點(diǎn)。本文將以奇秀PCweb端為例,從動效效果、性能、研發(fā)效率、兼容性等多角度談?wù)劧Y物動效的發(fā)展。
演進(jìn)之路
禮物動效的實(shí)現(xiàn)格式可以有很多種,不同文件格式之間各有利弊,從業(yè)務(wù)角度出發(fā)選取相對較優(yōu)的方案是我們的目的。整條演進(jìn)路上,我將帶領(lǐng)大家從Flash時(shí)代開始了解多種動效格式,希望在了解多種方案后,你能找到適合自己業(yè)務(wù)的較優(yōu)方案。
動效格式
●過去的王者:Flash
●動圖:GIF、APNG、Webp
●開源和自研:Lottie、SVGA、IXD(自研)
●視頻:MP4
Flash時(shí)代
奇秀平臺剛開始上線的時(shí)候,視頻行業(yè)在網(wǎng)頁端還是Flash的天下,基于Flash的流媒體播放器幾乎是唯一選擇,拿它實(shí)現(xiàn)動效制作也是很自然的事情,對設(shè)計(jì)師來說使用Adobe Flash CC導(dǎo)出Flash動畫也是常規(guī)操作。
沒多久,Flash式微,html5技術(shù)飛速發(fā)展,替換Flash變成迫切需要做的事情。彼時(shí)團(tuán)隊(duì)內(nèi)部出現(xiàn)兩種實(shí)現(xiàn)方向:
●APNG動圖
●自研新的動效方案
APNG動圖
APNG(Animated Portable Network Graphics)誕生于2004年,是一個(gè)基于png的位圖動畫格式,擴(kuò)展方法類似主要用于網(wǎng)頁的GIF 89a,仍對傳統(tǒng)PNG保留向下兼容,2017年主流瀏覽器幾乎都已經(jīng)支持APNG。由于當(dāng)時(shí)平臺上移動端一直是使用圖片序列生成的APNG/Webp作為動效資源,為了保持多端的統(tǒng)一,PCweb端也開始嘗試使用動圖作為后續(xù)的動效格式。
綜合對比文件大小、效果以及瀏覽器兼容性,選擇使用APNG作為新的動效格式。單純使用<img>標(biāo)簽直接展示APNG會遇到如下幾個(gè)問題:
●小部分瀏覽器不支持播放APNG
●為了動效播放連貫性,需要預(yù)加載APNG
●APNG播放開始、過程、結(jié)束等時(shí)間點(diǎn)不受控
為了解決這幾個(gè)問題,我們開始研究APNG的文件格式結(jié)構(gòu),包括PNG的結(jié)構(gòu)和擴(kuò)展的acTL(動畫控制塊)、fcTL(幀控制塊)、fdAT(幀數(shù)據(jù)塊)。
基于對APNG的了解,對一些開源方案進(jìn)行了調(diào)研測試,最終決定使用apng-js幫助我們解決上述幾個(gè)問題。使用apng-js解析APNG,可以得到APNG的很多信息,包括寬高、幀數(shù)、播放時(shí)長,以及播放過程中的每一幀畫面,有了這些再配合canvas便可以將APNG繪制和控制起來。下面是設(shè)計(jì)的播放器參數(shù)的結(jié)構(gòu):
{?src:?string,?// 動效地址selector:?string????????????// dom容器playStart:?()?=>?void,?// 動畫開始playProgress:?(index:?number, totalTime:?number, remainTime:?number) =>?void,?// 動畫過程playEnd:?()?=>?void,?// 動畫結(jié)束 };上述設(shè)計(jì)以及播放、暫停、重播等使用方法,基本滿足對APNG播放的控制,且在后續(xù)業(yè)務(wù)中也可直接實(shí)現(xiàn)支持音效禮物,只要在start處讀配置播放對應(yīng)的音頻資源,end處刪除音頻即可。為了提高動效播放的連貫性,在解析APNG后會將解析出的數(shù)據(jù)存入indexedDB,后面在播放同一動效時(shí)便可省去下載和格式解析的耗時(shí)。
這種方案對于設(shè)計(jì)來說也很方便,AE做好動畫后,使用格式工具和插件直接導(dǎo)出動圖即可。但是后面也發(fā)現(xiàn)了該方案的弊端,平臺對動效的要求越來越高,越酷炫的動效體積越大,很多復(fù)雜動效甚至達(dá)到5、6M。
自研IXD
后Flash時(shí)代,另一部分同學(xué)開始了動效自研的路子。APNG的本質(zhì)是對PNG格式的擴(kuò)展,除了向下兼容的IDAT(圖像數(shù)據(jù)塊)塊外,多了很多fdAT(幀數(shù)據(jù)塊),每一塊都是完整的圖像,每多一幀就會做一張位圖的大小。如果每一數(shù)據(jù)塊不是完整位圖,而是圖集素材,且數(shù)據(jù)塊表示素材的位置、寬高、縮放等各種信息,那么素材復(fù)用率會極高,再輔以對應(yīng)的解析,那么整體文件大小也會降低很多。
按照該思路去實(shí)現(xiàn),封裝了自研的IXD格式,原本10M的PNG序列可以被拆解壓縮到1M以內(nèi),動效效果幾乎沒有收到影響。
對于使用端,只需要支持二進(jìn)制數(shù)據(jù)和PNG位圖的處理,再按照設(shè)定的格式解析數(shù)據(jù)塊動態(tài)去渲染每一幀即可。對于開發(fā)人員,我們同步配套了web端SDK。
為了方便設(shè)計(jì)師生產(chǎn),也配套開發(fā)了動效編輯器,將素材導(dǎo)入到工具中,通過復(fù)用素材和組合效果的方式,支持疊加多個(gè)圖層,最終導(dǎo)出IXD文件。對于有動態(tài)數(shù)據(jù)的動效,也支持變量占位,開發(fā)人員按照占位符取值,使得同一動效不同用戶看到的各不一樣。
同期市面上也出現(xiàn)了Airbnb的Lottie和YY的SVGA方案:
●Lottie需要AE安裝Bodymovin插件導(dǎo)出JSON文件給開發(fā)同學(xué)使用,有興趣的同學(xué)可以去了解下。
●SVGA也提供了AE插件,它做的事情其實(shí)和IXD類似。SVGA從AE源文件里提取素材,并將素材在時(shí)間軸里的表現(xiàn)(位移、旋轉(zhuǎn)、縮放等)導(dǎo)出,各端parser負(fù)責(zé)將這些還原到畫布上。它比IXD優(yōu)秀的點(diǎn)在于,提供了IOS、Android端的解析SDK。
目前我們有APNG方案和IXD方案,包括市面上的SVGA方案,從播放可控到文件大小都有了一定的解決方案,似乎已經(jīng)可以告一段落了。但這幾個(gè)方案依舊有各自的缺陷:
MP4
有沒有既能盡量保證AE動效,也能保證文件體積小的方案呢?有,用MP4!肯定會有人以為我在開玩笑,MP4都不支持透明,如何能夠用來承擔(dān)直播動效呢。我們先了解下透明是什么:圖像的透明使用Alpha通道表示,即RGBA里的A,該通道是一個(gè)8位灰度通道,由256級灰度來記錄圖像中的透明信息。說白了透明和RGB一樣都是顏色信息,雖然MP4不支持透明通道,只要想辦法給它展示出來就好了吧!還是canvas技術(shù),只要我們可以用canvas把透明視頻畫出來就可以了。
通過和設(shè)計(jì)同學(xué)溝通,也參考了網(wǎng)絡(luò)上的文章和討論,最終決定將動效以上下同步的兩塊視頻拼接而成。上面的視頻保留原始的RGB信息,下面的視頻將A信息用黑白來表示,當(dāng)MP4播放的時(shí)候分別讀取上下兩塊視頻進(jìn)行拼接,得到完整了RGBA像素信息,然后繪制在目標(biāo)畫布上。
代碼很簡單,canvas入門的同學(xué)應(yīng)該都可以寫出來:
// 繪制視頻 buffer.drawImage(video,?0,?0, width, height *?2); // 讀取上下視頻圖像數(shù)據(jù) let?imageData = buffer.getImageData(0,?0, width, height).data; let?alphaData = buffer.getImageData(0, height, width, height).data; // 塞alpha通道 for?(let?i =?3, len = imageData.length; i < len; i = i +?4) {imageData[i] = alphaData[i-1]; } // 繪制canvas output.putImageData(image,?0,?0,?0,?0, width, height);本以為一切都特別順利,結(jié)果進(jìn)行性能測試發(fā)現(xiàn)動效繪制時(shí)CPU暴漲,根本無法投入生產(chǎn)。原因其實(shí)看代碼也能發(fā)現(xiàn),在視頻播放過程中密集遍歷處理像素點(diǎn),計(jì)算頻率太高,所以CPU暴漲。既然單純canvas2d不行,我們就打算試試性能更好的WebGL。WebGL(Web Graphics Library)基于OpenGL,可以為HTML5 Canvas提供硬件3D加速渲染,也可以借助系統(tǒng)顯卡來在瀏覽器里更流暢地展示3D場景和模型。WebGL里的概念很多,有scene、camera、texture等,這里不會一一介紹,有興趣的同學(xué)可以去了解下。在實(shí)現(xiàn)中為了便捷,我們借助Three.js來實(shí)現(xiàn)功能,利用THREE.ShaderMaterial自定義的著色器去處理,以下是核心代碼:
gl_FragColor?= vec4(texture2D(texture, vec2(vUv.x,?0.5?+ vUv.y/2.)).rgb,texture2D(texture, vec2(vUv.x, vUv.y/2.)).r );經(jīng)過性能測試和對比,動效播放時(shí)的CPU使用率顯著降低:
總結(jié)
通過對以上各種方案的分析,從實(shí)際效果、資源大小、成本的角度我們得出以下表格:
我們的場景主要是直播間的禮物動效,暫時(shí)沒有什么動效的用戶交互需要,因此我們選擇讓設(shè)計(jì)同學(xué)充分發(fā)揮才能的MP4方案,設(shè)計(jì)同學(xué)無需學(xué)習(xí)第三方插件,也不用考慮資源大小而被迫抽幀導(dǎo)致降低動效質(zhì)量。
我們堅(jiān)持認(rèn)為在禮物動效制作方面,MP4的是未來的大趨勢,視頻編解碼技術(shù)也在不斷發(fā)展,H.265、H.266,視頻文件體積將會不斷縮小,用戶等待的時(shí)長減少和帶寬節(jié)省都是很不錯(cuò)的收益。
后續(xù)我們將繼續(xù)深入MP4方案,在格式解析和動態(tài)素材占位上下功夫,嘗試參照IXD的方案將配置信息寫到文件中,創(chuàng)建一個(gè)新的BOX塞入MP4文件里,播放時(shí)候先取這個(gè)BOX讀取配置信息,然后和后續(xù)的視頻幀播放時(shí)結(jié)合起來達(dá)到實(shí)現(xiàn)動態(tài)素材的效果。也將繼續(xù)研究WebGL,尋求更加高效的渲染方式,爭取進(jìn)一步提高播放性能。
也許你還想看
干貨 | 奇秀直播連麥技術(shù)探索
愛奇藝奇秀直播 - 千萬級黑產(chǎn)風(fēng)控平臺搭建
?掃一掃下方二維碼,更多精彩內(nèi)容陪伴你!
總結(jié)
以上是生活随笔為你收集整理的从Flash到MP4,爱奇艺奇秀直播礼物特效精进之路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bt种子php啥格式的,bt种子是什么意
- 下一篇: [转]关于PSP的3.52 M33-2自