引言
本文建立WebApp在微信內(nèi)置瀏覽器上顯示效果的白皮書。
一、先了解幾個(gè)屬性
1. HTML <video> poster 屬性
實(shí)例
帶有預(yù)覽圖(海報(bào)圖片)的視頻播放器:
<video controls poster="/images/w3school.gif">
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
所有主流瀏覽器都支持 poster 屬性。
注釋:Internet Explorer 8 以及更早的版本不支持 <video> 標(biāo)簽。
定義和用法
poster 屬性規(guī)定視頻下載時(shí)顯示的圖像,或者在用戶點(diǎn)擊播放按鈕前顯示的圖像。
如果未設(shè)置該屬性,則使用視頻的第一幀來(lái)代替。
poster 屬性是 HTML 5 中的新屬性。
<video poster="URL">
URL可能的值:
- 絕對(duì) URL - 指向另一個(gè)網(wǎng)站(比如 href="http://www.example.com/poster.jpg")
- 相對(duì) URL - 指向網(wǎng)站內(nèi)的文件(href="poster.jpg")
在微信瀏覽器里面使用video標(biāo)簽,會(huì)自動(dòng)變成全屏,改成下面就好了,起碼可以在video標(biāo)簽之上加入其他元素。
<video id="videoID" webkit-playsinline="true" x-webkit-airplay="true"
playsinline="true" x5-video-player-type="h5" x5-video-player-fullscreen="true"
width="100%" height="100%" preload="auto" poster="" src="">
</video>
還有個(gè)問(wèn)題,在android的微信里面,就算加上了上面的屬性,還會(huì)出現(xiàn)上下有黑邊,不能全屏的問(wèn)題。
解決辦法:給video加上object-fit: fill的style屬性。
style="object-fit:fill"
HTML5 video 移動(dòng)端填坑記
<video id="video"
style="object-fit:fill"
autoplay
webkit-playsinline
playsinline
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
x5-video-orientation="portraint"
src="video.mp4" />
</video>
<!--
object-fit: fill 視頻內(nèi)容充滿整個(gè)video容器
poster:"img.jpg" 視頻封面
autoplay: 自動(dòng)播放
auto - 當(dāng)頁(yè)面加載后載入整個(gè)視頻
meta - 當(dāng)頁(yè)面加載后只載入元數(shù)據(jù)
none - 當(dāng)頁(yè)面加載后不載入視頻
muted:當(dāng)設(shè)置該屬性后,它規(guī)定視頻的音頻輸出應(yīng)該被靜音
webkit-playsinline playsinline: 內(nèi)聯(lián)播放
x5-video-player-type="h5" : 啟用x5內(nèi)核H5播放器
x5-video-player-fullscreen="true" 全屏設(shè)置。ture和false的設(shè)置會(huì)導(dǎo)致布局上的不一樣
x5-video-orientation="portraint" :聲明播放器支持的方向,可選值landscape 橫屏,portraint豎屏。
默認(rèn)值portraint。無(wú)論是直播還是全屏H5一般都是豎屏播放,
但是這個(gè)屬性需要x5-video-player-type開啟H5模式
-->
自動(dòng)播放
設(shè)置autoplay屬性
<video autoplay></video>
在移動(dòng)瀏覽器中播放
在很多移動(dòng)瀏覽器里,都是要求用戶的真實(shí)操作來(lái)(touchend、click、doubleclick 或 keydown 事件等標(biāo)準(zhǔn)的事件)觸發(fā)調(diào)用video.play(),才能自動(dòng)播放影音視頻。
dom.addEventListener('click', function () {
video.play()
})
在微信中播放
可以在 wx.ready()里觸發(fā)video.play()
wx.ready(function () {
video.play()
})
內(nèi)聯(lián)播放
設(shè)置屬性 webkit-playsinline playsinline
<video id="video" webkit-playsinline playsinline /></video>
在iOS Safari和一些安卓的一些瀏覽器下播放視頻的時(shí)候,不能在h5頁(yè)面中播放視頻,系統(tǒng)會(huì)自動(dòng)接管視頻
如果需要在h5頁(yè)面內(nèi)播放視頻,需要在視頻標(biāo)簽上加上 webkit-playsinline,在iOS10以后,需要加上playsinline,建議同時(shí)加上這兩個(gè)屬性。同時(shí)還需要app支持這種模式
webview.allowsInlineMediaPlayback = YES;
ios手Q和微信都支持這種模式,但是android 微信就掛了
android 微信
android微信內(nèi)置瀏覽器采用騰訊X5內(nèi)核,不遵循X5web標(biāo)準(zhǔn),video強(qiáng)制全屏就是其一。視頻播放完畢后還會(huì)出現(xiàn)QQ自己的視頻推薦
據(jù)說(shuō),其有個(gè)白名單,白名單下的視頻資源,就不會(huì)全屏。但是騰訊已經(jīng)不能再增加白名單了。尿性,無(wú)解。。。。。。
目前還有一個(gè)解決辦法,就是使用h5 canvas 播放 video
canvas 播放視頻
使用canvas 遇到的坑:video 必須加 x5-video-player-type="h5" 屬性,否則,在移動(dòng)端就會(huì)卡死不能播放視頻,個(gè)人認(rèn)為是因?yàn)橐曨l被接管的原因?qū)е隆?/p>
<div class="wrapper">
<video id="video" style="display: none" autoplay src="video.mp4" x5-video-player-type="h5"></video>
<canvas id="canvas"></canvas>
</div>
<script>
var video = document.querySelector('#video')
var canvas = document.querySelector('#canvas')
var wrapper = canvas.parentNode
var width = wrapper.offsetWidth
var height = wrapper.offsetHeight
var ctx = c.getContext('2d')
var time = null
canvas.width = width
canvas.height = height
canvas.addEventListener('click', function () {
video.play()
})
video.addEventListener('play', function () {
time = window.setInterval(function () {
ctx.drawImage(v, 0, 0, width, height);
}, 20);
}, false);
video.addEventListener('pause', function () {
window.clearInterval(time);
}, false);
video.addEventListener('ended', function () {
window.clearInterval(time);
}, false);
</script>
最后發(fā)現(xiàn),雖然使用canvas播放視頻,android微信中可以屏蔽全屏視頻播放完的推薦視頻。但是還沒辦法禁止視頻播放時(shí) 的全屏問(wèn)題。還是得萬(wàn)惡的白名單。吐槽。。。。。。。。。。。。。。。。
更坑爹的是沒有找到j(luò)s觸發(fā)退出全屏的方法。
ios黑屏問(wèn)題
ios 在播放視頻時(shí),會(huì)出現(xiàn)短暫的黑屏,然后正常顯示。
解決方法:
在視頻上層覆蓋一個(gè) 添加一個(gè)div并用一張圖片填充,制造播放前加載假象。然后監(jiān)聽事件 timeupdate ,視頻播放有畫面時(shí)移除這個(gè)“div塊”
video.addEventListener('timeupdate', function(){
if(video.currentTime > 0.1){
posterImg.hidden();
}
})
Media 方法和屬性
HTMLVideoElement和HTMLAudioElement 均繼承自HTMLMediaElement
// 媒體錯(cuò)誤
MediaObj.error; //null:正常
MediaObj.error.code; //1.用戶終止 2.網(wǎng)絡(luò)錯(cuò)誤 3.解碼錯(cuò)誤 4.URL無(wú)效
//媒體當(dāng)前狀態(tài)
MediaObj.currentSrc; //返回當(dāng)前資源的URL
MediaObj.src = value; //返回或設(shè)置當(dāng)前資源的URL
MediaObj.canPlayType(type); //是否能播放某種格式的資源
MediaObj.networkState; //0.此元素未初始化 1.正常但沒有使用網(wǎng)絡(luò) 2.正在下載數(shù)據(jù) 3.沒有找到資源
MediaObj.load(); //重新加載src指定的資源
MediaObj.buffered; //返回已緩沖區(qū)域,TimeRanges
MediaObj.preload; //none:不預(yù)載 metadata:預(yù)載資源信息 auto:
//準(zhǔn)備狀態(tài)
MediaObj.readyState;//1:HAVE_NOTHING
//2:HAVE_METADATA
//3.HAVE_CURRENT_DATA
//4.HAVE_FUTURE_DATA
//5.HAVE_ENOUGH_DATA
MediaObj.seeking; //是否正在seeking
//回放狀態(tài)
MediaObj.currentTime = value; //當(dāng)前播放的位置,賦值可改變位置
MediaObj.startTime; //一般為0,如果為流媒體或者不從0開始的資源,則不為0
MediaObj.duration; //當(dāng)前資源長(zhǎng)度 流返回?zé)o限
MediaObj.paused; //是否暫停
MediaObj.defaultPlaybackRate = value;//默認(rèn)的回放速度,可以設(shè)置
MediaObj.playbackRate = value;//當(dāng)前播放速度,設(shè)置后馬上改變
MediaObj.played; //返回已經(jīng)播放的區(qū)域,TimeRanges,關(guān)于此對(duì)象見下文
MediaObj.seekable; //返回可以seek的區(qū)域 TimeRanges
MediaObj.ended; //是否結(jié)束
MediaObj.autoPlay; //是否自動(dòng)播放
MediaObj.loop; //是否循環(huán)播放
MediaObj.play(); //播放
MediaObj.pause(); //暫停
//視頻控制
MediaObj.controls;//是否有默認(rèn)控制條
MediaObj.volume = value; //音量
MediaObj.muted = value; //靜音
//TimeRanges(區(qū)域)對(duì)象
TimeRanges.length; //區(qū)域段數(shù)
TimeRanges.start(index) //第index段區(qū)域的開始位置
TimeRanges.end(index) //第index段區(qū)域的結(jié)束位置
//【★★★**相關(guān)事件**★★★】
//事件分發(fā)
var eventTester = function(e){
Media.addEventListener(e,function(){
console.log((new Date()).getTime(),e)
},false);
}
//事件監(jiān)聽
eventTester("loadstart"); //客戶端開始請(qǐng)求數(shù)據(jù)
eventTester("progress"); //客戶端正在請(qǐng)求數(shù)據(jù)
eventTester("suspend"); //延遲下載
eventTester("abort"); //客戶端主動(dòng)終止下載(不是因?yàn)殄e(cuò)誤引起)
eventTester("loadstart"); //客戶端開始請(qǐng)求數(shù)據(jù)
eventTester("progress"); //客戶端正在請(qǐng)求數(shù)據(jù)
eventTester("suspend"); //延遲下載
eventTester("abort"); //客戶端主動(dòng)終止下載(不是因?yàn)殄e(cuò)誤引起),
eventTester("error"); //請(qǐng)求數(shù)據(jù)時(shí)遇到錯(cuò)誤
eventTester("stalled"); //網(wǎng)速失速
eventTester("play"); //play()和autoplay開始播放時(shí)觸發(fā)
eventTester("pause"); //pause()觸發(fā)
eventTester("loadedmetadata"); //成功獲取資源長(zhǎng)度
eventTester("loadeddata"); //
eventTester("waiting"); //等待數(shù)據(jù),并非錯(cuò)誤
eventTester("playing"); //開始回放
eventTester("canplay"); //可以播放,但中途可能因?yàn)榧虞d而暫停
eventTester("canplaythrough"); //可以播放,歌曲全部加載完畢
eventTester("seeking"); //尋找中
eventTester("seeked"); //尋找完畢
eventTester("timeupdate"); //播放時(shí)間改變
eventTester("ended"); //播放結(jié)束
eventTester("ratechange"); //播放速率改變
eventTester("durationchange"); //資源長(zhǎng)度改變
eventTester("volumechange"); //音量改變
關(guān)于如何在微信里面讓video不全屏播放
之前有關(guān)于如何讓video在微信或者QQ瀏覽器里面不默認(rèn)彈出全屏播放,可點(diǎn)擊這里查看。
今天發(fā)現(xiàn)一個(gè)更簡(jiǎn)單的解決方法,加上一條屬性即可。x5-video-player-type=”h5″。通過(guò)設(shè)置這個(gè)屬性,讓video開啟同層H5播放器。另外在X5內(nèi)核里,video是單獨(dú)的一個(gè)view,會(huì)覆蓋在任何元素之上,據(jù)說(shuō)是為了統(tǒng)一用戶體驗(yàn),加上這個(gè)屬性之后,也可以讓其他元素浮在video上面了。
經(jīng)過(guò)測(cè)試,在IOS設(shè)備,依然還需要添加如下屬性 x-webkit-airplay=”true” playsinline webkit-playsinline=”true”。
<video id="video" src="mp4.mp4" x-webkit-airplay="true" playsinline webkit-playsinline="true" x5-video-player-type="h5"></video>
另外還有幾個(gè)屬性 x5-video-player-fullscreen=”true”,視頻播放時(shí)將會(huì)進(jìn)入到全屏模式。
x5-video-orientation,聲明播放器支持的方向,可選值: landscape 橫屏, portraint豎屏 ,此屬性只在聲明了x5-video-player-type=”h5″情況下生效。