Riproduzione di elementi multimediali in background legacy

Questo articolo descrive il modello legacy a due processi per l'aggiunta del supporto audio in background all'app UWP. A partire da Windows 10 versione 1607, un modello a processo singolo per l'audio in background molto più semplice da implementare. Per altre informazioni sulle raccomandazioni correnti per l'audio in background, vedere Riprodurre elementi multimediali in background. Questo articolo è destinato a fornire supporto per le app già sviluppate usando il modello legacy a due processi.

Nota

A partire da Windows, versione 1703, BackgroundMediaPlayer è deprecato e potrebbe non essere disponibile nelle versioni future di Windows.

Architettura audio in background

Un'app che esegue la riproduzione in background è costituita da due processi. Il primo processo è l'app principale, che contiene l'interfaccia utente dell'app e la logica client, in esecuzione in primo piano. Il secondo processo è l'attività di riproduzione in background, che implementa IBackgroundTask come tutte le attività in background dell'app UWP. L'attività in background contiene la logica di riproduzione audio e i servizi in background. L'attività in background comunica con il sistema tramite i controlli di trasporto multimediale di sistema.

Il diagramma seguente è una panoramica del modo in cui viene progettato il sistema.

Architettura audio in background di Windows 10

Media Player

Lo spazio dei nomi Windows.Media.Playback contiene le API usate per riprodurre l'audio in background. Esiste una singola istanza di MediaPlayer per app tramite cui viene eseguita la riproduzione. L'app audio in background chiama metodi e imposta le proprietà nella classe MediaPlayer per impostare la traccia corrente, avviare la riproduzione, sospendere, inoltrare rapidamente, riavvolgere e così via. L'istanza dell'oggetto lettore multimediale è sempre accessibile tramite la proprietà BackgroundMediaPlayer.Current.

Proxy e Stub di MediaPlayer

Quando si accede a BackgroundMediaPlayer.Current dal processo in background dell'app, l'istanza di MediaPlayer viene attivata nell'host attività in background e può essere modificata direttamente.

Quando si accede a BackgroundMediaPlayer.Current dall'applicazione in primo piano, l'istanza di MediaPlayer restituita è effettivamente un proxy che comunica con uno stub nel processo in background. Questo stub comunica con l'istanza effettiva di MediaPlayer, ospitata anche nel processo in background.

Sia il processo in primo piano che quello in background possono accedere alla maggior parte delle proprietà dell'istanza di MediaPlayer, ad eccezione di MediaPlayer.Source e MediaPlayer.SystemMediaTransportControls a cui è possibile accedere solo dal processo in background. L'app in primo piano e il processo in background possono ricevere notifiche di eventi specifici dei supporti, ad esempio MediaOpened, MediaEnded e MediaFailed.

Elenchi di riproduzione

Uno scenario comune per le applicazioni audio in background consiste nel riprodurre più elementi in una riga. Questa operazione viene eseguita più facilmente nel processo in background usando un oggetto MediaPlaybackList, che può essere impostato come origine in MediaPlayer assegnandolo alla proprietà MediaPlayer.Source.

Non è possibile accedere a MediaPlaybackList dal processo in primo piano impostato nel processo in background.

Controlli di sistema per il trasporto multimediale

Un utente può controllare la riproduzione audio senza usare direttamente l'interfaccia utente dell'app tramite dispositivi Bluetooth, SmartGlass e i controlli di trasporto multimediale di sistema. L'attività in background usa la classe SystemMediaTransportControls per sottoscrivere questi eventi di sistema avviati dall'utente.

Per ottenere un'istanza SystemMediaTransportControls dall'interno del processo in background, usare la proprietà MediaPlayer.SystemMediaTransportControls. Le app in primo piano ottengono un'istanza della classe chiamando SystemMediaTransportControls.GetForCurrentView, ma l'istanza restituita è un'istanza di solo primo piano che non è correlata all'attività in background.

Invio di messaggi tra attività

Ci sono momenti in cui si vuole comunicare tra i due processi di un'app audio in background. Ad esempio, è possibile che l'attività in background invii una notifica all'attività in primo piano all'inizio della riproduzione di una nuova traccia e quindi invii il nuovo titolo del brano all'attività in primo piano da visualizzare sullo schermo.

Un semplice meccanismo di comunicazione genera eventi sia in primo piano che in background. I metodi SendMessageToForeground e SendMessageToBackground richiamano ogni evento nel processo corrispondente. I messaggi possono essere ricevuti sottoscrivendo gli eventi MessageReceivedFromBackground e MessageReceivedFromForeground.

