html5demos/demos/video.html

114 lines
3.8 KiB
HTML

<title>Video</title>
<article>
<p id="altmsg">It doesn't appear that your browser supports native video, sorry :(</p>
<p id="controls">
<input type="button" id="play" value="play">
<span id="position">00:00</span> / <span id="duration">loading...</span>
</p>
<p>Video loaded: <span id="using">loading...</span></p>
<p>Note that (at time of writing) <a href="http://webkit.org/" title="The WebKit Open Source Project">Webkit nightly</a> supports full screen mode, which will add a button above.</p>
</article>
<script>
/*
Note that this example used to contain the video inline in the HTML above.
However, since it's been understood that there's the possible risk of a race
condition (which I'll explain in a moment), it means the best way to prevent
this problem is to generate the video element attaching the events, and only
once all this is in place, assign the source and insert the element.
Other possible alternatives would be to listen on the window object for the
loadedmetadata event and to check the event.target with the element we're
interested in, but it would require the script at the top of the code -
which would block, and that's something I prefer not to do.
Another alternative is to put inline event handlers in the markup, again
this is something I prefer not to do.
I was called out by a couple of eager folk, one suggesting that what we had
before wasn't The Right Way(tm) - which frankly, ultimately, since we can't
attach the event handlers like we would anything else (though technically
an image element is subject to the same problems), I argue that there's
therefore No Right Way(tm) to achieve this. Anyway, this change is for
them. I know they'll love me a little more for it. Maybe. Perhaps. ...
*/
var container = document.getElementById('altmsg'),
video = document.createElement('video'),
source, // support will be detected
togglePlay = document.getElementById('play'),
position = document.getElementById('position'),
using = document.getElementById('using'),
ready = false,
controls = document.getElementById('controls'),
fullscreen = null;
if (video.canPlayType('video/webm')) {
source = 'assets/dizzy.webm';
} else if (video.canPlayType('video/mp4')) {
source = 'assets/dizzy.mp4';
} else if (video.canPlayType('video/ogv')) {
source = 'assets/dizzy.ogv';
}
addEvent(togglePlay, 'click', function () {
if (ready) {
video.playbackRate = 0.5;
if (video.paused) {
if (video.ended) video.currentTime = 0;
video.play();
this.value = "pause";
} else {
video.pause();
this.value = "play";
}
}
});
addEvent(video, 'timeupdate', function () {
position.innerHTML = asTime(this.currentTime);
});
addEvent(video, 'ended', function () {
togglePlay.value = "play";
});
// this used to be canplay, but really it should have been loadedmetadata - sorry folks
addEvent(video, 'loadedmetadata', function () {
video.muted = true;
ready = true;
document.querySelector('#duration').innerHTML = asTime(this.duration);
using.innerHTML = this.currentSrc;
// note: .webkitSupportsFullscreen is false while the video is loading, so we bind in to the canplay event
if (video.webkitSupportsFullscreen) {
fullscreen = document.createElement('input');
fullscreen.setAttribute('type', 'button');
fullscreen.setAttribute('value', 'fullscreen');
controls.insertBefore(fullscreen, controls.firstChild);
addEvent(fullscreen, 'click', function () {
video.webkitEnterFullScreen();
});
}
});
if (source) {
video.src = source;
console.log(video);
container.parentNode.replaceChild(video, container);
}
function asTime(t) {
t = Math.round(t);
var s = t % 60;
var m = Math.round(t / 60);
return two(m) + ':' + two(s);
}
function two(s) {
s += "";
if (s.length < 2) s = "0" + s;
return s;
}
</script>