video 標籤在微信瀏覽器的問題解決方法
最近做的些web頁面,內嵌許多小視頻,在ios和安卓手機上播放時,遇到不少問題:
- 在微信瀏覽器內播放時,視頻會自動全屏
- 如果每個視頻都有一張自定義的圖片作爲封面,在顯示視頻的同時,如果沒有給這個視頻設置高度,視頻的容器在安卓手機上會被視頻的封面撐大到變形
解決辦法:
給video標籤加一些屬性,調用h5原生video,我寫了個例子,加了註釋,如果有錯誤,煩指正,謝謝!
<video class="video-source" width="100%" height="240px" /*如果有封面,請設置高度*/ controls /*這個屬性規定瀏覽器爲該視頻提供播放控件*/ style="object-fit:fill" /*加這個style會讓 Android / web 的視頻在微信裏的視頻全屏,如果是在手機上預覽,會讓視頻的封面同視頻一樣大小*/ webkit-playsinline="true" /*這個屬性是ios 10中設置可以讓視頻在小窗內播放,也就是不是全屏播放*/ x-webkit-airplay="true" /*這個屬性還不知道作用*/ playsinline="true" /*IOS微信瀏覽器支持小窗內播放*/ x5-video-player-type="h5" /*啓用H5播放器,是wechat安卓版特性*/ x5-video-orientation="h5" /*播放器支付的方向,landscape橫屏,portraint豎屏,默認值爲豎屏*/ x5-video-player-fullscreen="true" /*全屏設置,設置爲 true 是防止橫屏*/ preload="auto" /*這個屬性規定頁面加載完成後載入視頻*/ </video>
如果你的video標籤也加了上面的屬性,那麼,你的視頻可以在IOS手機上的小窗口播放,同時,視頻封面同視頻的寬度與高度也保持一致了。
經過各種嘗試,在iOS下,可以給video添加webkit-playsinline屬性,使視頻在頁面上原本位置播放,但這個屬性在安卓上無效。
/****華麗麗的分割線,以下內容摘抄自網絡,供參考****/
IOS微信瀏覽器是Chrome內核,下面大部分屬性都支持,安卓微信瀏覽器是X5內核,一些屬性是不支持的,比如可以設置局部播放的屬性 playsinline,因此,始終是全屏。
下面的內容用以解釋上面的內容:
2017-01-20 17:07:32
preload="auto" :屬性規定在頁面加載後載入視頻。如果設置了 autoplay 屬性,則忽略該屬性。
一般參數可能的值:
· auto - 當頁面加載後載入整個視頻
· meta - 當頁面加載後只載入元數據
· none - 當頁面加載後不載入視頻
muted:當設置該屬性後,它規定視頻的音頻輸出應該被靜音
controls="controls" :屬性規定瀏覽器應該爲視頻提供播放控件。
autoplay="autoplay": 視頻自動播放設置,但是有經驗的人都應該知道,autoplay標籤在手機上不兼容,APP中設置問題導致無法自動播放,無論安卓或IOS。需要模擬自動播放只能通過一些事件觸發。
webkit-playsinline playsinline:視頻播放時局域播放,不脫離文檔流 。但是這個屬性比較特別, 需要嵌入網頁的APP比如WeChat中UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES,才能生效。換句話說,如果APP不設置,你頁面中加了這標籤也無效,這也就是爲什麼安卓手機WeChat 播放視頻總是全屏,因爲APP不支持playsinline,而ISO的WeChat卻支持。
這裏就要補充下,如果是想做全屏直播或者全屏H5體驗的用戶,ISO需要設置刪除 webkit-playsinline 標籤,因爲你設置 false 是不支持的 ,安卓則不需要,因爲默認全屏。但這時候全屏是有播放控件的,無論你有沒有設置control。 做直播的可能用得着播放控件,但是全屏H5是不需要的,那麼去除全屏播放時候的控件,需要以下設置:同層播放。
x5-video-player-type:啓用同層H5播放器,就是在視頻全屏的時候,div可以呈現在視頻層上,也是WeChat安卓版特有的屬性。同層播放別名也叫做沉浸式播放,播放的時候看似全屏,但是已經除去了control和微信的導航欄,只留下"X"和"<"兩鍵。目前的同層播放器只在Android(包括微信)上生效,暫時不支持iOS。筆者想過爲什麼同層播放只對安卓開放,因爲安卓不能像ISO一樣局域播放,默認的全屏會使得一些界面操作被阻攔,如果是全屏H5還好,但是做直播的話,諸如彈幕那樣的功能就無法實現了,所以這時候同層播放的概念就解決了這個問題。不過筆者在測試的過程中發現,不同版本的ISO和安卓效果略有不同。
x5-video-orientation:聲明播放器支持的方向,可選值landscape 橫屏, portraint豎屏。默認值portraint。無論是直播還是全屏H5一般都是豎屏播放,但是這個屬性需要x5-video-player-type開啓H5模式
x5videoplayerfullscreen:全屏設置。筆者還未能領悟這個標籤的用意,在測試過程中發現,ture和false的設置會導致佈局上的不一樣,如圖 Click標籤先後的位置。
另外補充下,ISO 微信瀏覽器是Chrome的內核,相關的屬性都支持,也是爲什麼X5同層播放不支持的原因。安卓微信瀏覽器是X5內核,一些屬性標籤比如playsinline就不支持,所以始終全屏。
/****貌似到這裏,瞭解了爲什麼安卓手機的全屏視頻了****/
2017-01-20 17:13:55
還有個問題,在Android的微信裏面,就算加上了上面的屬性,還會出現上下有黑邊,不能全屏的問題。
解決辦法:給video加上object-fit: fill;的style屬性。
/****關於微信內置瀏覽器不能小窗口播放視頻的問題-知乎答****/
2017-01-20 17:40:38
在最新的ios微信6.5.3及其之後的版本中,webview默認支持小窗播放,
開發者需要特別注意小窗播放需要前端同時適配iOS10和iOS10以下的低版本
適配建議:需要完全按照以下代碼設置video標籤纔可同時兼容不同的iOS版本
<video webkit-playsinline playsinline> </video>
作者:Lying
鏈接:https://www.zhihu.com/question/36423771/answer/93953992
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
知友說 webkit-playsinline 可以解決這個問題.但是經過個人以及各位知友的驗證該方法在ios 系統並且是在非微信自帶的瀏覽器的內核中能夠解決。Android 然並卵。
/****還沒測試的 video.js 據說,很好用,安卓微信瀏覽器不會全屏播放****/
2017-01-20 17:44:22
知友:張豔紅
1,公司網頁要求播放很多小視頻,於是採用了videojs框架,官網鏈接:Video.js: The Player Framework ,實測,很好用,而且安卓微信內不會全屏播放。
2,效果見我私官網:http://gethover.com 。
3, 另外此框架支持IE8瀏覽器 。
作者:張豔紅
鏈接:https://www.zhihu.com/question/36423771/answer/108443996
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
打算明天測試這個JS 是否如知友所說的那樣好用,如果真是那樣,我的問題就解決了。目前就是安卓手機的視頻全屏的樣子讓人蛋疼!
video.js CDN: http://www.bootcdn.cn/video.js/
video.js 教程:http://www.cnblogs.com/afrog/p/4115377.html
使用video.js有感而發,使用它主要是爲了兼容iOS與安卓在顯示效果上可以有比較相似的一面,同時,把視頻或音步的顯示效果自定義一番。上面爲視頻,下面爲音頻:
這個做的還不好,現在是兼容了iOS了,但是安卓上還不好用,安卓上的視頻播放按鈕看不到了,再需要再調整,如果大神知道方法,煩請告我一下,非常感謝。
<!--video.js--> <link href="http://vjs.zencdn.net/5.8.8/video-js.css" rel="stylesheet"> <script src="http://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script> <script src="http://vjs.zencdn.net/5.8.8/video.js"></script>
<script type="text/javascript"> var source = $('<source></source>'); //視頻url地址 var audioPlayImg = "../img/doctor/play-audio.png"; //播放按鈕 var pauseImg = "../img/doctor/pause.png"; //暫停按鈕 (function(window, document) { searchVideo(); //獲取要操作的元素 var video = document.getElementById("video"); var audio = document.getElementById('audio'); var videoControls = document.getElementById("videoControls"); var audioControls = document.getElementById("audioControls"); var videoContainer = document.getElementById("videoContainer"); var audioControls = document.getElementById("audioControls"); var controls = document.getElementById("video_controls"); var playBtn = document.getElementById("playBtn"); var audioBtn = document.getElementById("audioPlayBtn"); var fullScreenFlag = false; var progressFlag; // 音頻: 創建我們的操作對象,我們的所有操作都在這個對象上。 var audioPlayr = { init: function() { var that = this; //刪除音頻的控制按鈕屬性 audio.removeAttribute("controls"); bindEvent(audio, "loadeddata", audioPlayr.initControls); audioPlayr.operateControls(); }, initControls: function() { audioPlayr.showHideControls(); }, showHideControls: function() { bindEvent(audio, "mouseover", showAudioControls); bindEvent(audioControls, "mouseover", showAudioControls); bindEvent(audio, "mouseout", hideAudioControls); bindEvent(audioControls, "mouseout", hideAudioControls); }, operateControls: function() { bindEvent(audioBtn, "click", audioPlay); bindEvent(audio, "click", audioPlay); } } audioPlayr.init(); function showAudioControls() { videoControls.style.opacity = 1; } function hideAudioControls() { videoControls.style.opacity = 1; } function audioPlay() { if(audio.paused || audio.ended) { if(audio.ended) { audio.currentTime = 0; } audio.play(); audioBtn.setAttribute('src', pauseImg); } else { audio.pause(); audioBtn.setAttribute('src', audioPlayImg); clearInterval(progressFlag); } } // 視頻: 創建我們的操作對象,我們的所有操作都在這個對象上。 var videoPlayer = { init: function() { var that = this; //刪除視頻的播放按鈕屬性 video.removeAttribute("controls"); //如果當前的數據是可用的,爲視頻綁定事件 bindEvent(video, "loadeddata", videoPlayer.initControls); videoPlayer.operateControls(); }, initControls: function() { videoPlayer.showHideControls(); }, showHideControls: function() { bindEvent(video, "mouseover", showControls); bindEvent(videoControls, "mouseover", showControls); bindEvent(video, "mouseout", hideControls); bindEvent(videoControls, "mouseout", hideControls); }, operateControls: function() { bindEvent(playBtn, "click", isIOSOrAndroid); bindEvent(video, "click", isIOSOrAndroid); } } videoPlayer.init(); // 原生的JavaScript事件綁定函數 function bindEvent(ele, eventName, func) { if(window.addEventListener) { ele.addEventListener(eventName, func); } else { ele.attachEvent('on' + eventName, func); } } // 顯示video的控制面板 function showControls() { // 爲了讓控制面板一直出現,我把videoControls.style.opacity的值改爲1 videoControls.style.opacity = 1; } // 隱藏video的控制面板 function hideControls() { videoControls.style.opacity = 1; } //判斷當前系統是iOS系統還是安卓系統,因爲iOS微信瀏覽器會加載完視頻後自動添加一個播放按鈕。而我們的播放按鈕是自定義的 function isIOSOrAndroid() { var ua = navigator.userAgent.toLowerCase(); if(ua.match(/iPhone\sOS/i) == "iphone os") { iOSPlay(); } else if(ua.match(/Android/i) == "android") { androidPlay(); } } // 控制video的播放 當前操作是在iOS系統下操作 function iOSPlay() { $('.videoPlayer').css('margin-bottom', '0'); if(video.paused || video.ended) { if(video.ended) { video.currentTime = 0; } video.play(); playBtn.setAttribute('src', pauseImg); } else { video.pause(); playBtn.setAttribute('src', audioPlayImg); clearInterval(progressFlag); } } // 控制video的播放 當前操作是在安卓系統下操作 function androidPlay() { if(video.paused || video.ended) { if(video.ended) { video.currentTime = 0; } video.play(); playBtn.setAttribute('src', audioPlayImg); } else { video.pause(); playBtn.setAttribute('src', audioPlayImg); clearInterval(progressFlag); } } }(this, document)) </script>
HTML:
<div class="video-play-content"> <!--視頻--> <div class="videoPlayer video-js" id="videoContainer" style="height: 200px;margin-bottom: 15px;"> <video id="video" width="100%" height="200" preload controls style="object-fit: fill" webkit-playsinline="true" x-webkit-airplay="true" playsinline="true" x5-video-player-type="h5" x5-video-player-fullscreen="true"> </video> <div id="videoControls"> <div class="video-box"> <img id="playBtn" src="" /> </div> </div> </div> <!--音頻--> <div id="audioControls"> <audio id="audio" width="100%" height="50" preload controls> <source src="../video/wssf.mp3" type="audio/mp3"></source> </audio> <div id="audioControls"> <div class="audio-box"> <img id="audioPlayBtn" src="../img/doctor/play-audio.png" style="-webkit-appearance:none;" /> <div class="audio-detail"> <div class="audio-title">骨髓灰質炎疫苗選擇</div> <div class="audio-size"><span class="audio-time">24:26</span><span class="audio-size">11.44</span>MB</div> </div> </div> </div> </div> </div>
CSS:
body{ color: #555; font-family:Helvetica; margin: 15px; /*去掉默認外觀*/ -webkit-appearance:none; /*長按不觸發系統菜單*/ -webkit-touch-callout: none; /*禁止選中文字*/ -webkit-user-select:none; } @font-face { font-family: 'MicrosoftYaHei'; src: url('MicrosoftYaHei.eot'); /* IE9 Compat Modes */ src: url('MicrosoftYaHei.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('MicrosoftYaHei.woff') format('woff'), /* Modern Browsers */ url('MicrosoftYaHei.ttf') format('truetype'), /* Safari, Android, iOS */ url('MicrosoftYaHei.svg#MicrosoftYaHei') format('svg'); /* Legacy iOS */ } html{ font-size:13px; height: 100%; -webkit-tap-highlight-color: transparent; } @media screen and (min-width:321px) and (max-width:375px){ html{font-size:11px} .logo-box{ position: absolute; top: -56px; left: 50%; transform: translateX(-50%); } } @media screen and (min-width:376px) and (max-width:414px){ html{font-size:12px} .logo-box{ position: absolute; top: -56px; left: 50%; transform: translateX(-50%); } } @media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}} @media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}} @media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}} @media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}} @media screen and (min-width:800px){html{font-size:25px}} .main{ margin-bottom: 40px; } .video-js { display: block; vertical-align: top; box-sizing: border-box; color: #fff; background-color: #000; position: relative; padding: 0; font-size: 12px; line-height: 1; font-weight: normal; font-style: normal; font-family: Arial, Helvetica, sans-serif; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; height: 200px; } .videoPlayer{ width: 100%; position: relative; margin-bottom: 15px; /*background: #555;*/ } #video{ android:layout_margin="0dp"; android:padding="0dp"; } #audioControls,.video-explain-3{ margin-bottom: 15px; } #playBtn{ width: 5.5em; position: absolute; top: 72px; left: 50%; transform: translateX(-50%); z-index: 9; cursor: pointer; } .audio-box{ width: 100%; margin: auto; height: 80px; background: #e2e2e2; position: relative; display: flex; justify-content: space-around; align-items: center; } #audioPlayBtn { width: 5em; position: absolute; top: 10.5%; left: 6%; z-index: 9; cursor: pointer; } .vaccine{ width: 100%; margin: 15px 0; } .video-info{ margin-bottom: 20px; color: #999; } .audio-time{ margin-right: 10px; }
修改一下判斷瀏覽系統的方法:
function isIOSOrAndroid() { var browser = { versions: function() { var u = navigator.userAgent, app = navigator.appVersion; return { //移動終端瀏覽器版本信息 trident: u.indexOf('Trident') > -1, //IE內核 presto: u.indexOf('Presto') > -1, //opera內核 webKit: u.indexOf('AppleWebKit') > -1, //蘋果、谷歌內核 gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐內核 mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否爲移動終端 ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios終端 android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android終端或者uc瀏覽器 iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否爲iPhone或者QQHD瀏覽器 iPad: u.indexOf('iPad') > -1, //是否iPad webApp: u.indexOf('Safari') == -1 //是否web應該程序,沒有頭部與底部 }; }(), language: (navigator.browserLanguage || navigator.language).toLowerCase() } if(browser.versions.ios || browser.versions.iPhone || browser.versions.iPad) { $('.videoPlayer').css('margin-bottom', '15px'); iOSPlay(); } else if(browser.versions.android) { androidPlay(); } }
參考鏈接: