Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Gestire l'audio del telefono

Gli oggetti e gli elementi per riprodurre suoni, anche in background
Gli oggetti e gli elementi per riprodurre suoni, anche in background
Link copiato negli appunti

L'SDK di Windows Phone consente la creazione di applicazioni in grado di riprodurre audio sia in contesti di foreground, ovvero all'interno di un'applicazione attiva e sia in background ovvero quando, da un'applicazione attiva, l'utente preme il pulsante hardware Back o Start, inviando quindi la nostra app in una stato "dormiente" ma comunque in grado di riprodurre media.

Foreground

Il modo più semplice per riprodurre audio da un'applicazione attiva è utilizzare l'oggetto MediaPlayerLauncher a cui demandare l'intero processo, un semplice utilizzo è il seguente:

MediaPlayerLauncher launcher = new MediaPlayerLauncher();
launcher.Media = new Uri("Kalimba.mp3", UriKind.Relative);
launcher.Location = MediaLocationType.Install;
launcher.Controls = MediaPlaybackControls.Pause | MediaPlaybackControls.Stop;
launcher.Orientation = MediaPlayerOrientation.Landscape;
launcher.Show();

Per provare il precedente esempio è sufficiente creare una Windows Phone Application e aggiungere il file Kalimba.mp3 (presente nella directory Sample Music di Windows 7), ricordarsi inoltre di impostare "Copy if newer" nelle proprietà del file.

Il vantaggio del MediaPlayerLauncher è sicuramente la semplicità di utilizzo, ma svolgerà il suo compito in una "finestra" esterna rispetto alla nostra applicazione: verrà infatti lanciato (da cui il nome launcher) un nuovo contesto esecutivo. Esistono però molti casi in cui non vogliamo far uscire il nostro utente dalla nostra app, si pensi lo scenario di una preview audio su una playlist, sarebbe decisamente scomodo uscire e rientrare continuamente nell'applicazione per ascoltare pochi secondi di una traccia; per questi casi la scelta migliore ricade sull'elemento MediaElement.

Per usare un controllo MediaElement basta inserirlo nel sorgente XAML, impostare la proprietà Source e AutoPlay="True" per far partire immediatamente la riproduzione del file audio.

<MediaElement Source="Kalimba.mp3" AutoPlay="True"/>

Se usiamo l'elemento MediaElement dobbiamo anche preoccuparci della realizzazione grafica dei vari pulsanti di playback: play, stop, pausa, volume ecc.ecc. Per gestire la logica di riproduzione è sufficiente usare i metodi Play, Pause e Stop sull'elemento stesso.

Nel prossimo esempio definiamo il contenuto e la logica di un semplice player audio, iniziamo creando la toolbar dei pulsanti di playback (play, stop e pausa) e il MediaElement:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  <Button Content="Play" Height="122" HorizontalAlignment="Left" Margin="0,6,0,0" Name="Play"
          VerticalAlignment="Top" Width="148" Click="Play_Click" />
  <Button Content="Pause" Height="122" HorizontalAlignment="Left" Margin="154,6,0,0" Name="Pause"
          VerticalAlignment="Top" Width="149" Click="Pause_Click" />
  <Button Content="Stop" Height="122" HorizontalAlignment="Left" Margin="309,6,0,0" Name="Stop"
          VerticalAlignment="Top" Width="147" Click="Stop_Click" />
  <MediaElement Name="mediaElement1" Source="Kalimba.mp3" AutoPlay="False"/>
</Grid>

Il codice di code-behind non presenta particolari difficoltà:

private void Play_Click(object sender, RoutedEventArgs e)
{
  mediaElement1.Play();
}
private void Pause_Click(object sender, RoutedEventArgs e)
{
  mediaElement1.Pause();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
  mediaElement1.Stop();
}

È importante evidenziare che la proprietà Source del controllo può essere impostata verso un url remoto, per la riproduzione sia di contenuti singoli che di streaming (web radio).

Da notare che il controllo MediaElement partecipa al processo di layout della page Silverlight, esattamente come una listbox o un button, ha infatti proprietà di layout come Margin, Width, Height, HorizontalAlignment e VerticalAlignment. Potremmo chiederci il perchè di tale scelta visto che la riproduzione di un file audio non ha bisogno di tali caratteristiche; la spiegazione è semplice: MediaElement può essere utilizzato per la riproduzione di contenuti video, le modalità sono identiche rispetto a quanto abbiamo capito per la parte audio.

