Supporto audio e video in Silverlight 3.0

di Cristian Civera, in Silverlight,


Questo articolo è tratto dal capitolo 13 (Supporto ad audio e video) del libro Silverlight 3.0 - Guida Completa di Daniele Bochicchio, Cristian Civera, Alessio Leoncini e Marco Leoncini.

Acquista subito la tua copia!

La crescente disponibilità di banda ha favorito la diffusione di contenuti multimediali attraverso il web, a tal punto che ormai qualsiasi sito offre video on demand oppure in streaming.
Nel passato, per usufruire di un video o di un audio occorreva avere a disposizione il relativo player installato: si trattava spesso di un'applicazione molto pesante, che non favoriva un facile approccio per l'utente comune.
In questo senso, la tecnologia offerta da Adobe con Flash ha contribuito moltissimo ad uniformare, con un unico e leggero plug-in, l'accesso a questo tipo di contenuti e, allo stesso tempo, ha consentito il nascere di nuovi tipi di codifica e compressione audio/video, che hanno reso meno onerosa la diffusione tramite HTTP, permettendo di mantenere sempre una buona qualità.
Silverlight è stato esplicitamente pensato come una proposta alternativa in questo settore, tanto è vero che la prima versione forniva soprattutto funzionalità da player e poco altro.
Con le successive versioni, sono state introdotte nuove caratteristiche, in modo da rendere il plug-in adatto anche ad applicazioni ad alto impatto visivo, di tipo RIA, ma cercando di inserire caratteristiche innovative, come il supporto ai contenuti ad alta definizione, oppure lo smooth streaming (un sistema adattivo ai carichi della rete e alle capacità del client, per poter usufruire on demand o live di flussi audio e video senza interruzioni nè buffering).
In questo capitolo vedremo quindi come incorporare audio e video nelle nostre applicazioni, quali sono i formati supportati, le possibilità di interazione e di estensione.
In questo senso esistono tecnologie di contorno che permettono di trarre il massimo da Silverlight, come Expression Encoder, un tool che ci permette di preparare e codificare flussi audio e video nei più famosi formati, ottenendo gratuitamente un player completo di tutte le funzionalità.
Dal punto di vista della distribuzione, i Media Services di IIS forniscono dei servizi aggiuntivi per Internet Information Services 7.0 o 7.5, che permettono il download di contenuti multimediali in modo adattivo.
Ma prima di addentrarci in questi dicorsi, vale la pena analizzare le funzionalità di base.

Il controllo MediaElement

Silverlight, per usufruire di contenuti multimediali, offre uno specifico elemento di nome MediaElement.
Di fatto è un normale UIElement, che possiamo posizionare all'interno del markup, trasformandolo con Projection o RenderTransform, rendendolo partecipe del sistema di posizionamento in relazione agli altri elementi.

La proprietà principale di questo controllo è Source, che ci permette di indicare l'URI del file da caricare.
I protocolli consentiti sono HTTP per il normale download e MMS per lo streaming dai Window Media Services, con la libertà di usufruire di contenuti anche non appartenenti al nostro dominio e senza la necessità di file di policy.
Ci è concesso anche di incorporare il video come risorsa, allo stesso modo in cui procediamo con le immagini.
Ovviamente questo comporta l'incremento dell'intero pacchetto XAP, aumentando i tempi d'attesa per l'inizializzazione dell'intera applicazione.
Nell'esempio 1 vediamo come dichiarare questo controllo per caricare un semplice video.

Esempio 1 - XAML
<MediaElement Source="MioVideo.wmv"
              Stretch="None"
              HorizontalAlignment="Center"
              VerticalAlignment="Center" />

