HTML5: Introduzione al tag video

Un altro interessante elemento dell'HTML5  è rappresentato dal tag video descritto nella specifica HTML5 del W3C . In Internet Explorer 9 abbiamo il supporto anche per questo elemento in aderenza alle specifiche del W3C a cui collabora anche Microsoft stessa ed anche in questo caso il nuovo engine di IE9 consente di sfruttare l'accelerazione grafica anche per questo elemento. Un esempio di utilizzo del tag video per lo sviluppo di applicazioni multimediali lo trovate in questo esempio dedicato a questo aspetto del supporto HTML5 di IE9 nel test drive center di Internet Explorer.

Il tag video consente di inserire direttamente nell'HTML della nostra pagina un elemento di tipo video e permette di controllarne la riproduzione attraverso il JavaScript. I vari browser che implementando il tag offrono anche direttamente una pulsantiera di controlli per i classici controlli di riproduzione(play, pause, etc) ed è possibile anche gestire la costruzione di una barra di comandi personalizzata.

Come prima cosa voglio specificare che il tag video ad oggi permette di gestire in modo standard solo gli scenari di progressive download e non tutti i browser implementando la stessa tipologia di formato video in quanto nella specifica non sono indicati gli aspetti relativi appunto al formato, anche se al momento il formato maggiormente diffuso è H264/AAC in un container .mp4 . Non c'è supporto nella parte standard per lo streaming Live o per protocolli adattativi come ad esempio lo Smooth Stremaming,  e  per la protezione dei contenuti video. Per tanto con questo tag si possono gestire al momento solo alcuni tipi di scenario nella riproduzione del video, per scenari avanzati dove si vuole costruire una maggiore esperienza utente o gestire eventi live o contenuti protetti, si può utilizzare Silverlight e lo Smooth Streaming. Una introduzione allo Smooth Streaming la trovate in questo post ed in questo articolo.

Inserire il tag video in una pagina HTML è semplice è può essere fatto come indicato nel seguente esempio:

