複数画面でのバックグラウンド音楽再生

 以前、バックグラウンドで音楽再生をする方法について紹介しました。
 バックグラウンドでの音楽再生 - rebuild

 この方法でバックグラウンド再生はできるのですが、画面が複数ある場合は問題があります。

 前回作成したアプリにサブ画面を追加して、ナビゲートできるようにしてみるとわかるのですが、MediaElement を定義した画面から別の画面に移動すると音楽再生が止まってしまいます。
 Page の NavigationCacheMode を Required にして MediaElement を定義した画面がキャッシュされるようにしても状況は変りません。

 MediaElement を定義した画面がアクティブになっていないと再生が止まってしまうようですので、常にアクティブになる方法を考えます。
 テンプレートで生成された App.xaml.cs を見ると、最初に Frame のインスタンスを生成し、その Frame のメソッドを使って Page のナビゲートを行っています。
 この事から最初に生成した Frame は常に存在している物と推測されますので、ここに MediaElement を定義します。
 具体的には App.xaml で MediaElement を含んだ Frame のスタイルを定義し、App.xaml.cs でインスタンスを生成した時に定義したスタイルを適用します。

<Style x:Key="CustomFrameStyle" TargetType="Frame">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Frame">
                <Grid>
                    <MediaElement x:Name="bkMediaElem" AudioCategory="BackgroundCapableMedia" AutoPlay="True" />
                    <ContentPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
rootFrame = new Frame();
rootFrame.Style = Resources["CustomFrameStyle"] as Style;

 これで、常に MediaElement がアクティブになるようになりました。
 MediaElement を操作する場合は、MainPage.xaml.cs で画面レイアウトが終了した後(Loadedイベント発生後)に、VisualTreeHelper を使って取得します。

DependencyObject rootGrid = VisualTreeHelper.GetChild(Window.Current.Content, 0);
MediaElement mediaElem = (MediaElement)VisualTreeHelper.GetChild(rootGrid, 0);

 MediaElement が取得できてしまえば、後は画面が一つしかない場合と同じように操作するだけです。
 これで、画面が複数あっても途切れずに再生ができるようになります。もちろんどの画面でバックグラウンドにまわっても再生は継続されます。