<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入理解Video標(biāo)簽

          共 6648字,需瀏覽 14分鐘

           ·

          2021-07-09 22:33

          作者 | 華仔專業(yè)打雜
          鏈接 | https://juejin.cn/post/6979881494189703199


          Video相關(guān)屬性

          1、自動播放

          目前主流瀏覽器加強(qiáng)了對自動播放策略(Autoplay)的限制:瀏覽器在沒有交互操作之前不允許有聲音的媒體文件自動播放。 而且各個(gè)瀏覽器關(guān)于自動播放策略有不同的實(shí)現(xiàn)。
          {/* 自動播放 */}<video ref={ videoRef } controls autoPlay />

          為了解決自動播放失敗,在這里介紹兩種方法解決 Autoplay 限制的方案

          播放失敗時(shí)繞過 Autoplay 限制
          直接繞過 Autoplay 限制

          1.1 播放失敗時(shí)繞過 Autoplay 限制

          在實(shí)際使用中,頁面并不是完全被 Autoplay 限制,隨著用戶使用這個(gè)頁面的次數(shù)增加,瀏覽器會將這個(gè)頁面加入自己的 Autoplay 白名單列表中。

          根據(jù)這個(gè)原理,可在檢測到播放失敗時(shí),引導(dǎo)用戶點(diǎn)擊頁面上的某個(gè)位置來恢復(fù)播放。(Google瀏覽器下測試均播放失敗)

          // 可播放監(jiān)聽。當(dāng)瀏覽器能夠開始播放指定的音頻/視頻時(shí)觸發(fā)this.videoRef.addEventListener('canplay', () => {    console.log('視頻可以播放了')    setTimeout(() => {        // this.videoRef.paused 判斷是否暫停,用來判斷是視頻是否在播放中,如果沒有播放就        console.log(this.videoRef.paused)         console.log('視頻是否在暫停中', this.videoRef.paused)         this.isPlay = !this.videoRef.paused    }, 500)})
          // 通過promise來判斷是否在播放const videoPromise = this.videoRef.play()if(!!videoPromise) { videoPromise.then(() => { this.isPlay = true console.log('播放成功') }).catch(() => { this.isPlay = false console.log('播放失敗') })} else { // 此時(shí)可以通過canplay 監(jiān)聽是否在播放}

          1.2 直接繞過 Autoplay 限制

          可以通過如下兩種方案實(shí)現(xiàn)直接繞過 Autoplay 限制

          在video標(biāo)簽中關(guān)閉靜音muted屬性設(shè)置為true。媒體不包含聲音時(shí)不會被 Autoplay 限制。(引導(dǎo)用戶開啟聲音)

          UI上引導(dǎo)用戶觸發(fā)播放

          注意:無論使用哪種方案,在自動播放策略的限制下,沒有用戶操作之前都不可能自動播放有聲媒體。

          雖然瀏覽器會在本地維護(hù)一個(gè)白名單來決定對哪些網(wǎng)站解除自動播放限制,但該白名單無法通過 JavaScript 探測到。

          // 移動端document.body.addEventListener('touchstart', () => {    console.log('觸發(fā)播放')    this.videoRef.play();})// PC端document.body.addEventListener('mousedown', () => {    console.log('觸發(fā)播放')    this.videoRef.play();})// 微信端IOS手機(jī)下觸發(fā)自動播放,大部分IOS能正常自動播放(安卓機(jī)只能通過touchstart觸發(fā)播放)document.body.addEventListener('WeixinjsBridgeReady', () => {    console.log('觸發(fā)播放')    this.videoRef.play();})

          注意: Safari 只允許通過用戶交互來觸發(fā)有聲媒體的播放,而不是在用戶交互后就打開 Autoplay 限制。

          2、播放時(shí)間屬性控制

          首先我們來看一段代碼,在Google端能夠正常播放,但是在移動端和Safari中還是重頭開始播放。使用了canplay 和loadedmetadata,oncanplay事件來判斷視頻狀態(tài)再設(shè)置currentTime,但移動端還是無效。

          const videoPromise = this.videoRef.play()this.videoRef.currentTime =  10

          解決方案:

          設(shè)置視頻的Timeupdate事件監(jiān)聽設(shè)置播放時(shí)間

          使用定時(shí)器設(shè)置播放時(shí)間

          this.videoRef.play();   // 通過時(shí)間更新播放時(shí)間let timer = setTimeout(function(){    // 這里還是有一定的缺陷,如果用戶觸發(fā)了視頻播放,但是加載比較長就會有問題    this.videoRef.currentTime = 需要設(shè)置的時(shí)間;    clearTimeout(timer);},200);
          // timeupdate:目前的播放位置已更改時(shí),播放時(shí)間更新this.videoRef.addEventListener('timeupdate', (e) => { console.log('timeupdate') let timeDisplay = Math.floor(this.videoRef.currentTime); if(timeDisplay > 0){ if(this.firstOpen){ this.videoRef.currentTime = 10; this.firstOpen = false; } }})
          // seeking:查找開始。當(dāng)用戶開始移動/跳躍到音頻/視頻中新的位置時(shí)觸發(fā)this.videoRef.addEventListener('seeking', (e) => { // 在這里處理視頻播放是否播到放指定的時(shí)間 console.log('開始移動進(jìn)度條', this.videoRef.currentTime)})
          // seeked:查找結(jié)束。當(dāng)用戶已經(jīng)移動/跳躍到視頻中新的位置時(shí)觸發(fā)this.videoRef.addEventListener('seeked', (e) => { console.log('進(jìn)度條已經(jīng)移動到了新的位置', this.videoRef.currentTime)})

          其他屬性介紹:

          this.videoRef.error; //null:正常

          this.videoRef.error.code; //1.用戶終止 2.網(wǎng)絡(luò)錯誤 3.解碼錯誤 4.URL無效

          this.videoRef.networkState; //0.此元素未初始化 1.正常但沒有使用網(wǎng)絡(luò) 2.正在下載數(shù)據(jù) 3.沒有找到資源

          this.videoRef.buffered; //返回已緩沖區(qū)域,TimeRanges

          this.videoRef.paused; //是否暫停

          this.videoRef.defaultPlaybackRate = value;//默認(rèn)的回放速度,可以設(shè)置

          this.videoRef.playbackRate = value;//當(dāng)前播放速度,設(shè)置后馬上改變

          this.videoRef.played; //返回已經(jīng)播放的區(qū)域,TimeRanges,

          this.videoRef.seekable; //返回可以seek的區(qū)域 TimeRanges

          this.videoRef.ended; //是否結(jié)束

          Video相關(guān)事件

          了解Video 標(biāo)簽相關(guān)事件觸發(fā)時(shí)機(jī),才能處理好業(yè)務(wù)相關(guān)邏輯。

          // loadstart 視頻查找。當(dāng)瀏覽器開始尋找指定的音頻/視頻時(shí)觸發(fā),也就是當(dāng)加載過程開始時(shí)this.videoRef.addEventListener('loadstart', (e) => {    console.log('提示視頻的元數(shù)據(jù)已加載')    // console.log(e)    console.log(this.videoRef.duration)            // NaN})
          // durationchange 時(shí)長變化。當(dāng)指定的音頻/視頻的時(shí)長數(shù)據(jù)發(fā)生變化時(shí)觸發(fā),加載后,時(shí)長由 NaN 變?yōu)橐纛l/視頻的實(shí)際時(shí)長this.videoRef.addEventListener('durationchange', (e) => { console.log('提示視頻的時(shí)長已改變') console.log(this.videoRef.duration) // 視頻的實(shí)際時(shí)長(單位:秒)})
          // loadedmetadata :元數(shù)據(jù)加載。當(dāng)指定的音頻/視頻的元數(shù)據(jù)已加載時(shí)觸發(fā),元數(shù)據(jù)包括:時(shí)長、尺寸(僅視頻)以及文本軌道this.videoRef.addEventListener('loadedmetadata', (e) => { console.log('提示視頻的元數(shù)據(jù)已加載') // console.log(e)})
          // loadeddata:視頻下載監(jiān)聽。當(dāng)當(dāng)前幀的數(shù)據(jù)已加載,但沒有足夠的數(shù)據(jù)來播放指定音頻/視頻的下一幀時(shí)觸發(fā)this.videoRef.addEventListener('loadeddata', (e) => { console.log('提示當(dāng)前幀的數(shù)據(jù)是可用的')})
          // progress:瀏覽器下載監(jiān)聽。當(dāng)瀏覽器正在下載指定的音頻/視頻時(shí)觸發(fā)this.videoRef.addEventListener('progress', (e) => { console.log('提示視頻正在下載中')})
          // canplay:可播放監(jiān)聽。當(dāng)瀏覽器能夠開始播放指定的音頻/視頻時(shí)觸發(fā)this.videoRef.addEventListener('canplay', (e) => { console.log('視頻可以播放了') setTimeout(() => { // this.videoRef.paused 判斷是否暫停 console.log('視頻是否在暫停中', this.videoRef.paused) this.isPlay = !this.videoRef.paused }, 1000)})
          // canplaythrough:可流暢播放。當(dāng)瀏覽器預(yù)計(jì)能夠在不停下來進(jìn)行緩沖的情況下持續(xù)播放指定的音頻/視頻時(shí)觸發(fā)this.videoRef.addEventListener('canplaythrough', (e) => { console.log('提示視頻能夠不停頓地一直播放') console.log(e)})
          // play: 播放監(jiān)聽this.videoRef.addEventListener('play', (e) => { console.log('提示該視頻正在播放中')})
          // pause:暫停監(jiān)聽this.videoRef.addEventListener('pause', (e) => { console.log('暫停播放')})
          // seeking:查找開始。當(dāng)用戶開始移動/跳躍到音頻/視頻中新的位置時(shí)觸發(fā)this.videoRef.addEventListener('seeking', (e) => { // 在這里處理到底有沒有更新到最新的位置 console.log('開始移動進(jìn)度條', this.videoRef.currentTime)})
          // seeked:查找結(jié)束。當(dāng)用戶已經(jīng)移動/跳躍到視頻中新的位置時(shí)觸發(fā)this.videoRef.addEventListener('seeked', (e) => { console.log('進(jìn)度條已經(jīng)移動到了新的位置', this.videoRef.currentTime)})
          // waiting:視頻加載等待。當(dāng)視頻由于需要緩沖下一幀而停止,等待時(shí)觸發(fā)this.videoRef.addEventListener('waiting', (e) => { console.log('視頻加載等待') console.log(e)})
          // playing:當(dāng)視頻在已因緩沖而暫?;蛲V购笠丫途w時(shí)觸發(fā)this.videoRef.addEventListener('playing', (e) => { console.log('playing') console.log(e)})
          // timeupdate:目前的播放位置已更改時(shí),播放時(shí)間更新this.videoRef.addEventListener('timeupdate', (e) => { // console.log('timeupdate') // let timeDisplay = Math.floor(this.videoRef.currentTime); // if(timeDisplay > 0){ // if(this.firstOpen){ // this.videoRef.currentTime = 10; // this.firstOpen = false; // } // }})
          // ended:播放結(jié)束this.videoRef.addEventListener('ended', (e) => { console.log('視頻播放完了') console.log(e)})
          // error:播放錯誤this.videoRef.addEventListener('error', (e) => { console.log('視頻出錯了') console.log(e)})
          // volumechange:當(dāng)音量更改時(shí)this.videoRef.addEventListener('volumechange', (e) => { console.log('volumechange') console.log(e)})
          // stalled:當(dāng)瀏覽器嘗試獲取媒體數(shù)據(jù),但數(shù)據(jù)不可用時(shí)this.videoRef.addEventListener('stalled', (e) => { console.log('stalled') console.log(e)})
          // ratechange:當(dāng)視頻的播放速度已更改時(shí)this.videoRef.addEventListener('ratechange', (e) => { console.log('ratechange') console.log(e)})

          關(guān)于微信H5視頻兼容介紹: 移動端兼容

          最后

          移動端Web對于Video自動播放的兼容性是在太差,尤其安卓。各種問題,各種兼容,各種心累。

          本文到此結(jié)束。希望對你有幫助。

          學(xué)習(xí)更多技能

          請點(diǎn)擊下方公眾號


          瀏覽 48
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人视频网网址 | 国产在线拍揄自揄拍无码福利 | 成人无码不卡免费视频 | 黄色免费日本欧美 | 日韩AV东京热一 |