<video id="videoElement1" src=sample.mp4 width=320 height=240 controls poster=sample.jpg> Video not supported</video>  

 Attraverso la proprietà src si può indicare l'url del video da riprodurre. Con la proprietà autoplay  si imposta l'avvio automatico del file (basta scrivere autoplay non è necessario inserire autoplay="true" sono equivalenti), con poster si indica l'url dell'immagine da mostrare caricata nel tag video prima del play del video, con controls si chiede al player di mostrare i controlli per play\pause ect , con loop si può mandare in loop la riproduzione del video, con height e width si impostano le dimensioni , con preload si può stabilire il tipo di preload che il browser fa del video  ( none nessun preload, metadata solo i metadati, auto il browser può avviare il download dell'intero file).

 Si può accedere ai metodi ed alle proprietà dell'elemento anche via JavaScript accedendo direttamente all'oggetto nel DOM ad esempio con un getElementById. Relativamente al tag precedente a cui abbiamo dato il nome videoElement1 per eseguire un play sull'elemento per far partire il video si può usare il seguente codice:

var myVideo = document.getElementById("myVideo");

myVideo.play();

Oppure ad esempio, si può spostare la posizione del video attraverso la proprietà currentTime ad un valore specifico :

var myVideo = document.getElementById("myVideo");

myVideo.currentTime = document.getElementById ("time").value;  

o con la proprietà duration si può accedere alla durata del video caricato nell'elemento. La stessa proprietà currentTime può essere utilizzata, ad esempio, per mostrare dei contenuti solo durante degli intervalli specifici di tempo durante la riproduzione del video, per gestire ad esempio, dei sottotitoli o delle inserzioni pubblicitarie. Di seguito un banale esempio di utilizzo che moetra un div solo in uno specifico intervallo di tempo, usanto un interval che punta ad usa funzione specifica:

<div style="visibility:hidden" id=msg>Messaggio</div>
<script>

var starttime=2; var endtime=3;
var video = document.getElementsByTagName('video')[0];
var msg = document.getElementById('msg');
var msgstart = msg.getAttribute('starttime');
var msgend = msg.getAttribute('endtime');

setInterval(function() {
var hasHidden = msg.hasAttribute('hidden');
if (video.currentTime > msgstart && video.currentTime < msgend) {
msg.style.visibility="visible" }

else {
msg.style.visibility='"hidden";
}
}, 100);
</script>
 

Si tratta ovviamente di un esempio molto semplice per spiegare il concetto di utilizzo della proprietà currentTime per questo tipo di scenari , che poi può ovviamente ssere esteso e generalizzato in applicazioni più complesse o che , ad esempio , utilizzano un canvas sovrapposto al video per permettere ad esempio, la comparsa di banner pubblicitari animati , in specifici momenti della riproduzione del video.

Attraverso la proprietà error si può accedere all'errore incontrato durante la riproduzione del video e con la proprietà readyState si può accedere allo stato del tag video.

Si possono controllare le dimensioni del video con le proprietà classiche dell'elemento width and height e con le stesse si può gestire il full screen allargando il video all'intera dimensione del browser.

L'elemento espone anche una serie eventi che possono essere usati come ad esempio onplay che ci permette di agganciare una funzione da eseguire all'inizio del play, abbiamo poi ad esempio onended che permette di ricevere l'evento di fine video onseeking e onseeked che permette di capire quando è in corso un seeking sul video e quando è terminato e molti altri eventi ancora.

Ad esempio per agganciare l'evento di fine video alla funzione test direttamente inline:

  <video src="fish.mp4" autoplay controls onerror="fallback(this)" onended="test(this)">

oppure si può ovviamente farlo agganciando l'evento direttamente via JavaScript con addEventListener .

Per un elenco esaustivo delle proprietà  , metodi e degli eventi vi consiglio di riferirvi direttamente alla specifica .

Come vedete dall'esempio precedente anche per questo tag html5 si possono inserire all'interno del  tag i contenuti alternativi per i browser che non supportano il tag video. In particolare per gestire il fallback per i browser che non implementano il tag video si può inserire un player alternativo come ad esempio un player basato su Silverlight.

Genericamente si imposta anche il metodo onerror per gestire anche le eccezioni che si possono generare su quei browser che implementano il tag ma ad esempio non sono compatibili con il codec utilizzato nel video e quindi si può gestire il fallback in questo modo:

<html>
<head>
<title></title>

     <style type="text/css">
html, body {
height: 100%;
overflow: auto;
}
body {
padding: 0;
margin: 0;
}
#silverlightControlHost {
height: 100%;
text-align:center;
}
</style>
<script type="text/javascript" src="Silverlight.js"></script>
<script type="text/javascript">
function onSilverlightError(sender, args) {
var appSource = "";
if (sender != null && sender != 0) {
appSource = sender.getHost().Source;
}

            var errorType = args.ErrorType;
var iErrorCode = args.ErrorCode;

            if (errorType == "ImageError" || errorType == "MediaError") {
return;
}

            var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

            errMsg += "Code: " + iErrorCode + " \n";
errMsg += "Category: " + errorType + " \n";
errMsg += "Message: " + args.ErrorMessage + " \n";

            if (errorType == "ParserError") {
errMsg += "File: " + args.xamlFile + " \n";
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
else if (errorType == "RuntimeError") {
if (args.lineNumber != 0) {
errMsg += "Line: " + args.lineNumber + " \n";
errMsg += "Position: " + args.charPosition + " \n";
}
errMsg += "MethodName: " + args.methodName + " \n";
}

            throw new Error(errMsg);
}

function fallback(video) {
while (video.firstChild) {
if (video.firstChild instanceof HTMLSourceElement) {
video.removeChild(video.firstChild);
} else {
video.parentNode.insertBefore(video.firstChild, video);
}
}
video.parentNode.removeChild(video);
}
</script>
</head>
<body>

   <video src="fish.mp4" autoplay controls onerror="fallback(this)">
   

    <div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ProgressiveDownloadPlayer.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50401.0" />
<param name="autoUpgrade" value="true" />
<param name="InitParams" value="mediaurl=fish.mp4" />
<a href="
https://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0 " style="text-decoration:none">
<img src="
https://go.microsoft.com/fwlink/?LinkId=161376 " alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>

   </video>

</body>
</html>

Nel caso  in cui il browser non supporta il tag video, viene caricato automaticamente il player Silverlight e sarà lui ad effettuare la riproduzione dle video. Nel caso in cui il browser supporta il tag video ma, ade sempio, non supporta il formato del video, il tag video genera l'evento onerror e viene quindi eseguita la funzione fallback  che rimuove il tag video dal DOM e fa caricare il player alternativo che riprodurrà così il video.

E' eventualmente possibile utilizzare il JavaScript e delle specifiche API per poter determinare via script se il tag video è supportato o meno :

function supports_video() {
return !!document.createElement('video').canPlayType;
}

 Come abbiamo già detto prima per poter riprodurre il video il nostro tag video deve fare almeno tre cose contemporaneamente:

1.Interpretare il formato contenitore per scoprire quali tracce video e audio sono disponibili, e il modo in cui sono memorizzati all'interno del file in modo che possa trovare i dati necessari per decodificare prossimo
2.Decoding il flusso video e la visualizzazione di una serie di immagini sullo schermo
3.Decoding il flusso audio e l'invio del suono agli altoparlanti

 I principali formati che sono implementati non tutti allo stesso tempo, dai diversi browser che implementano in tag video HTML5 sono tre e sono i seguenti:

 - H.264 video + AAC audio in an MP4 container

- Ogg Theora (video) + Vorbis (audio) in Ogg container

 - Wbem VP8(video) + Vorbis (audio) in wbem container

 

Internet Explorer 9 supporta nativamente il primo e con l'istallazione di codec aggiuntivi permette di riprodurre i contenuti anche negli altri formati. Il formato più comune e oggi su Internet anche oltre il tag video HTML5 è sicuramente il formato H.264 video + AAC audio in an MP4 container  . 

 Per determinare i formati video supportati dal browser su cui si esegue la nostra pagina, il tag video espone anche un metodo canPlayType  che consente di verificare se uno specifico formato è supportato dal browser : 

 videoElement1.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');

Il metodo torna indietro =="" in caso di formato non supportato e =="probably" quando il browser è confidente di poter riprodurre il formato. E' opportuno anche in caso di risposta di probabile possibilità di riproduzione del contenuto proposto, agganciare l'evento enerror e gestire il fallback con il player basato su pluging come ad esempio Silverlight  in quanto non è comunque sicura la riproduzione , dato uno specifico codec, possono esserci problemi di coincompatibilità o limiti nella risoluzione , nel numero di frame o nel livello di bitrate del file. Di seguito abbiamo un esempio di funzione della verifica del probabile supporto di un formato h264 baseline da parte del browser che esegue la nostra pagina:

function supports_h264_baseline_video() {
if (!supports_video()) { return false; }

var v = document.createElement("video");
return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
}

In maniera simile a quanto abbiamo visto per il canvas, possiamo anche utilizzare la libreria Modernzr sia per verificare il supporto del tag video sia per la verifica dei codec. Di seguito un esempio di utilizzo:

if (Modernizr.video) {
if (Modernizr.video.webm) {
// try WebM
}
else if (Modernizr.video.ogg)
{ // try Ogg Theora + Vorbis in an Ogg container }
else if (Modernizr.video.h264){
// try H.264 video + AAC audio in an MP4 container }
}

 Per gestire la riproduzione  in maniera da poter supportare browser che implementano formati diversi ,oltre al fallback sul plugin, si può anche decidere di codificare il video in formati diversi e di appendere più src ai differenti formati come da esempio:

 
<video width="400" height="300" poster="frame.png" autoplay controls loop>
<source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<source src="video.ogv" type='video/ogg; codecs="theora, vorbis"'>
</video>

il browser seleziona i diversi formati e riproduce quello idoneo, generando un onerror nel caso in cui nessuno dei formati indicati sia supportato. 

Una buona libreria per gestire player HTML5 con il fallback su uno dei plugin è sicuramente mediaelement.js e qui trovate un elenco con il confronto tra varie librerie disponibili.  

Codificare i video in formati diversi per permetterne la riproduzione su browser differenti non è una operazione semplice e comoda, comporta una maggiore spesa sia di tempo di preparazione dei contenuti , sia di storage. Si complica inoltre, lo sviluppo della pagina. Il suggerimento è quello di prevedere un unico formato basato su H264  e AAC in un container .mp4 che è il formato tipicamente più diffuso e gestire il fallback con un plugin come Silverlight. Il tag video permette di gestire solo gli secanri più semplici di riproduzione in progressive download e come già detto non supporta ne streaming adattatico , ne live streaming ne tantomeno la protezione dei contenuti con un DRM. Ad oggi i player basati su plugin come ad esempio Silverlight, anche per la sola riproduzione in progressive download offrono una maggiore semplicità e uniformità di riproduzione su browser e SO differenti, consentendo anche la protezione con Microsft Playready , lo streaming adattativo con lo Smooth Streaming e anche il live streaming. Anche se il tag video comincia ad avere una sua applicabilità negli scenari più semplici di progressive download senza protezione e per contenuti che non hanno lunghezza eccessiva e bitrate elevati , per i quali è meglio utilizzare uno streaming adattativo come lo Smooth Streaming con Silverlight. Anche negli scenari mobile lo streaming adattativo permette di fornire una migliore user experience durante la riproduzione.

Per produrre i contenuti video in H264/AAC in .mp4 si possono utilizzare diversi tipi di encoder. La maggioranza degli encoder disponibili è in grado di produrre contenuti in questo formato che è tra i più utilizzati. Si può utilizzare anche Expression Encoder 4 Pro per produrre file .mp4 per il tag video ed avere al tempo stesso un encoder in grado di produrre anche contenuti Smooth Streaming. In un successivo post illustrerò un breve tutorial per utilizzare Expression Encoder 4 Pro per codificare contenuti in .p4 utilizzabili con il tag video HTML5.  Vi invito a prestare attenzione al fatto che solo nella versione full del prodotto sono presenti i codec H264, nella trial e nella versione che trovate in msdn non sono presenti, occorre appunto la versione full. Expression Encoder 4 è anche utilizzabile come encoder per il Live Smooth Streaming in combinazione con IIS Media Services e Silverlight consentendo anche lo streaming Live e on demand non solo per Silverlight  PC e MAC ma anche per per i device Apple e Windows Phone 7. In particolare su Windows Phone 7 si può usare lo specifico Smooth Streaming Media Element per la riproduzione dei contenuti Smooth Streaming.

Per la distribuzione dei contenuti video in progressive download si può utilizzare un qualunque server web. Per una maggiore efficienza e per ridurre ed ottimizzare il consumo di banda per la distribuzione di contenuti in progressive download, vi  suggerisco di prendere in considerazione IIS con gli IIS Media Services. IIS Media Services è una estensione di IIS che si scarica e si installa in modo gratuito dal sito deidicato e che   oltre a permettervi anche  l'utilizzo dello Smooth Streaming live e ondemand, offre una interessante funzionalità per il progressive downaload anche per file .mp4 che si chiama Bit Rate Throttling che consente di controllare il consumo di banda portandolo al livello del bitrate con cui è codificato il file, permettendo un significativo risparmio di banda e una maggiore ottimizzazione della stessa. Maggiori informazioni sull'utilizzo le trovate in questo mio post sulla specifica funzionalità e nell'area del sito di IIS MS dedicata a questa feature

 Oltre al tag video nella specifica HTML5 abbiamo anche il tag audio che ha un funzionamento molto simile a quanto visto per il video e serve essenzialmente a riprodurre contenuti audio. Il formato più comune per i contenuti audio è .mp3 e wav.