iOS 10 Safari 視訊播放新政策
提醒:本文最後更新於 788 天前,文中所描述的資訊可能已發生改變,請謹慎使用。
隨著 iOS 10 的正式釋出,Safari 也迎來了大量更新,例如新增了對 ES6、CSP2.0、Shadow DOM 等功能和特性的支援。本文為大家介紹 iOS10 自帶 Safari 瀏覽器在視訊播放政策上的最新變化。首先劃出重點:1)iOS 10 Safari 支援特定視訊自動播放;2)iOS 10 Safari 支援視訊內聯播放。想了解更多細節的同學請接著往下看。
之前的政策?
在 iPhoneOS 3(沒錯,當時 iOS 還不叫 iOS)Safari 開始支援 <video>
標籤時,蘋果人為設定了很多限制,例如視訊無法自動播放 —— 甚至連 Meta 資訊預載入都被禁用。顯然,這是為了避免給使用者造成高額流量費用而作出的妥協,順便還能節省使用者手機電量。
隨著視訊的普及,在 iOS 8 中,蘋果放寬了對 Safari 視訊播放的限制:允許使用 preload="metadata"
來預載入視訊 Meta 資訊。但僅此而已,Safari 中的 <video>
元素仍然無法自動播放,也無法內聯播放 —— 這意味著視訊只能在使用者主動操作後才能播放,且播放時必須全屏。
至於「使用者主動操作」具體指的是哪些行為,蘋果官方有詳細的說明:
- 點選視訊播放按鈕;
- 觸發
touchend
、click
、doubleclick
或keydown
事件,且在事件處理函式中直接呼叫video.play()
方法。顯然,button.addEventListener('click', () => { video.play(); })
video.addEventListener('canplaythrough', () => { video.play(); })
不滿足要求;
值得注意的是,上面討論的是 iOS 自帶 Safari 的視訊播放政策。對於 iOS APP 而言,開發者在給 webview 設定 mediaPlaybackRequiresUserAction
和 allowsInlineMediaPlayback
屬性之後,頁面中的 <video>
標籤就可以通過 autoplay
和 webkit-playsinline
屬性來啟用自動播放和內聯播放功能。
iOS 10 新政策
隨著視訊的進一步普及,在 iOS 10 中,蘋果終於進一步放鬆了 Safari 視訊播放政策。
自動播放
iOS 10 Safari 允許自動播放以下兩種視訊:
- 無音軌視訊;
- 無聲音視訊(設定了
muted
屬性);
對於這兩種型別的視訊,可以通過 <video autoplay>
或 video.play()
兩種方式來自動播放,無需使用者主動操作。但是,如果它們在播放時變得有聲音(獲取了音軌,或者 muted
屬性被取消),Safari 會暫停播放。
通過 <video autoplay>
自動播放的視訊元素還需要滿足一個條件:在可視區域內。同樣,如果它們在播放時因為頁面滾動等原因導致不可見,Safari 也會暫停播放。
通過 video.play()
自動播放的視訊元素無需可見。video.play()
返回的是 Promise
,如果不滿足自動播放條件,會觸發 reject
行為。
內聯播放
在 iOS 10 Safari 中,通過 <video playsinline>
可以讓視訊內聯播放。設定了 playsinline
屬性的視訊在播放時不會自動全屏,但使用者可以點選全屏按鈕來手動全屏;沒有設定 playsinline
的視訊會在播放時自動全屏。無論是否設定 playsinline
屬性,退出全屏後視訊都會繼續播放。
playsinline
屬性在 iOS 10 之前需要寫成 webkit-playsinline
,它的瀏覽器廠商字首在 iOS 10 中被移除。但是目前 iOS 微信還不支援去掉字首的寫法,兩個屬性最好都加上。
顯然,<video autoplay>
必須和 playsinline
屬性一起使用。也就是說,只有預設內聯播放的視訊才有可能自動播放,這一點很容易理解。
一些典型應用
根據蘋果公司的文章:GIF 相比 H.264 編碼的視訊,頻寬佔用為十二倍,電池消耗為兩倍。沒有聲音的 <video>
元素很適合用作網頁背景,取代 GIF:
<video autoplay loop muted playsinline>
<source src="image.mp4">
<source src="image.webm" onerror="fallback(parentNode)">
<img src="image.gif">
</video>
<script>
function fallback(video) {
var img = video.querySelector('img');
if (img) {
video.parentNode.replaceChild(img, video);
}
}
</script>
這段程式碼使用 <video>
來替代 GIF 動畫,並考慮了降級。但在 iOS 10- Safari 中,由於視訊無法自動並內聯播放,體驗很差。要解決這個問題,可以使用 CSS 的 Media Queries:
<style>
#either-gif-or-video video { display: none; }
@media (-webkit-video-playable-inline) {
#either-gif-or-video img { display: none; }
#either-gif-or-video video { display: initial; }
}
</style>
<div id="either-gif-or-video">
<video src="image.mp4" autoplay loop muted playsinline></video>
<img src="image.gif">
</div>
由於沒有聲音的 <video>
元素可以通過呼叫 video.play()
來自動播放,並且 <video>
元素不需要插入到 DOM 中,我們還可以使用 <canvas>
來做為視訊播放的容器,這樣就可以方便地修改視訊畫面了。示意程式碼如下:
var video;
var canvas;
function startPlayback() {
if (!video) {
video = document.createElement('video');
video.src = 'image.mp4';
video.loop = true;
video.addEventListener('playing', paintVideo);
}
video.play();
}
function paintVideo() {
if (!canvas) {
canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
document.body.appendChild(canvas);
}
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
if (!video.paused) {
requestAnimationFrame(paintVideo);
}
}
startPlayback();
--EOF--
發表於 2016-10-07 15:20:46 ,並被新增「 Safari 、 iOS 」標籤 。檢視本文 Markdown 版本 »
提醒:本文最後更新於 788 天前,文中所描述的資訊可能已發生改變,請謹慎使用。