H5視頻播放

html5新增了音頻/視頻(audio/video)的API。
這次我們先來(lái)了解video。
video 元素支持三種視頻格式:
.ogg
.mp4
. webm

<video src="movie.ogg" >
  你的瀏覽器不支持video
</video>

video 元素允許多個(gè) source 元素。source 元素可以鏈接不同的視頻文件。瀏覽器將使用第一個(gè)可識(shí)別的格式:

<video width="320" height="240" controls="controls">
  <source src="movie.ogg" type="video/ogg">
  <source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>

知道視頻在移動(dòng)端播放會(huì)出現(xiàn)很多坑,我們來(lái)踩踩坑。首先對(duì)video的Api還不熟悉,所以先不考慮移動(dòng)端的兼容問(wèn)題。首先來(lái)實(shí)現(xiàn)video的播放等功能。
video Api


這是我寫(xiě)的html元素標(biāo)簽。
??現(xiàn)在我是把Dom元素和js都放在了body標(biāo)簽中。dom中綁定的onclick之類的事件,必須是全局的才能夠正確獲取。像settimeout函數(shù)里面定義的函數(shù)不是全局的,是局部的。出了settimeout函數(shù)就獲取不到了,所以綁定的事件不能寫(xiě)在任何函數(shù)里。如果不想污染全局可以選擇寫(xiě)一個(gè)匿名自執(zhí)行函數(shù)里寫(xiě)響應(yīng)事件,然后通過(guò)addEventListener綁定監(jiān)聽(tīng),而不是在html綁定監(jiān)聽(tīng)事件。


html中事件里面的this代表什么?
this作為事件的參數(shù)傳遞的話,指的是觸發(fā)事件的html element。如果不傳this,第一個(gè)參數(shù)是event, event.target 和這里的this是等價(jià)的。
onclick事件之類的event.offsetX 和 event.target.offsetWidth。一個(gè)在target上獲取。一個(gè)直接獲取。

var video = document.querySelector('.videoSource');
獲取視頻總時(shí)長(zhǎng)

video元素屬性duration返回音頻視頻長(zhǎng)度,單位為s。初始化顯示獲取需要用到video的loadeddata事件。

鼠標(biāo)點(diǎn)擊快進(jìn)或者后退

直接修改video.currentTime屬性即可。

全屏播放

h5暴露了一個(gè)webkitRequestFullScreen方法,可以讓每個(gè)dom都請(qǐng)求全屏,當(dāng)然video標(biāo)簽也可以使用。
但是一些安卓機(jī)不支持該屬性,如小米手機(jī),所以需要在調(diào)用的時(shí)候進(jìn)行一下判斷

if (video.webkitSupportsFullscreen) {
        video.webkitEnterFullscreen();
 } else {
        video.webkitRequestFullScreen();
}

頁(yè)面生成二維碼掃描

這幾天總看h5通過(guò)一個(gè)二維碼掃描就可以訪問(wèn)了。于是搜了一下。
二維碼生成方法
只需在頁(yè)面中加一段代碼

      thisURL = document.URL;  
      strwrite = 
      "<img src='https://chart.googleapis.com/chart?cht=qr&chs=150x150&choe=UTF-8&chld=L|4&chl="
        + thisURL + "' width='150' height='150' alt='網(wǎng)址URL 二維碼生成' />"; 
      document.write( strwrite );  

二維碼是生成了,但是手機(jī)掃描卻會(huì)出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤打不開(kāi),我本地寫(xiě)了個(gè)項(xiàng)目,打開(kāi)是file:// 這種方式。其實(shí)手機(jī)掃二維碼也就是通過(guò)手機(jī)打開(kāi)的生成二維碼的document.URL。手機(jī)上去訪問(wèn)file:// 肯定是加載不到的。于是我就用http-sever生成一個(gè)web服務(wù)器。一般可以生成兩個(gè)可訪問(wèn)的地址

 http://127.0.0.1:8000
 http://172.16.222.157:8000

我開(kāi)始用第一個(gè)地址打開(kāi),不行,還是網(wǎng)絡(luò)錯(cuò)誤。因?yàn)槭謾C(jī)也無(wú)法識(shí)別127.0.0.1。我突然就想到一個(gè)局域網(wǎng)內(nèi)是可以互相訪問(wèn)ip的。第二個(gè)不就是ip嗎。我的手機(jī)和電腦都連接的是公司的無(wú)線,應(yīng)該可以訪問(wèn)了吧。果然換成第二個(gè)地址手機(jī)就可以訪問(wèn)了。不過(guò)微信掃描二維碼會(huì)出現(xiàn)緩存問(wèn)題。
android video播放進(jìn)度控制

頁(yè)面內(nèi)聯(lián)播放問(wèn)題

