Original address: webkit.org/blog/6784/n…
@jernoble
If you are familiar with ios development, in iphoneOS 3, safari only allows users to interact with video and trigger data loading. But in an effort to put more media playback control back into the hands of web developers, iOS 8 relaxes this: Safari is starting to support the preload=”metadata” attribute, which allows the
The reason
As it turns out, people love giFs. But compared to modern video codecs such as H.264, the GIF format is far less cost-effective than encoding animated images. We found that giFs can have up to twelve times the bandwidth. This is very expensive, and many of the largest GIF providers have moved from GIF to
But while this move can save websites bandwidth costs as well as users’ batteries. But you also have to pay some costs. On iOS 9,
Note about user gesture requirements: Call JavaScript when we say that an action must occur “as a result of a user gesture.” For example: Video.play () must be triggered when the user triggers a Touchend, click, Doubleclick, or KeyDown event. So,
button.addEventListener('click', () => {
video.play();
})
Copy the code
while
video.addEventListener('canplaythrough', () => {
video.play();
})
Copy the code
Will not trigger play.
Similarly, web developers can do some amazing things by integrating
elements into their pages. And since there are no user gestures required, these pages don’t work on iOS at all, or the
element doesn’t work as a full-screen background for animations.
WebKit’s new strategy
Starting with iOS 10, WebKit has relaxed its built-in and autoplay strategies to allow for some effects, but you still need to consider the user’s traffic and battery consumption.
By default, WebKit will have the following policies:
<video autoplay>
Element autoplay can now trigger if it meets the following conditions:
-
Elements will be allowed toplay without user gestures if their source media does not contain audio tracks.
-
autoplay is also allowed when muted
-
If a
element acquires a track or is not muted without a user gesture, playback is paused.
-
elements can only start playing when they are visible on the screen, such as when they are scrolled into the viewport, visible through CSS, and inserted into the DOM.
-
< Video autoplay> If the element becomes invisible, for example by scrolling out of the viewport, the element will be paused.
<video>
Elements can now implement play() with elements that satisfy the following conditions:
-
play() If their source media does not contain an audio track, or if their fraternal attribute is set, elements will be allowed to play without triggering a gesture.
-
If a
element gets a track or becomes unmuted without a user gesture, playback is paused.
-
The
element allows play() when it is not visible on the screen or outside the viewport.
-
Video.play () will return a Promise and will be rejected if any of these conditions are not met.
-
On the iPhone, the < Video Playsinline > element can now play online and does not automatically go into full-screen mode at the start of playback.
-
Elements without the playsinline attribute continue to play in full screen mode.
-
Playsinline does not continue with the
element when gestured to exit full screen.
For clients with the WebKit framework on iOS, these policies can still be controlled through apis to meet their specific needs. About automatic broadcast strategy more fine-grained control, please refer to the new mediaTypesRequiringUserActionForPlayback WKWebViewConfiguration attribute. Safari on iOS 10 will use WebKit’s default policy.
A note on the Playsinline property: This property has recently been added to the HTML specification, and WebKit has modified it by undoing its old WebKit-Playsinline property. This property has been supported since iPhoneOS 4.0, and we are happy to be able to do unmodified webkit-playsinline according to our updated unmodified policy. Unfortunately, this change did not expire in iOS 10 Developer Seed 2. If you want to experiment with this new policy using iOS Developer Seed 2, the prefix attribute will work, but we encourage you to switch to undefined attributes until they are available in the future.
example
How can we as developers take advantage of these new policies? Suppose you have a blog post or a post with many GIFs that are more likely to be used as
elements. Here is an example of a simple GIF substitution:
<video autoplay loop muted playsinline>
<source src="image.mp4">
<source src="image.webm" onerror="fallback(parentNode)">
<img src="image.gif">
</video>
Copy the code
function fallback(video)
{
var img = video.querySelector('img');
if (img)
video.parentNode.replaceChild(img, video);
}
Copy the code
On iOS 10, if no
source is not supported, giFs can be provided for playback.
If your page design requires different behavior, allow inline playback, while when full-screen playback is required, use the -webkit-video-playable-inline media query to distinguish between the two:
<div id="either-gif-or-video">
<video src="image.mp4" autoplay loop muted playsinline></video>
<img src="image.gif">
</div>
Copy the code
#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; }}Copy the code
These new policies mean that more advanced uses of elements are possible, such as drawing
using
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); }Copy the code
<button onclick="startPlayback()">Start Playback</button>
Copy the code
The same method can be used to render for WebGL. Note that in this example, the user’s gesture (click event) is required because the
element is not in the DOM and therefore not visible. A
These new policies really enable video to enhance the interaction and design of our site without reducing users’ broadband and battery consumption. For more information, please contact @Jernoble, AppleWorks Web Technology evangelist Jonathan Davis, @Jonathandavis or @webKit.