移動端視訊轉序列圖片播放
專案所用5s的視訊,起初使用video標籤直接內嵌到頁面,看起來很正常。但是在安卓瀏覽器會彈出小窗播放,不支援視訊內嵌。
線上案例: https://mc.163.com/m/brain/
解決方案
將視訊轉化成序列幀,用JS控制img src的切換,視覺上達到和播放視訊一樣的效果。這個方法適用於短視訊,建議控制在5M以內。最終匯出的圖片會轉化成base64,然後以陣列的形式存放在一個JS檔案。如果視訊太大的話,匯出的圖片就會多,那麼存放base64的JS檔案也將會很大,這個要根據具體情況斟酌。
1、使用 Premiere 將視訊轉化成序列幀
選擇合適的尺寸,寬750會比較大,可選600,640。質量選擇50左右。輸出格式選擇JPEG,幀速率選擇12-15。5s的視訊,選擇12幀速率,匯出了60張:

2、使用node將匯出的圖片轉化成base64
將匯出的圖片轉化成base64,然後以陣列的形式存放在一個JS檔案,最終生成這個JS檔案。
目錄結構
|--img |--index.js
const fs = require('fs'); const toBase64 = foldername => { let fileNmaeArr = fs.readdirSync(foldername); let strBase64 = ""; fileNmaeArr.forEach((item, index, array) => { let path = foldername + '/' + item; let str = fs.readFileSync(path, { encoding: 'base64' }) if (index < array.length - 1) { strBase64 += '\"' + str + '\"' + ","; } else { strBase64 += '\"' + str + '\"'; let imgs = `var imgList = [${strBase64}]`; fs.writeFileSync('img.js', imgs); console.log("匯出成功!") } }) } toBase64('img')
執行 node index.js
匯出 img.js
3、JS切換img標籤的src,播放序列幀
ImgSequence
呼叫前,頁面要先預載入img.js。
<img src="" id="imgVideo">
var requestAnimFrame = (function() { return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } ) })() var ImgSequence = function() { var _class = function(opt) { this.container = opt.container; this.imgArr = []; this.isOver = false; this.nowpic = opt.nowpic; this.stopPicIndex = 0; this.speed = opt.speed || 12; this.oldpic = -1; this.isLoop = opt.isLoop === false ? false : true; } _class.prototype = { loop: function() { if (this.isOver) { return; } var ntime = +new Date; var diftime = ntime - this.stime; this.nowpic = Math.floor(diftime * this.speed * 0.001) + this.stopPicIndex; if (this.nowpic == this.imgArr.length) { this.stopPicIndex = 0; if (this.isLoop) { this.play(); } return; } requestAnimFrame(() => { if (+new Date - ntime > 100) { this.stopPicIndex = this.nowpic; this.play(); } else { this.loop(); } }); if (this.nowpic == this.oldpic) { return; } this.container.setAttribute("src", "data:image/jpg;base64," + this.imgArr[this.nowpic]); this.oldpic = this.nowpic; }, show: function() { if (window["imgList"]) { this.container.style.display = 'block'; this.imgArr = window["imgList"]; this.play(); } }, play: function() { this.nowpic = 0; this.oldpic = -1; this.stime = +new Date; this.stime += this.nowpic * 1000 / this.speed; this.container.setAttribute("src", "data:image/jpg;base64," + this.imgArr[this.nowpic + this.stopPicIndex]); this.loop(); }, onplay: function() { this.isOver = false; this.play() }, stop: function() { this.isOver = true; this.stopPicIndex = this.nowpic; } } return { init: function(opt) { return new _class(opt); } } }() var imgSequence = ImgSequence.init({ 'container': document.getElementById('imgVideo'),//必填 'speed': 12, //可選,每秒播放多少幀,預設12 ,小於imgList的長度 'isLoop': true //可選,預設true }) imgSequence.show() //初始化顯示並播放 imgSequence.stop() //暫停 imgSequence.onplay()//繼續播放