摘要:考慮到只適合在單位時間內繪制少量彈幕,這對于我們播放器來說明顯是不合需求的。比如說直播播放器模式和視頻播放器模式的優化細節又有點不一樣,還有高級彈幕的處理圖片,圖形等。。
前言
大家年前好,馬上就要元旦了,在很久沒有寫文章之后,想到這篇文章將會成為本人今年的
絕響也是有點蛋疼。不過也好,畢竟本人算不得什么勤快的生物,而且比起那些大神來說也差遠了,就作為自己工作半年后的一次沉淀算了。
文中有些思想可能不見得是最好的解決辦法,大神們請輕噴。
這個項目本來是我自己準備的一個開源插件,但由于上班寫這個的過程中被老板發現了(∑(O_O;)),就說把這個東西寫成公司用的吧,然后,然后開源就GG了(我了個大擦,我說我這個是自己的項目也沒用),雖然說也可以偷偷放出來,但畢竟我還在職,就原諒我這次沒辦法把代碼放出來吧。我會在講解過程中盡可能講解詳細的。以上。。。。開始一波交♂易吧,騷年們(手動滑稽)
demo : 我是你親愛的demo (彈幕數2000)
準備至少需要有canvas和js的編程經驗,然后養成一個好的代碼習慣(不然一段時間后你都不知道你自己干了什么),下面講解的內容不會涉及到具體程序和功能的編寫,更多地是在強調性能優化這方面,完全當教程看的可以略過了。。。大神請隨意
一. 選取合適的方案其實實現彈幕的方式可以有多種,比如說用dom和canvas實現都是可以的,但我們這里選取的是canvas來繪制彈幕。
考慮到dom 只適合在單位時間內繪制少量彈幕 ,這對于我們播放器來說明顯是不合需求的。其實去過B站的都知道,因為播放器有時會出現短時間內的“彈幕轟炸”,你想想如果是用dom來寫,頁面瞬間創建幾百個、甚至上千個element。。。那酸爽,簡直讓人不敢相信。。。所以說,dom只適用于那些對時間把握要求不那么高的項目,因為你可以通過控制單位時間內彈幕的繪制數量來達到緩解性能的目的。
使用canvas好處有幾點: 1.不用頻繁的操控dom元素 2.有強大的api,操作簡單 3.在移動設備上也能比較高性能地運行 4.強化你的代碼組織能力(如何更好地分離功能什么的,而不是加個css3動畫就了事)二. 盡可能地多考慮移動設備和PC的差異
其實最簡單的就體現在api上,比如說實現全屏模式,其實android和ios到目前為止都還是不支持元素全屏的,所以說你這里要考慮 requestFullScreen 不能用的情況下,對移動設備的降級處理。還有一點就是移動設備和PC的性能差距還是有點大的,這就需要你考慮在某些消耗性能的功能和用戶體驗之間做些取舍。
三. 在特效和性能之間做出平衡其實這里也是考慮各個主流瀏覽器的性能差異,對某些功能做出適當的調整。其實在使用canvas text API的時候,有些效果的使用是會大大地加重瀏覽器的負擔,比如說:文字陰影、漸變、變換等;不見得每個瀏覽器都能很迅速的繪制出你想要的效果,即使在你自己看起來不怎么需要時間。 這里,chrome內核的瀏覽器表現極其優秀,反而讓我一臉懵逼的是火狐。。在這我整理了一些主流瀏覽器在繪制方面的差異(參考數據):
upperNum : { //當彈幕數超過一定數額時,取消文字的全局特效(如陰影等) //ps:火狐爸爸不給力啊,向谷歌勢力低頭 "firefox" : 500, "safari" : 800, "chrome" : 2000, "ie" : 900, "edge" : 1100 }, scale : 1, rotate : 0
從上面可以看出,其實瀏覽器性能之間的差異還是有的,此時就需要我們根據數據的多少來調整特效的展現,你可以分別用火狐和chrome打開demo頁面看效果
四. 減少api的操作次數(主要部分)如全局文字顏色等一些能在循環體外設置的api,就千萬不要放到循環體內部去給每個彈幕多帶帶設置(除非全局樣式發生了改變)。
還有就是優化循環,沒錯,就是優化循環。。。。。當你的彈幕池達到數千甚至上萬的時候,你一個循環就能浪費掉許多時間,其實有些條件達到的時候你是沒必要再進行循環了的。對于視頻彈幕來說,我們需要的只是 “把某一個時間點的所有彈幕進行一次繪制”,這樣我們就已經確立了一部分優化原則:在當前播放時間之前的彈幕我不需要管,在當前播放時間之后的彈幕我不需要管。至于怎么實現,我們可以改變for循環的start下標來達到忽略前面的彈幕,可以通過判斷當前彈幕的時間和播放器時間的大小來達到跳出循環的目的。 在下面的循環體代碼(部分)就可以看出來優化的操作
if(!this.Canvas.globalStyleHasChanged) Canvas.setBaseTextStyle(cxt); //設置文字基本樣式,我們在這里設置好統一樣式 //我這里是彈幕循環 for( var i = DMsystem.idx, DM; DM = DMs[i++]; ){ if( DM.currentTime > currentTime ){ break; } if( DM.currentTime < currentTime && !DM.isDisplaying ){ DM.hasShowed = true; continue; } DMsystem.refresh(DM); //更新位置 Canvas.drawDM(cxt,DM,options); //繪制 DMsystem.recovery(DM,currentTime); //判斷彈幕是否顯示完畢并回收相關行 }五. 避免某些誤區
其實在這一版之前我還寫過1.0版,不過在移動設備上的性能太糟糕所以舍棄了(你們可以用手機打開這一版demo看看效果,性能其實還是可以的),原因是我把每一條彈幕都new了一個實例。。。當時忙著js的偽面向對象編程實踐:“彈幕嘛,每一條彈幕都應該是一個成熟的個體,不僅有自己獨特的顏色,還有所在的位置.....”。然后呢?當我把彈幕數調整為5000的時候---然后就沒有然后了。。。。too young too simple,sometimes naive.....瀏覽器直接炸掉了。。。。。所以說我們在面向對象的時候要考慮哪些才是真正應該new的。。(盡管看起來好像就我自己有點蠢....)
以上就是要寫的所有的東西了,盡管我知道各位看起來可能有點不那么方便(畢竟代碼少,而且講得很籠統),當你自己開始寫的時候就會明白項目中大部分東西都很簡單(各種api的調用),真正麻煩的還是性能的優化,以及對設備和瀏覽器差異的處理。。如果不懂的話歡迎留言詢問,我這個還不是最終版,接下來還要加入模式的切換。。。比如說 直播播放器模式(live)和視頻播放器模式(player)的優化細節又有點不一樣,還有高級彈幕的處理(圖片,圖形等)。。后續有空閑時間可能會繼續更新,最后再說一次------------提前祝大家新年快樂
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86689.html
摘要:考慮到只適合在單位時間內繪制少量彈幕,這對于我們播放器來說明顯是不合需求的。比如說直播播放器模式和視頻播放器模式的優化細節又有點不一樣,還有高級彈幕的處理圖片,圖形等。。 前言 大家年前好,馬上就要元旦了,在很久沒有寫文章之后,想到這篇文章將會成為本人今年的絕響也是有點蛋疼。不過也好,畢竟本人算不得什么勤快的生物,而且比起那些大神來說也差遠了,就作為自己工作半年后的一次沉淀算了。 文中...
摘要:上一篇前端常用插件工具類庫匯總上內容摘要動畫庫滾動庫輪播圖滾屏彈出框消息通知下拉框級聯選擇器顏色選擇器時間日期處理表單驗證分頁插件本篇延續上一篇的內容繼續給大家帶來一系列關于前端插件工具類的內容。 showImg(https://segmentfault.com/img/bVbjsMh?w=900&h=383); 前言 對本文感興趣可以先加個收藏,也可以轉發分享給身邊的小伙伴,以后遇到...
閱讀 3806·2023-04-25 19:07
閱讀 3553·2021-11-22 12:02
閱讀 3137·2021-10-12 10:11
閱讀 3907·2021-09-03 10:49
閱讀 2891·2019-08-30 13:21
閱讀 2997·2019-08-30 11:14
閱讀 2088·2019-08-29 15:40
閱讀 2872·2019-08-28 18:29