Vi suggerisco inoltre di leggere la tabella comparitiva Supported Media Codecs for Windows Phone, per capire quali tipologie di file audio e video sono supportate dal device e dalle API.

Background

Dalla versione 7.5 di Windows Phone è possibile riprodurre audio in background, ciò significa che la nostra applicazione, anche dopo un'uscita seguente alla pressione del pulsante hardware Back o Start, è in grado di continuare il playback dei contenuti.

Una Background Audio Application sfrutta i meccanismi dei background agent, novità di Windows Phone 7.5 che vedremo meglio più avanti parlando del multitasking

.

Tutti i media su Windows Phone sono gestiti attraverso un unico oggetto del sistema operativo chiamato Zune Media Queue, la nostra applicazione invierà i comandi a Zune Media Queue per svolgere le attività di playback (play, stop, fast forward ecc.), dal punto di vista programmatico il nostro entry point è rappresentato dalla classe BackgroundAudioPlayer.

Quando un'applicazione in background riproduce un media, il device prevede un set di controlli di user interface per consentire all'utente le attività base di gestione volume, play/pause e vai al contenuto precedente/successivo. Tali controlli sono chiamati Universal Volume Control (UVC) e vengono visualizzati nel lock screen o alla pressione dei pulsanti hardware del volume.

Esistono due tipologie di Background Audio Application: la prima prevede la gestione di una playlist di contenuti da riprodurre in background, l'altra tipologia invece consente la riproduzione di uno stream audio in background. Per semplificare la trattazione in questo articolo ci concentreremo solo sulla prima tipologia.

Nella successiva figura vengono evidenziati tutti i componenti che definiscono una soluzione completa di background audio per una playlist application.

Figura 1. Componenti di una Playlist Application
(clic per ingrandire)

Componenti di una Playlist Application

In verde sono evidenziati i componenti di nostro dominio mentre in bianco gli oggetti gestiti dal sistema operativo del device.

È importante comprendere che una soluzione di background audio è costituita da due progetti distinti, un classico progetto di user interface e uno speciale progetto di background agent che conterrà il codice in grado di girare in background; come si può notare dallo schema entrambi i componenti lavoreranno con la classe BackgroundAudioPlayer che rappresenta il proxy verso Zune Media Queue.

Visual Studio ci semplificherà la creazione del background agent grazie al template Windows Phone Audio Playback Agent

Figura 2. Windows Phone Audio Playback Agent
(clic per ingrandire)


Windows Phone Audio Playback Agent

In tale progetto Visual Studio creerà l'infrastruttura necessaria al nostro compito, troviamo infatti una classe che deriva da AudioPlayerAgent, tale classe verrà instanziata dal sistema operativo per gestire le azioni richieste dall'utente, sia tramite la user interface della nostra applicazione che tramite UVC (Universal Volume Control). La nostra classe inoltre, tramite un'instanza di BackgroundAudioPlayer, invierà i comandi di riproduzione a Zune Media Queue.

Gli override importanti della nostra AudioPlayerAgent sono:

  1. OnPlayStateChanged
    1. Invocato al cambiamento dello stato di playback (es: quando termina la track o quando la traccia è pronta per la riproduzione)
  2. OnUserAction
    1. Chiamato a fronte di una esplicita richiesta dell'utente (es: l'utente richiede la pausa o la successiva track)
  3. OnError
    1. Si verifica a fronte di un errore nella riproduzione (es: una traccia non è stata scaricata correttamente)

È importante notificare al sistema operativo che il nostro agent ha finito il suo compito tramite la chiamata al metodo NotifyComplete, in modo da rilasciare le risorse allocate.

Segue un semplice esempio di implementazione dell'override di OnUserAction, notare la chiamata a NotifyComplete al termine:

protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
{
  switch (action)
  {
    case UserAction.Play:
	  if (player.PlayerState != PlayState.Playing)
	  {
	    player.Play();
	  }
    break;
	case UserAction.Stop:
	  player.Stop();
	  break;
	case UserAction.Pause:
	  player.Pause();
	  break;
    case UserAction.FastForward:
	  player.FastForward();
	  break;
	case UserAction.Rewind:
	  player.Rewind();
	  break;
	case UserAction.Seek:
	  player.Position = (TimeSpan)param;
	  break;
	case UserAction.SkipNext:
	  player.Track = GetNextTrack();
	  break;
	case UserAction.SkipPrevious:
	  AudioTrack previousTrack = GetPreviousTrack();
	  if (previousTrack != null)
	  {
	    player.Track = previousTrack;
	  }
	break;
  }
  NotifyComplete();
}

Ti consigliamo anche