概要: バックグラウンド オーディオ (Windows Phone ストア アプリ) (HTML)

[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]

バックグラウンドでオーディオを再生する Windows Phone 8.1 用のアプリを作ることができます。つまり、ユーザーがデバイスの [戻る] ボタンまたは [スタート] ボタンを押してアプリから離れても、アプリでオーディオを再生し続けることができます。この記事では、バックグラウンド オーディオ アプリの構成要素と、それらの連携のしくみについて説明します。

バックグラウンド オーディオ再生のシナリオには次のものがあります。

  • 長時間にわたって実行される再生リスト: ユーザーは、フォアグラウンド アプリを簡単に起動し、再生リストを選んで再生を開始します。その後、再生リストはバックグラウンドで再生を続行できます。
  • タスク スイッチャーの使用 ユーザーは、オーディオの再生を開始するためにフォアグラウンド アプリを一時的に表示した後、タスク スイッチを使って別の開いているアプリに切り替えます。ユーザーは、バックグラウンドでオーディオの再生が継続することを期待します。

ヒント  この概要で説明するコードを実装する、Windows Phone 8.1 サンプルのバックグラウンド オーディオに関するページでコードをダウンロードできます。

 

バックグラウンド オーディオのアーキテクチャ

バックグラウンド オーディオ アプリでは、バックグラウンド エージェントを使います。ただし、Windows Phone 8.1 におけるバックグラウンドでのオーディオ再生は、Windows 8 におけるバックグラウンド オーディオの再生方法とは異なります。このモデルは、Windows Phone の以前のバージョンで使われたバックグラウンド オーディオ エージェントとも異なります。

重要  

JavaScript を使って、バックグラウンド オーディオ アプリを作成できます。ただし、Windows Phone 8.1 では、JavaScript をバックグラウンド プロセスで実行することはできません。これは、フォアグラウンド アプリと UI は JavaScript で記述できるが、バックグラウンド タスクは C# または C++ で記述する必要があることを意味します。Windows Phone 8.1 用バックグラウンド オーディオのサンプルに関するページには、C# バックグラウンド エージェントを使ってバックグラウンド オーディオをサポートする JavaScript アプリの例が用意されています。

 

Windows.Media.Playback 名前空間では汎用オーディオ API を導入し、フォアグラウンドでの音楽再生にも使うことができますが、主な目的はバックグラウンドでオーディオを再生することです。この API を使う場合、すべての再生がグローバルな単一の MediaPlayer によって行われます。バックグラウンド オーディオ アプリは、このメディア プレーヤーに対して、現在のトラックの設定、再生の開始、一時停止、早送り、巻き戻しなどのコマンドを送ります。そのためには、MediaPlayer クラスのメソッドを呼び出します。次に、BackgroundMediaPlayer.Current プロパティを使ってアクセスすることができるメディア プレーヤーのインスタンス オブジェクトが、グローバル メディア プレーヤーとやり取りすることでオーディオの再生を操作します。

MediaPlayer の新しいインスタンスを作ることはできません。

SystemMediaTransportControls クラスを使って、Universal Volume Control (UVC) によって使用されるイベントを発生させます。UVC は、アプリ ユーザーがデバイスのボリューム コントロールを押すと表示される UI です。SystemMediaTransportControls を使って、メディア プレーヤーを操作します。アプリからのオーディオの再生開始に加えて、オーディオの再生を制御できます。たとえば、アプリの IBackgroundTask にイベントを送信するために、SystemMediaTransportControls を使います。また、再生リストのロジックを実装できます。IBackgroundTask については、このトピックで後ほど詳しく説明します。

次の図は、システムの設計のしくみを非常に簡単に示しています。バックグラウンド再生を実行するアプリは、2 つのプロセスで構成されています。最初のプロセスはメイン アプリです。UI を含み、フォアグラウンドで実行されます。2 番目のプロセスはバックグラウンド再生タスクです。オーディオ再生機構を含みますが、アプリのロジックを含むこともあります。フォアグラウンド プロセスは、リソースのニーズに基づいてオペレーティング システムによって中断または終了されます。バックグラウンド プロセスは、実行を続けます。

オーディオ再生をバックグラウンド プロセスで実行している間は、フォアグラウンド プロセスでプロキシ オブジェクトを介してすべての情報にアクセスできます。フォアグラウンド プロセスでは、バックグラウンド プロセスにおける MediaPlayer インスタンスのプロパティを管理できます。フォアグラウンド アプリは、MediaOpenedMediaEndedMediaFailed などのメディア固有のイベントの通知を受け取ることができます。フォアグラウンド プロセスが終了するか、アプリが中断された場合、メディアは再生を続けます。

バックグラウンド オーディオのアーキテクチャ

システム メディア トランスポート コントロール

SystemMediaTransportControls は、Windows 8.1 で新しく導入された API セットです。また Windows Phone 8.1 でもこのクラスを実装していますが、Windows Phone では 1 つのグローバル ボリューム コントロールを持つために、1 つのプロセスのみが同時に操作できます。MediaPlayer API のコンテキストでは、バックグラウンド プロセスでインスタンスとすべてのハンドラーを定義することが非常に重要です。これにより、フォアグラウンド アプリが終了した場合に、接続が正しいプロセスに確実にバインドされるようになります。

タスク間のメッセージ送信

バックグラウンド オーディオ アプリの 2 つのプロセス間で通信することが必要になる場合があります。たとえば、新しいトラックの再生が始まるときにバックグラウンド タスクからフォアグラウンド タスクに通知し、新しい曲のタイトルをフォアグラウンド タスクに送って画面に表示させることがあります。単純な通信メカニズムにより、フォアグラウンド プロセスとバックグラウンド プロセスの両方でイベントを発生させることができます。SendMessageToForeground メソッドと SendMessageToBackground メソッドは、それぞれ対応するタスクでイベントを呼び出します。データは、引数として受信側タスクのイベント ハンドラーに渡すことができます。ValueSet という新しいクラスを使ってデータを渡します。このクラスは、文字列をキーとして格納し、その他の値の型を値として格納するディクショナリです。intstringbool など、単純な値の型を渡すことができます。

バックグラウンド タスクの有効期間

バックグラウンド タスクの有効期間は、音楽を再生するアプリの機能に密接に関係します。たとえば、ユーザーがオーディオ再生を一時停止すると、システムは状況に応じてアプリを終了させたり、取り消したりします。

バックグラウンド タスクが開始されるのは、初めてアプリが BackgroundMediaPlayer.Current フォアグラウンド アプリ コードにアクセスしたときと、MessageReceivedFromBackground イベントのハンドラーを登録するときのうち、早い方です。IBackgroundTask.Run メソッドが呼び出されたときに通信チャネルが必ず確立されているようにするために、BackgroundMediaPlayer.Current プロパティに初めてアクセスする前に MessageReceivedFromBackground イベントを登録する必要があります。 アプリでは、オーディオ再生の開始を試みる前に、バックグラウンド タスクの実行を待つ必要があります。こうして、メディア イベントの受信登録を行うことができるようになります。

バックグラウンド タスクを有効な状態に維持するために、アプリでは Run メソッドの BackgroundTaskDeferral を取得し、タスク インスタンスが Canceled イベントまたは Completed イベントを受け取るときに、BackgroundTaskDeferral.Complete を呼び出すことが必要になります。Run メソッドでは待機しないようにしてください。リソースが使われてしまい、アプリのバックグラウンド タスクの終了を引き起こす可能性があるためです。

Run メソッドが完了し、遅延が要求されない場合、バックグラウンド タスクは Completed イベントを取得します。場合によっては、アプリで Canceled イベントを取得したときに、その後に Completed イベントが続くことがあります。