Se la sorgente contiene solo la traccia audio, l'elemento risulterà bianco (pur essendo udibile l'audio), perciò possiamo tranquillamente nasconderlo attraverso la proprietà Visibility, o impostarne dimensioni ridotte attraverso le proprietà Width e Height.
Qualora invece sia presente una traccia video, questa risulta visibile nell'area di competenza dell'elemento, ridimensionata in modo uniforme in base alle impostazioni della proprietà Stretch, normalmente impostata su Uniform.
Sebbene questo sia il comportamento predefinito e anche il più comodo, implica un maggiore lavoro per il motore di rendering e quindi per ottenere il massimo delle prestazioni, consigliamo di codificare il file già nella risoluzione di visualizzazione e di disattivare lo Stretch, come abbiamo fatto nell'esempio 1.
Con queste poche linee di markup otteniamo l'avvio automatico del filmato al caricamento dell'applicazione, grazie alla proprietà AutoPlay, che di default è impostata su true.
L'avvio del contenuto multimediale non è però immediato, ma dipende dal tipo di protocollo e dal contenitore utilizzato.
Nel caso di un normale file HTTP, questo viene scaricato e, non appena viene raggiunta la quantità di byte necessaria per avviarlo, il flusso parte.
Nel caso invece del protocollo MMS lo streaming comporta il download continuo dei byte, ma senza una fine del flusso.
In entrambi i casi, il processo di visualizzazione è sempre preceduto dal buffering, termine con il quale indichiamo il caricamento parziale di un contenuto multimediale, per una quantità sufficiente a garantire che il flusso di visualizzazione non venga interrotto.
Per controllare questa caratteristica, abbiamo a disposizione la proprietà BufferingTime, normalmente impostata a cinque secondi (riferiti allo stream di byte caricati e non al tempo d'attesa dell'utente).
Dobbiamo agire su di essa con molta cautela, perché tempi più lunghi mettono al riparo da interruzioni del video, ma comportano lunghe attese iniziali per l'utente.
D'altro canto, tempi più corti possono invece rendere sgradevole l'esperienza dell'utente, vittima di continue interruzioni.
Inoltre, per tenerne controllato lo stato, disponiamo della proprietà BufferingProgress, con valori che vanno da 0 a 1.
Il buffering è una tecnica usata da molto tempo, ma che non offre garanzie totali sulla fluidità della visualizzazione, dato che le condizioni della rete e della macchina dell'utente cambiano nel tempo ed è per questo motivo che la tecnologia come smooth streaming, di cui parleremo più avanti, tenta di risolvere il problema con un approccio che si adatti a questi parametri.
Infine, dato che il download del file continua mentre è in corso la visualizzazione del contenuto, possiamo intercettare lo stato di avanzamento del download mediante l'evento DownloadProgressChanged.
Con le proprietà DownloadProgress e DownloadProgressOffset possiamo poi conoscere, con un valore che va da 0 a 1,rispettivamente quanto è stato caricato e da che punto è iniziato il download (nel caso cambiamo la posizione attuale del MediaElement).
Possiamo quindi, con poche righe di markup e codice, creare una barra progressiva che mostri lo stato attuale del download, come mostrato negli esempi 2 e 3.

Esempio 2 - XAML
<MediaElement Source="MioVideo.wmv"
              x:Name="media"
              DownloadProgressChanged="media_DownloadProgressChanged" />
<Border Width="100"
        Height="10"
        Background="LightGray">
  <Rectangle Fill="Gray"
             Width="100"
             Height="10"
             x:Name="progress">
  </Rectangle>
</Border>
<TextBlock x:Name="percentage" />

Nel markup, inseriamo un bordo per delimitare la zona di riempimento, con un grigio chiaro e un rettangolo grigio per indicare la progressione che dovrebbe riempire l'intera zona a disposizione.

Esempio 3 - VB.NET
  Private Sub media_DownloadProgressChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Margine sinistro
    Dim left As Double = Media.DownloadProgressOffset * progress.Width
    ' Margine destro
    Dim right As Double = progress.Width - (Media.DownloadProgress * progress.Width) - left
    progress.Margin = New Thickness(left, 0, Right, 0)
    ' Percentuale di download
    Dim perc As Double = Math.Round(Media.DownloadProgress - Media.DownloadProgressOffset)* 100R)
    percentage.Text = perc & "%"
  End Sub
Esempio 3 - C#
void media_DownloadProgressChanged(object sender, RoutedEventArgs e)
{
  // Margine sinistro
  double left = media.DownloadProgressOffset * progress.Width;
  // Margine destro
  double right = progress.Width -
  (media.DownloadProgress * progress.Width) - left;
  progress.Margin = new Thickness(left, 0, right, 0);
  // Percentuale di download
  double perc = Math.Round(
  (media.DownloadProgress - media.DownloadProgressOffset)
    * 100d);
  percentage.Text = perc + "%";
}

Nell'esempio 3 utilizziamo i margini per restringere la zona di riempimento del rettangolo in grigio, che calcoliamo dapprima sul margine sinistro, per spostarci in base al DownloadProgressOffset, che è normalmente pari a zero.
Successivamente, calcoliamo il margine destro in base alla percentuale di download che l'utente deve ancora effettuare.
Infine, calcoliamo anche la percentuale da mostrare tramite un controllo di tipo TextBlock.
Il risultato che otteniamo è visibile nella figura seguente.

In qualsiasi momento possiamo ottenere informazioni sul file multimediale corrente: ad esempio con le proprietà NaturalVideoWidth e NaturalVideoHeight ricaviamo le dimensioni reali, in pixel fisici, del video, mentre con AudioStreamCount e AudioStreamIndex possiamo conoscere il numero dei flussi audio disponibili, presenti solitamente nei video multilingua, e impostare l'indice del flusso audio da utilizzare.

6 pagine in totale: 1 2 3 4 5 6
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti