HTML5 video

Simon Pieters

Opera Software

2010-02-16

Innehåll

Om Opera, Om mig, Demos, Historia, Hur video fungerar, Codec-krig, Konvertera format, .htaccess, Video-elementet, Audio-elementet, Source-elementet, DOM API, Events, Canvas, Sökning, CSS, Fallback

Om Opera

Mobile, Mini, Desktop, Devices, Widgets...

Kontor

Norge, Kina, Tjeckiska Republiken, Indien, Japan, Polen, Sydkorea, Sverige, Taiwan, USA.

Kunder

AirTies, Amino, Archos, Asus, Casio, Cisco, Fly, Ford, Hitachi, HTC, Importec, Iplus Technology, Iwatsu, Kocom, Kyocera, Motorola, NDS, Nintendo, Nokia, Nvidia, Palm, Pirelli, Philips, Posbro, Q-MATIC, SAGEM, Samsung, Sanyo, Sharp, Sonim, Sony, Sony Ericsson, Spice, Telsey, Ten by Orange, Thales, Thomson, Tilgin, Toshiba, Tranzas, UIQ Technology, USEN, VeriFone, Vestel, Yahoo!, Westell, Wistron, ZiiLABS, ZTE, ZyXEL Communications.

Om mig

2005: WHATWG

2007: Sommarjobb Opera

2007: Anställning Opera

Specifikationer

HTML5, ARIA, xml-stylesheet, Web DOM Core.

Kvalitetssäkring

Testsvit för video.

Demos

opera, YouTube, vimeo, Wikipedia, metavid, Dailymotion, mozilla, 9elements, simon

demo/

Historia

Windows Media Player, QuickTime, RealPlayer, Adobe Shockwave Player.

Historia

Flash.

Historia

[whatwg] <video> element proposal, annevk at opera.com, Feb 28, 2007. Hi, Opera has some internal builds with an implementation of a <video> element. The element exposes a simple API (for the moment) much like the Audio() object: play() pause() stop()

Historia

Safari, Firefox, Chrome.

Hur video fungerar

Container

Video-codec

Audio-codec

Container-format

Ogg

MPEG-4

Video-codec

Theora

H.264

H.264

Baseline profile

Main profile

High profile

Audio-codec

Vorbis

AAC

AAC

Low complexity profile

Main profile

Scalable sampling rate profile

Codec-krig

SafariFirefoxChromeOperaiPhoneAndroid
Ogg
MP4

Codec-krig

YouTubevimeometavidWikipedia
Ogg
MP4

Google köper On2

On2, Google.

Konvertera format

Firefogg

Handbrake

diveintohtml5.org

.htaccess

AddType video/ogg .ogv
AddType audio/ogg .oga .ogg
AddType video/mp4 .mp4

Video-elementet

<video src="test.ogv">
</video>

Attribut för video

<video
 src="test.ogv"
 poster="test.jpg"
 autobuffer
 autoplay
 loop
 controls
 width="320"
 height="240">
</video>

boolean-attribut

<video loop>
<video loop="">
<video loop="loop">

Audio-elementet

<audio
 src="test.oga"
 autobuffer
 autoplay
 loop
 controls>
</audio>

Source-elementet

<video>
 <source src="test.ogv"
         type="video/ogg">
 <source src="test.mp4"
         type="video/mp4">
</video>

Attribut för source

<source
 src="test.ogv"
 type="video/ogg"
 media="all and (device-min-height:720px)">

DOM API

width height videoWidth videoHeight poster error src currentSrc networkState autobuffer buffered load() canPlayType() readyState seeking currentTime duration paused defaultPlaybackRate playbackRate played seekable ended autoplay loop play() pause() controls volume muted

Skapa media-element

var video = document.createElement('video');
video.src = 'test.ogv';

var audio = new Audio('test.oga');

Lägg till i dokument

document.body.appendChild(video);

videoWidth & videoHeight

video.onloadedmetadata = function(e) {
  video.width = 3 * video.videoWidth;
}

error

if (video.error)
 alert(video.error.code);
video.error.MEDIA_ERR_ABORTED
video.error.MEDIA_ERR_NETWORK
video.error.MEDIA_ERR_DECODE
video.error.MEDIA_ERR_SRC_NOT_SUPPORTED

currentSrc

<video onloadedmetadata="alert(currentSrc)">
 <source src="test.ogv"
         type="video/ogg">
 <source src="test.mp4"
         type="video/mp4">
</video>

networkState

video.NETWORK_EMPTY
video.NETWORK_IDLE
video.NETWORK_LOADING
video.NETWORK_NO_SOURCE

buffered, played & seekable

alert(video.buffered.length);
alert(video.buffered.start(0));
alert(video.buffered.end(0));

load()

video.src = 'video2.ogv'; // inget load() behövs

load()

source1.src = 'video2.ogv';
source2.src = 'video2.mp4';
video.load();

canPlayType()

"", "maybe" eller "probably"