バックグラウンド タスクは、次のような状況の場合に取り消されることがあります。

  • オーディオ再生機能を備えた新しいアプリが起動した場合。
  • バックグラウンド タスクが起動したが、音楽はまだ再生されず、フォアグラウンド アプリが中断された場合。
  • バックグラウンド タスクが起動してからしばらくして、再生が一時停止され、フォアグラウンド アプリが中断された場合。ユーザーまたは他のメディアの割り込み (着信呼び出しや VoIP 通話など) によって再生が一時停止されることがあります。電話や VoIP 通話が 5 分以内に終われば、アプリは Run 通知を受け取り、SystemMediaTransportControlsButton.Play ボタンが SystemMediaTransportControlsButtonPressedEventArgs に示されます。5 分以内に終わらない場合、ユーザーは SMTC を使って明示的に再生を開始することが必要になります。UVC は、状態を喪失しません。 ただし、ユーザーが [再生] ボタンを押すと、バックグラウンド タスクが再起動されます。次に、Run メソッド呼び出しと SystemMediaTransportControlsButton.Play 通知を取得します。

バックグラウンド タスクは、次のような状況の場合に警告なしに終了されることがあります。

  • VoIP 通話の着信があるが、メモリが十分にない場合。
  • リソース ポリシーに違反した場合。
  • タスクの取り消しまたは完了が適切に終わらない場合。

バックグラウンド オーディオのベスト プラクティス

メディア パイプラインは本質的に非同期です。つまり、発生したイベントはそのイベントの発生を保証するだけで、イベントの順序を保証するわけではありません。たとえば、アプリでリモート ソースからオーディオ ファイルをフェッチする場合、アプリは、StartingPausedClosed などのさまざまな状態変更のイベントを取得します。これらのハンドラーは、毎回必ず同じ順序で呼び出されるわけではありません。CurrentStateChanged ハンドラーの CurrentState の値に大きく依存しないようにしてください。

MediaOpened は非常に重要なイベントで、複数の役割を果たします。AutoPlayfalse に設定した場合に MediaPlayer のソースを設定すると、引き続き MediaOpened が表示されます。これは、メディア パイプラインが開始され、メディアを再生する準備が整ったことを示しています。ソースを設定すると、メディアの再生が自動的に始まります。ソースの設定後に Play を呼び出す必要はありません。もう 1 つの非常に便利な技法は、メディアの用意ができたら明示的に再生することです。これは、AutoPlayfalse に設定し、MediaOpened ハンドラーの Play を特別に呼び出すことで実行できます。

SetUriSourceSetFileSourceSetMediaSource、または SetStreamSource を呼び出すと、メディア ソースをいくつかの異なる種類のコンテンツに設定できます。MediaPlayer にも、保護されたコンテンツを再生する機能があります。URI ソースの設定を除き、システムは、アプリのオブジェクト、またはメモリで実行されているアプリ コードに依存します。また、バックグラウンド プロセスでは、フォアグラウンド タスクのプロセス メモリが認識されません。したがって、ソースがバックグラウンド プロセスだけで設定されるよう、すべてのオブジェクトを定義してください。アプリがフォアグラウンド プロセスで URI 以外のソースを設定しようとすると、システムは InvalidCastException をスローします。

BackgroundMediaPlayer.Shutdown は、メディア パイプラインを閉じ、メモリから MediaPlayer オブジェクトを解放します。Shutdown の呼び出し後、BackgroundMediaPlayer.Current への参照にもう一度アクセスしようとすると、エラーになります。Shutdown は、タスクが取り消される場合にアプリでメディア パイプラインをクリーンアップするためのものです。

アプリが中断した場合、MediaPlayer イベントからの受信登録を忘れずに解除します。これを怠った場合、フォアグラウンド プロセスの終了に至る可能性がある望ましくないアクティビティが発生することがあります。ただし、フォアグラウンド プロセスがタスク スイッチャーから離れることはなく、ユーザーは引き続きアプリに戻ることができます。アプリの再開時に、中断された MediaPlayer への参照を引き続き保持している場合、バックグラウンド オーディオ タスクが取り消されてメディア パイプラインがシャットダウンされると、エラーがスローされます。

関連トピック

Windows Phone 8.1 サンプルのバックグラウンド オーディオ

バックグラウンド タスクをデバッグする方法