在iOS Safari和一些安卓的一些瀏覽器下播放視頻的時(shí)候,不能在h5頁(yè)面中播放視頻,系統(tǒng)會(huì)自動(dòng)接管視頻,就是會(huì)默認(rèn)全屏播放。如何禁止呢?
增加屬性webkit-playsinline playsinline就可以了
<video id="player" webkit-playsinline playsinline >

移動(dòng)端手勢(shì)觸發(fā)事件

移動(dòng)端多用touch事件,而不是click事件。并且click有兩個(gè)著名的bug,移動(dòng)端300ms點(diǎn)擊延遲和點(diǎn)擊穿透問(wèn)題。所以有很多庫(kù)對(duì)事件進(jìn)行封裝,用封裝的tap代替click事件。
我們這個(gè)視頻播放的例子主要是看video在手機(jī)端的一些問(wèn)題。設(shè)計(jì)手勢(shì)事件很少,并且設(shè)置了content="width=device-width"所以移動(dòng)端瀏覽器自動(dòng)就取消了300ms的延遲。

遇到的問(wèn)題
  1. 給video綁定的loadeddata事件怎么不觸發(fā)了呢
    找了快一早上的原因。
    ??最后發(fā)現(xiàn)問(wèn)題的根本是因?yàn)?strong>link引入外部css會(huì)阻塞后面內(nèi)聯(lián)腳本的執(zhí)行。所以css還沒(méi)加載完,video元素就已經(jīng)加載完了因?yàn)?a target="_blank" rel="nofollow">css不會(huì)會(huì)阻塞DOM的加載會(huì)阻塞DOM的渲染。這時(shí)候該video響應(yīng)的loadeddata綁定的事件沒(méi)響應(yīng)呢video的狀態(tài)都已經(jīng)變了,早都已經(jīng)過(guò)了。結(jié)果等css加載完成之后,已經(jīng)不會(huì)響應(yīng)loadeddata的事件了。如果綁定的是onplay事件還是可以響應(yīng)的,因?yàn)檫@個(gè)是視頻播放時(shí)候才會(huì)觸發(fā)的?;蛘甙裞ss異步加載,給link添加media="none"就可以異步加載。
  2. 給video綁定loadeddata的函數(shù)傳入一個(gè)函數(shù)執(zhí)行就可以觸發(fā)?
    ?? 答案肯定是否定的,給ele.addEventListener('click', func)這是給ele綁定click事件,但是如果變成ele.addEventListener('click', func())。就是js解析到這句會(huì)執(zhí)行func函數(shù)。如果func函數(shù)沒(méi)有return一個(gè)函數(shù),則就沒(méi)有綁定上事件。
  3. 判斷是否移動(dòng)端
//如果沒(méi)有觸摸事件 判定為PC  
var ua = navigator.userAgent.toLowerCase();
            var isTocuh = ("ontouchstart" in window) || (ua.indexOf("touch") !== -1) || (ua.indexOf("mobile") !== -1);
  1. 視頻旋轉(zhuǎn)尺寸問(wèn)題
    ?防止視頻尺寸因?yàn)閷捀咴O(shè)置亂掉,需要給video設(shè)置object-fit: contain;
    ?把視頻旋轉(zhuǎn)90deg。再把寬和高重新設(shè)置一下。這就可以實(shí)現(xiàn)旋轉(zhuǎn)全屏了呀??墒墙Y(jié)果出來(lái)為什么是這個(gè)樣子?

左邊和下邊都有空隙并且視頻內(nèi)容偏移了。
所以不能單單的旋轉(zhuǎn)90°,還要設(shè)置translate

var info = [
                   document.documentElement.clientWidth || document.body.clientWidth,
                   document.documentElement.clientHeight || document.body.clientHeigth
           ],
                   w = info[0],
                   h = info[1],
                   cha = Math.abs(h - w) / 2;
videoBox.style.transform = 'translate(-' + cha + 'px,' + cha + 'px) rotate(90deg)';

H5 直播避坑指南
html5 實(shí)現(xiàn)video標(biāo)簽的自定義播放進(jìn)度條
HTML5 VideoAPI,打造自己的Web視頻播放器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,300評(píng)論 25 708
  • HLS是什么 HLS,Http Live Streaming 是由Apple公司定義的用于實(shí)時(shí)流傳輸?shù)膮f(xié)議,HLS...
    富士里閱讀 66,289評(píng)論 9 27
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,588評(píng)論 4 61
  • 我有一個(gè)摩羯座好友。我昨晚做了個(gè)恐怖的夢(mèng),以下是我醒來(lái)后在有道云上做的夢(mèng)境回憶記錄: 昨晚夢(mèng)見(jiàn)自己的腳趾頭大腳趾裂...
    童心麻麻閱讀 559評(píng)論 3 2
  • 找出去年戴的帽子,本來(lái)想洗洗的,看到帽子里有根頭發(fā),應(yīng)該是媽媽的,舍不得洗了,把那根頭發(fā)又放回去了。
    小圣嘟嘟閱讀 129評(píng)論 0 0

友情鏈接更多精彩內(nèi)容