用canvas實現(xiàn)視頻播放與彈幕功能

寫在最前

本次分享一下使用canvas來進行視頻播放并且添加彈幕功能。

歡迎關注我的博客,不定期更新中——

效果圖

示例源碼見:源碼地址
[圖片上傳失敗...(image-63478a-1512320133960)]

可以看到上方為一段視頻奇唤,下面是用canvas來重新繪制的視頻,并且支持動態(tài)的添加彈幕伦意。

canvas載入視頻

canvas中的drawImage方法繪制圖片所需要的數(shù)據(jù)源不單單是某張圖片咒唆,同樣可以是使用視頻的某一幀來進行繪制。就像這樣:

var video = document.getElementById('video')
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ctx.drawImage(video, 0, 0, width, height);//當視頻開始播放后觸發(fā)這個方法可以開始繪制視頻

為什么通過canvas繪制視頻茶鹃?

因為canvas提供了getImageData && putImageData方法使得操作者可以動態(tài)得來更改每一幀圖像的顯示狀態(tài)涣雕,如果你知道它應該怎么變:)

比如像MDN中提到的可以對上面這段視頻中的黃色背景進行色調(diào)的變化:mdn示例地址

this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
    let l = frame.data.length / 4;

    for (let i = 0; i < l; i++) {
      let r = frame.data[i * 4 + 0];
      let g = frame.data[i * 4 + 1];
      let b = frame.data[i * 4 + 2];
      if (g > 100 && r > 100 && b < 43)
        frame.data[i * 4 + 3] = 0; //將視頻黃色部分的透明度進行了變化
    }
    this.ctx2.putImageData(frame, 0, 0);

視頻中效果截圖如下:


image

更多關于canvas的圖像操作可以參考下面這兩篇文章:

基于canvas的圖像處理可以實現(xiàn)很強大的功能,比如濾鏡啊之類的~

騰訊的Aolly Team團隊出品的AlloyImage - 基于HTML5技術的專業(yè)圖像處理庫就是個很好的范例闭翩。作者就搞不明白那些高深的東西了挣郭,什么拉普拉斯算子,各種算子:)

彈幕功能

彈幕功能分為兩部分:

  • 監(jiān)聽新彈幕的推送
  • 渲染彈幕到頁面

監(jiān)聽新彈幕的推送

通過維護一個彈幕數(shù)組來實時去渲染每一個彈幕字條的應有位置疗韵。而何時更新這個數(shù)組兑障,為了解耦作者使用了發(fā)布訂閱的方式來進行數(shù)組的更新。當然這里并不是一定要使用這種模式蕉汪,只不過作者剛剛學習完所以拿來用一下而已疯汁。千萬別噴我:)

var Event = (function(){
    var list = {},
        listen,
        trigger,
        remove;
        listen = function(key,fn){ /收集監(jiān)聽事件
            if(!list[key]) {
                list[key] = [];
            }
            list[key].push(fn);
        };
        trigger = function(){/觸發(fā)后依次執(zhí)行回調(diào)
            var key = Array.prototype.shift.call(arguments),
                 fns = list[key];
            if(!fns || fns.length === 0) {
                return false;
            }
            for(var i = 0, fn; fn = fns[i++];) {
                fn.apply(this,arguments);
            }
        };
        remove = function(key,fn){
            var fns = list[key];
            if(!fns) {
                return false;
            }
            if(!fn) {
                fns && (fns.length = 0);
            }else {
                for(var i = fns.length - 1; i >= 0; i--){
                    var _fn = fns[i];
                    if(_fn === fn) {
                        fns.splice(i,1);
                    }
                }
            }
        };
        return {
            listen: listen,
            trigger: trigger,
            remove: remove
        }
})();
//調(diào)用方式
Event.listen('data', addNewWord)

$('#submit').click(function() { //點擊發(fā)送后便觸發(fā)data事件
  var data = $('input').val()
    Event.trigger('data', {
      value: data,
    })
})

function addNewWord (data) {
    var newWord = new Barrage(this.canvas, this.ctx, data) //構建新的彈幕實例
    wordObj.push(newWord)
},

渲染彈幕到頁面

聲明了一個彈幕的構造函數(shù)绽族,內(nèi)部包含了其各種屬性并且在原型鏈中添加了draw方法來進行繪制:

function Barrage(canvas, ctx, data) {
    this.width = canvas.width
    this.height = canvas.height
    this.ctx = ctx
    this.color = data.color || '#'+Math.floor(Math.random()*16777215).toString(16) //隨機顏色
    this.value = data.value
    this.x = this.width //x坐標
    this.y = Math.random() * this.height
    this.speed = Math.random() + 0.5
    this.fontSize = Math.random() * 10 + 12
}
Barrage.prototype.draw = function() {
        if(this.x < -200) {
            return
        } else {
            this.ctx.font = this.fontSize + 'px "microsoft yahei", sans-serif';
            this.ctx.fillStyle = this.color
            this.x = this.x - this.speed
            this.ctx.fillText(this.value, this.x, this.y)
        }
}

最后

慣例po作者的博客碘橘,不定時更新中——
有問題歡迎在issues下交流阔籽。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市驹马,隨后出現(xiàn)的幾起案子竞漾,更是在濱河造成了極大的恐慌眯搭,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件业岁,死亡現(xiàn)場離奇詭異,居然都是意外死亡寇蚊,警方通過查閱死者的電腦和手機笔时,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仗岸,“玉大人允耿,你說我怎么就攤上這事“遣溃” “怎么了较锡?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盗痒。 經(jīng)常有香客問我蚂蕴,道長,這世上最難降的妖魔是什么俯邓? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任骡楼,我火速辦了婚禮,結果婚禮上稽鞭,老公的妹妹穿的比我還像新娘鸟整。我一直安慰自己,他們只是感情好朦蕴,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布篮条。 她就那樣靜靜地躺著,像睡著了一般吩抓。 火紅的嫁衣襯著肌膚如雪涉茧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天琴拧,我揣著相機與錄音降瞳,去河邊找鬼。 笑死蚓胸,一個胖子當著我的面吹牛挣饥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沛膳,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼扔枫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锹安?” 一聲冷哼從身側響起短荐,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤倚舀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忍宋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痕貌,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年糠排,在試婚紗的時候發(fā)現(xiàn)自己被綠了舵稠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡入宦,死狀恐怖哺徊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乾闰,我是刑警寧澤落追,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站涯肩,受9級特大地震影響轿钠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宽菜,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一谣膳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铅乡,春花似錦继谚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挚赊,卻和暖如春诡壁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荠割。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工妹卿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔑鹦。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓夺克,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嚎朽。 傳聞我的和親對象是個殘疾皇子铺纽,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容