I dati possono essere passati come argomento ai metodi di invio del messaggio che vengono quindi passati ai gestori di eventi ricevuti dal messaggio. Passare i dati usando la classe ValueSet. Questa classe è un dizionario che contiene una stringa come chiave e altri tipi di valore come valori. È possibile passare tipi di valore semplici, ad esempio numeri interi, stringhe e booleani.

Ciclo di vita delle attività in background

La durata di un'attività in background è strettamente legata allo stato di riproduzione corrente dell'app. Ad esempio, quando l'utente sospende la riproduzione audio, il sistema può terminare o annullare l'app a seconda delle circostanze. Dopo un periodo di tempo senza riproduzione audio, il sistema può arrestare automaticamente l'attività in background.

Il metodo IBackgroundTask.Run viene chiamato la prima volta che l'app accede a BackgroundMediaPlayer.Current dal codice in esecuzione nell'app in primo piano o quando si registra un gestore per l'evento MessageReceivedFromBackground, quello che si verifica per primo. È consigliabile registrarsi per il gestore dei messaggi ricevuti prima di chiamare BackgroundMediaPlayer.Current per la prima volta in modo che l'app in primo piano non perda alcun messaggio inviato dal processo in background.

Per mantenere attiva l'attività in background, l'app deve richiedere un oggetto BackgroundTaskDeferral dall'interno del metodo Run e chiamare BackgroundTaskDeferral.Complete quando l'istanza dell'attività riceve gli eventi Cancellato o Completato. Non eseguire un ciclo o attendere nel metodo Run perché utilizza le risorse e potrebbe causare la terminazione dell'attività in background dell'app da parte del sistema.

L'attività in background ottiene l'evento Completato quando il metodo Run viene completato e il differimento non viene richiesto. In alcuni casi, quando l'app ottiene l'evento Cancellato , può essere seguita anche dall'evento Completato. L'attività può ricevere un evento Cancellato durante l'esecuzione di Run, quindi assicurarsi di gestire questa potenziale concorrenza.

Le situazioni in cui l'attività in background può essere annullata includono:

  • Una nuova app con funzionalità di riproduzione audio viene avviata nei sistemi che applicano i criteri secondari di esclusività. Vedi la sezione Criteri di sistema per la durata delle attività audio in background di seguito.

  • È stata avviata un'attività in background, ma la musica non è ancora in riproduzione e quindi l'app in primo piano viene sospesa.

  • Altre interruzioni multimediali, ad esempio chiamate telefoniche in ingresso o chiamate VoIP.

Le situazioni in cui l'attività in background può essere terminata senza preavviso includono:

  • Viene visualizzata una chiamata VoIP e non è disponibile memoria sufficiente nel sistema per mantenere attiva l'attività in background.

  • I criteri delle risorse vengono violati.

  • L'annullamento o il completamento dell'attività non termina normalmente.

Criteri di sistema per la durata delle attività audio in background

I criteri seguenti consentono di determinare come il sistema gestisce la durata delle attività audio in background.

Esclusività

Se abilitato, questo criterio secondario limita il numero di attività audio in background al massimo 1 in un determinato momento. È abilitato per dispositivi mobili e altri SKU non desktop.

Timeout inattività

A causa dei vincoli di risorse, il sistema può terminare l'attività in background dopo un periodo di inattività.

Un'attività in background viene considerata "inattiva" se vengono soddisfatte entrambe le condizioni seguenti:

  • L'app in primo piano non è visibile (è sospesa o terminata).

  • Il lettore multimediale in background non è nello stato riproduzione.

Se entrambe queste condizioni sono soddisfatte, il criterio del sistema multimediale in background avvierà un timer. Se nessuna delle due condizioni è cambiata alla scadenza del timer, i criteri del sistema multimediale in background termineranno l'attività in background.

Durata condivisa

Se abilitata, questo criterio secondario forza l'attività in background a dipendere dalla durata dell'attività in primo piano. Se l'attività in primo piano viene arrestata, anche dall'utente o dal sistema, l'attività in background verrà arrestata.

Tuttavia, si noti che questo non significa che il primo piano dipende dallo sfondo. Se l'attività in background viene arrestata, questa operazione non forza l'arresto dell'attività in primo piano.

Nella tabella seguente sono elencati i criteri applicati ai tipi di dispositivo.

Criteri secondari Desktop Dispositivi mobili Altro
Esclusività Disabilitata Attivata Attivata
Timeout inattività Disabilitata Attivata Disabilitata
Durata condivisa Attivata Disabilitata Disabled