1. 程式人生 > 其它 >H5頁面video在app內實現poster效果

H5頁面video在app內實現poster效果

H5頁面Video元件 在APP內  時候沒有 載入的時候 沒有封面就是poster,所以要想辦法解決,

video標籤

  移動端的頁面裡如果有video標籤,根據官方文件上寫著,沒有加poster的話,就自動採用視訊第一幀作為poster。

  在ios上大部分瀏覽器都不會自動載入視訊第一幀作為poster,ios上表現為一個大播放按鈕在中間,然後播放器其他區域全是空白,安卓機上則表現良好

  • 查閱資料,得出解決方案是,用canvas載入video第一幀渲染一個base64的image作為poster,嘗試了後失敗,canvas報錯因為資源跨域,被汙染無法轉image,即便video設定了跨域也不行,資源的獲取上也是設定了跨域的
  • 換了種思路,不使用第一幀,使用第0.1秒作為封面,只要在src後面加上#t=0.1即可自動載入到第0.1秒,實現了poster效果,比如<video src="xxxxxx.mp4#t=0.1" />,試了一下大部分ios上的移動瀏覽器都支援,支援極為良好。(這個方法推薦)
  • 還有就是用 那種截圖的方式,視訊的連結後面加上一些?引數(是騰訊的提供的,當然是要付費的, )
1. 然後發現微信自帶的瀏覽器不支援自動播放(就是手機上直接從微信點開一個連結開啟的瀏覽器),
查閱資料後得知,需要加一個監聽,實現自動播放
document.addEventListener("WeixinJSBridgeReady", function
(){ document.getElementById('video').play() }, false)
但是我要的是實現poster效果,不是自動播放,所以要在play後給他暫停
 document.addEventListener("WeixinJSBridgeReady", function (){     
  document.getElementById('video').play();     
  document.getElementById('video').pause(); 
}, false)

2.於是在一對父子元件裡分別都監聽了這個事件,但是子元件一直觸發不了,父元件則能觸發,

   因為子元件是通過介面返回了資料才去渲染的,

而父元件頁面一載入就有,WeixinJSBridgeReady只會觸發一次,子元件裡面設定監聽的時候,已經遲了,不會再觸發了

3.子元件需要這樣判斷去觸發,在didmount的時候去判斷,然後按照下面的去呼叫,在回撥函式裡去播放和暫停,實現poster效果

componentDidMount = () => {        
  if (window.WeixinJSBridge) {            
    window.WeixinJSBridge.invoke('getNetworkType', {}, e => {            
    document.querySelector('video').play();                 
    document.querySelector('video').pause();             
    }, false);        
  }   
}

4.對於其他端,需要給src後面加上#t=0.1,並且設定預設內聯播放,不脫離文件流,

因為很多安卓瀏覽器都會劫持video標籤,在播放的時候自動呼叫原生播放器,提升效能,對於互動有嚴格要求的產品來說,這個是要幹掉的。

所以需要加一些屬性,由於是在字串裡面的標籤里加,如果用正則匹配替換,會非常不方便,所以用下面的方法

setVideoHTML = () => {         
  const {innerHTML} = this.props;        
  const div = document.createElement('div');        
  div.innerHTML = innerHTML;         
  div.querySelectorAll('video').forEach(video => {             
  video.src += '#t=0.1';             
  video.setAttribute('playsinline', 'true');             
  video.setAttribute('autoplay', 'false');             
  video.setAttribute('preload', 'auto');            
  video.setAttribute('webkit-playsInline', 'true');             
  video.setAttribute('x-webkit-airplay', 'allow');           
  video.setAttribute('x5-video-player-type', 'h5');            
  video.setAttribute('x5-video-player-fullscreen', 'true');           
  video.setAttribute('x5-video-orientation', 'portraint');    
});         
return div.innerHTML;    
}

最後需要調整

這裡好像只能用setAttribute方法,直接加沒生效,這樣子呼叫後,得到的還是一串字串,但是裡面對應的內容都被替換修改了,就可以正常用了

<div dangerouslySetInnerHTML={{__html: this.setVideoHTML()}}/>