alert(video.canPlayType('video/ogg'));
alert(video.canPlayType('video/ogg; codecs="theora, vorbis"'));

readyState

video.HAVE_NOTHING
video.HAVE_METADATA
video.HAVE_CURRENT_DATA
video.HAVE_FUTURE_DATA
video.HAVE_ENOUGH_DATA

seeking

alert(video.seeking);
video.currentTime = 5;
alert(video.seeking);

currentTime

alert(video.currentTime);
video.currentTime = 5;
alert(video.currentTime);

startTime

Är 0 i vanliga fall

Streaming kan vara > 0

duration

NaN: okänd

Infinity: streaming (eller okänd)

Videons längd i sekunder

paused

true om videon är pausad

defaultPlaybackRate & playbackRate

1.0: normal hastighet

0.5: slow motion

2.0: snabbspola

-1.0: spela baklänges

ended

true om videon har spelat klart

autobuffer, autoplay, loop, controls

video.loop = true;

video.setAttribute('loop', 'loop');

<video loop="loop">

autobuffer, autoplay, loop, controls

video.loop = false;

video.removeAttribute('loop');

<video>

volume, muted

volume: 0.0 .. 1.0

muted: true/false

Events

loadstart progress suspend abort error emptied stalled play pause loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange

Event-lyssnare

video.onloadstart = function(e) {}
video.addEventListener('loadstart', function(e) {}, false);
<video onloadstart=""></video>

loadstart

Första steget i processen att hitta src/source

progress

Några bytes har hämtats.

suspend

Webbläsaren väntar med att hämta mer data.

abort

Webbläsaren avbryter hämtning av data.

error

Ett fel har inträffat.

video.onerror = function(e) {
 alert(video.error.code)
}

emptied

Ett fatalt fel har inträffat eller load() har körts.

video.networkState == video.NETWORK_EMPTY

stalled

Servern slutar temporärt att ge data.

video.networkState == video.NETWORK_LOADING

play

Användaren klickar på play eller play() har körts.

video.paused == false

pause

Användaren klickar på pause eller pause() har körts.

video.paused == true

loadedmetadata

Webbläsaren vet dimensioner och längd på videon.

video.readyState == video.HAVE_METADATA

loadeddata

Webbläsaren kan rita nuvarande frame för första gången.

video.readyState == video.HAVE_CURRENT_DATA

waiting

Webbläsaren stannar för nästa frame är inte tillgänglig ännu.

video.readyState <= video.HAVE_CURRENT_DATA

playing

Webbläsaren börjar spela.

canplay

Webbläsaren kan spela en bit.

video.readyState == video.HAVE_FUTURE_DATA

canplaythrough

Webbläsaren kan spela hela vägen utan att stoppa.

video.readyState == video.HAVE_ENOUGH_DATA

seeking

Sökning i videon pågår.

video.seeking == true

seeked

Sökning är färdig.

video.seeking == false

timeupdate

Skickas hela tiden medan videon spelar.

ended

Videon har spelat klart.

video.ended == true

durationchange

Videons längd har ändrats (från okänd till känd eller från gissning till mer precis).

volumechange

Användaren ändrar volym eller volume eller muted har ändrats med skript.

Canvas

drawImage, createPattern

Sökning

HTTP/1.1 206 Partial Content
Accept-ranges: bytes
Content-range: bytes 123000-3456000/4567000

Ange duration

MPEG-4: metadata i början

Ogg: metadata i slutet

HTTP Content-Duration header

CSS

video {
 box-shadow:0 5px 10px black;
 -o-transition:1s width;
 -o-image-fit:fill;
 width:400px;
 height:300px;
}
video:hover {
 width:800px;
}

Fallback

<video controls src="video.ogv">
 <a href="video.ogv">video</a>
</video>

Fallback: Flash

<video controls src="video.mp4">
 <object data="video.swf">
  <a href="video.mp4">video</a>
 </object>
</video>

Fallback: Cortado Java applet

<video controls src="video.ogv">
 <object type="application/x-java-applet" width="480" height="288">
  <param name="archive" value="cortado-ovt-stripped-wm_r51500.jar">
  <param name="code" value="com.fluendo.player.Cortado.class">
  <param name="url" value="video.ogv">
  <a href="video.ogv">video</a>
 </object>
</video>

Fallback: codec stöds ej

function fallback(v) {
 while (v.firstChild) {
  if (v.firstChild.nodeName
       == 'SOURCE')
   v.removeChild(v.firstChild);
  else
   v.parentNode.insertBefore
    (v.firstChild, v);
 }
 v.parentNode.removeChild(v);
}

Fallback: codec stöds ej

<video controls src="video.ogv" onerror="fallback(this)">
 ...
</video>

Fallback: codec stöds ej

<video controls>
 <source src="video.ogv"
         type="video/ogg">
 <source src="video.mp4"
         type="video/mp4"
         onerror="fallback(parentNode)">
 ...
</video>

Tack

Frågor?