移動端canvas實現(xiàn)視頻截取圖片并下載為gif實例調(diào)研說明

需求說明

前端實現(xiàn)視頻截取片段,并轉(zhuǎn)換為gif圖片下載到本地

參考文檔

HTML5 CSS3 誘人的實例 :模仿優(yōu)酷視頻截圖功能
github antimatter15

結(jié)果說明

純前端通過canvas截幀并可以保存為gif形式當(dāng)前在移動端chrome、safari瀏覽器支持較好牲尺。

demo展示

圖片截圖
視頻截圖

canvas截圖圖片實例

  • 截取圖片
    在截取視頻之前疆柔,首先進(jìn)行了截取圖片的嘗試。截取圖片或者視頻主要使用了canvas的CanvasRenderingContext2D.drawImage()MDN說明該函數(shù)可以在canvas畫布上繪制圖像,繪制圖像后通過HTMLCanvasElement.toDataURL() 函數(shù)返回一個包含圖片展示的dataUrlMDN說明
this.canvas = document.createElement("canvas”);
 this.ctx = this.canvas.getContext("2d”);
 this.ctx.drawImage( this.img,0,0,this.Width, this.Height,0,0,this.Width,this.Height);
let dataUrl = this.canvas.toDataURL("image/png”);
  • 轉(zhuǎn)成gif下載
    轉(zhuǎn)成gif下載主要使用了jsgif中的如下代碼菇肃,引入了 如下JS文件
<script type="text/javascript" src="LZWEncoder.js"></script>
<script type="text/javascript" src="NeuQuant.js"></script>
<script type="text/javascript" src="GIFEncoder.js"></script>
<script type="text/javascript" src="b64.js"></script>

QQ20171121-192529@2x.png

這里需要注意的是encoder.addFrame(context);中傳遞的context參數(shù)拂玻,文檔中說或者是canvas元素酸些,或者是imageData形式。那么imageData.data類型要怎么獲取到呢檐蚜?通過函數(shù)CanvasRenderingContext2D.getImageData()MDN說明,該函數(shù)可以返回一個imageDataMDN說明對象魄懂,ImageData.data是[Uint8ClampedArray]類型,描述了一個一維數(shù)組闯第,包含以 RGBA 順序的數(shù)據(jù)市栗,數(shù)據(jù)使用
(包含)的整數(shù)表示。將ImageData.data傳入encoder.addFrame即可,這樣就實現(xiàn)了canvas截圖后并將其轉(zhuǎn)成gif形式填帽。

let context = this.ctx.getImageData(0,0,this.Width,this.Height).data
            var encoder = new GIFEncoder();
           encoder.setRepeat(0); //0  -> loop forever
                                                  //1+ -> loop n times then stop
            encoder.setDelay(10); //這里單張圖片并不需要用到蛛淋,用于設(shè)置幀數(shù)間隔時間
            encoder.start();
            encoder.setSize(640, 430); //此處應(yīng)和canvas獲得的圖片尺寸一致
            encoder.addFrame(context, true);            
            encoder.finish();
            encoder.download("download.gif");
        
  • gif下載
    單張圖片是完全沒有必要下載成gif的,這個主要是為了視頻截取而準(zhǔn)備篡腌,在GIFEncoder.js中褐荷,主要采用如下代碼實現(xiàn)了圖片下載。
ar templink = document.createElement("a");
templink.download=filename;//filename = ‘download.gif'
templink.href= URL.createObjectURL(new Blob([new Uint8Array(out.bin)], {type : "image/gif" } ))
console.log(templink)
templink.click()

在上面代碼中templink得到的是如下一個超鏈接標(biāo)簽嘹悼,在chrome中執(zhí)行click()會直接下載該文件叛甫,safari則會打開一個新的頁面
<a download="download.gif" href="blob:http://xxxxxx:3023/12465504-7074-466a-8828-29ee44848612"></a>

上面創(chuàng)建下載鏈接主要是采用了URL.createObjectURL()對象MDN說明

MDN上說該靜態(tài)方法會創(chuàng)建一個 [DOMString]其中包含一個表示參數(shù)中給出的對象的URL。這個 URL 的生命周期和創(chuàng)建它的窗口中的 [document]綁定杨伙。這個新的URL 對象表示指定[File]對象或 [Blob]對象

Blob對象表示不可變的類似文件對象的原始數(shù)據(jù)其监。Blob表示不一定是JavaScript原生形式的數(shù)據(jù)。 File 接口基于Blob限匣,繼承了 blob的功能并將其擴(kuò)展使其支持用戶系統(tǒng)上的文件對象

這里對Blob的理解并不深刻抖苦,上面獲取的href地址從測試結(jié)果來看,uc米死、QQ等瀏覽器是不支持其打開預(yù)覽下載的锌历。所以這個合成gif并下載的功能在chrome和safari可支持使用。

canvas截取視頻實例

截取視頻和截取圖片的區(qū)別在于視頻是多次截取拼成gif圖片哲身,在截圖辩涝、轉(zhuǎn)成GIF、下載與截取圖片所用核心代碼基本一致勘天,差別只在于視頻需要設(shè)置起始于結(jié)束時間怔揩,該時間段內(nèi)setInterval循環(huán)繪制canvas圖片,循環(huán)繪制后脯丝,生成imageData.data的數(shù)組商膊,該數(shù)組循環(huán)調(diào)用encoder.addFrame(context, true)方法。
事件主要代碼如下:

var draw = new drawVideo($('video')[0]);
document.getElementById('j_begin').addEventListener('click',()=>{
    document.getElementById('video').currentTime = startTime;
    document.getElementById('video').play();
    var time = setInterval(()=>{
        draw.paint();
        document.getElementById('video').play(); //每次繪制完需要將視頻播放

        if(document.getElementById('video').currentTime > endTime){//超過當(dāng)前結(jié)束時間停止繪制canvas
            console.log('stop');
            clearInterval(time);

            var encoder = new GIFEncoder();
            encoder.setRepeat(0); //0  -> loop forever
            //1+ -> loop n times then stop
            encoder.setDelay(300); //這個時間的設(shè)置會影響gif展現(xiàn)時的速度
            encoder.start();
            encoder.setSize(1280, 720);//此處高度應(yīng)為視頻寬高
            draw.result.forEach((ele,index)=>{
                encoder.addFrame(ele, true);//循環(huán)添加canvas的每一幀合成gif
            })
            encoder.finish();
            encoder.download("download.gif");


        }
        
    },1500);//1500秒為循環(huán)時間宠进,如果時間設(shè)置太短看晕拆,手機(jī)上卡頓特別明顯,時間設(shè)置太長材蹬,生產(chǎn)的gif不流暢实幕。
    
    
},false)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市堤器,隨后出現(xiàn)的幾起案子昆庇,更是在濱河造成了極大的恐慌,老刑警劉巖闸溃,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件整吆,死亡現(xiàn)場離奇詭異拱撵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)表蝙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門拴测,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人府蛇,你說我怎么就攤上這事集索。” “怎么了欲诺?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵抄谐,是天一觀的道長渺鹦。 經(jīng)常有香客問我扰法,道長,這世上最難降的妖魔是什么毅厚? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任塞颁,我火速辦了婚禮,結(jié)果婚禮上吸耿,老公的妹妹穿的比我還像新娘祠锣。我一直安慰自己,他們只是感情好咽安,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布伴网。 她就那樣靜靜地躺著,像睡著了一般妆棒。 火紅的嫁衣襯著肌膚如雪澡腾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天糕珊,我揣著相機(jī)與錄音动分,去河邊找鬼。 笑死红选,一個胖子當(dāng)著我的面吹牛澜公,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喇肋,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼坟乾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蝶防?” 一聲冷哼從身側(cè)響起甚侣,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慧脱,沒想到半個月后渺绒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年宗兼,在試婚紗的時候發(fā)現(xiàn)自己被綠了躏鱼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡殷绍,死狀恐怖染苛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情主到,我是刑警寧澤茶行,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站登钥,受9級特大地震影響畔师,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牧牢,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一看锉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧塔鳍,春花似錦施符、人聲如沸女阀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽普筹。三九已至求橄,卻和暖如春赋续,著一層夾襖步出監(jiān)牢的瞬間干奢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工郑兴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留犀斋,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓情连,卻偏偏與公主長得像叽粹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子却舀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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