バックグラウンドで音楽を再生する(後編)

2011年9月5日(月)
PROJECT KySS

前編では、「Windows Phone オーディオ再生エージェント」の追加と、そのロジックコードをメインに解説しました。今回は、分離ストレージまたはリモートURI からBackgroundAudioPlayerを再生する処理を追加して、プログラムを完成させます。

またExpression Blend 4(日本語版)を使ってButtonのUIを変更する処理も解説いたします。一度、前編を再読してから、後編を読むことをお勧めします。

サンプルは以下よりダウンロードできます(前編と同じ)。
→ 「バックグラウンドで音楽を再生する」のサンプルファイル(117.8MB)
※サンプル実行でエラーが発生した場合は、「ソリューションのビルド」を実行後、再度、デバッグ開始を行ってください
※ファイルサイズが大きいため、ダウンロードの際はご注意ください

まず、ソリューションエクスプローラーからApp.xamlを展開し表示されるApp.xaml.vb内に、リスト1のコードを記述します。

BackgroundAudioPlayerは分離ストレージまたはリモートURIからのみ再生できます。ファイルの配列に、プロジェクトに追加したオーディオの実際の名前を格納します。

ロジックコードを記述する

リスト1 (App.xaml.vb)

Option Strict On

仮想ファイルシステムを作成および使用するための型が含まれている、System.IO.IsolatedStorage 名前空間をインポートします。
Imports System.IO.IsolatedStorage

アプリケーションでのリソースの使用をサポートするクラスを提供する、System.Windows.Resources名前空間をインポートします。
Imports System.Windows.Resources

Partial Public Class App
  Inherits Application
  Public Property RootFrame As PhoneApplicationFrame

初期化

曲目ファイルを分離ストレージから読み取るCopyWavToIsolatedStorageプロシージャを実行します。
  Public Sub New()
    CopyWavToIsolatedStorage()
    ~コード略~
  End Sub

~コード略~

曲目を分離ストレージから読み取り分離ストレージ内のファイルに書き出す処理

BackgroundAudioPlayer は、ファイルを分離ストレージ、またはリモート URI からのみ再生できますので、wavファイル情報を分離ストレージから取得し分離ストレージ内のファイルに書き出します。
 変数storageを、ファイルとディレクトリを格納している分離ストレージ領域を表すIsolateStorageFileクラスとして宣言し、呼び出し元のコードのアプリケーションIDに対応する、ユーザースコープの分離ストレージを取得します。
参照型変数filesに初期値として各wavファイルを格納します。
参照型変数filesコレクション内を、変数_fileNameで反復処理しながら以下の処理を行います。
 _fileNameに該当するファイルが存在しなかった場合は、wavファイルを格納しているWAVフォルダと_fileNameを連結した_filePath変数を宣言します。
 StreamResourceクラスの型のresource変数を宣言します。StreamResourceクラスは、GetResourceStreamメソッドを使って取得したリソースのストリーム情報を提供するクラスです。ここでは、WAVフォルダ内のwavファイルのストリーム情報を取得しています。WAVフォルダ内に追加したwavファイルは、ビルドアクションプロパティが「コンテンツ」になっていますので、GetResourceStreamメソッドでファイル名を指定してリソースを取得できます。
 IsolatedStorageFileStreamクラス型のオブジェクト変数fileを宣言します。IsolatedStorageFileStreamクラスは、分離ストレージ内のファイルを公開するクラスです。IsolatedStorageFileクラスのCreateFileメソッドで、変数_fileNameに格納されているファイルを、分離ストレージ内に作成します。Integer型変数bufferSizeに4096を格納し、bufferSizeで初期化された新しいByte型配列変数bufferを生成します。バッファサイズを4096確保します。
 StreamResourceInfoクラスのStream.Readメソッドで、リソースに格納されているストリームを読み取りIsolatedStorageFileStreamにWriteメソッドで書き込みます。InlineAssignHelperヘルパー関数(後述)を使っています。
IsolatedStorageFileStream.Write メソッドの書式は下記の通りです。
IsolatedStorageFileStream.Write(書き込むバッファ,開始位置を示すバッファ内のオフセット,書き込むバッファの最大バイト数)
  Private Sub CopyWavToIsolatedStorage ()
    Using storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
      Dim files As String() = New String() {"AGAIN_Trial.wav", "DontCryMama_Trial.wav", "SambaDeOpacidade_Trial.wav", "TheGreenBells_Trial.wav"}
      For Each _fileName In files
        If storage.FileExists(_fileName) = False Then
          Dim _filePath As String = "WAV/" & _fileName
          Dim resource As StreamResourceInfo = Application.GetResourceStream(New Uri(_filePath, UriKind.Relative))
  
          Using file As IsolatedStorageFileStream = storage.CreateFile(_fileName)
            Dim bufferSize As Integer = 4096
            Dim buffer As Byte() = New Byte(bufferSize) {}
            Dim bufferCount As Integer
            While (InlineAssignHelper(bufferCount, resource.Stream.Read(buffer, 0, bufferSize))) > 0
              file.Write(buffer, 0, bufferCount)
            End While
          End Using
        End If
      Next
    End Using
  End Sub

MSDNのドキュメントで下記のように定義されているInlineAssignHelperヘルパー関数

  Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
    target = value
    Return value
  End Function
End Class

次に[WebBrowser]ボタンをクリックして遷移するページを作成します。

Windows Phone 縦向きのページ(WebBrowser.xaml)の追加

VS2010メニューの「プロジェクト(P)/新しい項目の追加(W)」と選択して、「Windows Phone 縦向きのページ」を選択し、「名前(N)」に「WebBrowser.xaml」と指定します。[追加(A)]ボタンをクリックします(図1)。

図1:Windows Phone 縦向きのページを追加する(クリックで拡大)

WebBrowser.xamlの編集とコントロールの追加

x:NameがApplicationTitleとPageTitleというTextBlockを削除します。x:NameがTitlePanelというStackPanel内にツールボックスから、TextBoxとButtonコントロールを1個ずつ配置します。横に配置するため、StackPanelのOrientationプロパティにHorizontalと指定します。デフォルトはVerticalです。TextBoxのTextプロパティには「http://jp.msn.com/」と記述しMSNのサイトを指定しておきます。

次に、TextBoxとButtonコントロールの下にツールボックスからWebBrowserコントロールを1個配置します。WebBrowserコントロールのプロパティウィンドウ内の[共通]パネルにある、IsScriptEnabledにチェックを付けておきます。チェックを付けないでおくと、JavaScriptが無効になり、正常に表示されないページが出てきます。書き出されるXAMLコードはリスト2のようになります。

リスト2 書き出されたXAMLコード(WebBrowser.xaml)

(1)TitlePanelというx:Nameの<StackPanel>要素のOrientationプロパティにHorizontalを指定し、中に<TextBox>と<Button> 要素を1個ずつ配置します。<TextBox> のTextプロパティには「http://jp.msn.com/」と指定しておきます。<Button> 要素のContentプロパティには「実行」と指定します。
(2)<phone:WebBrowser>要素のIsScriptEnabledにはTrueと指定されています。
<phone:PhoneApplicationPage 
  x:Class="WP71_BackgroundAudioPlayer.WebBrowser"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  FontFamily="{StaticResource PhoneFontFamilyNormal}"
  FontSize="{StaticResource PhoneFontSizeNormal}"
  Foreground="{StaticResource PhoneForegroundBrush}"
  SupportedOrientations="Portrait" Orientation="Portrait"
  mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
  shell:SystemTray.IsVisible="True" Langugae=”ja-JP”>

  <!--LayoutRoot is the root grid where all page content is placed-->
  <Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"/>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
 
    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28" Orientation="Horizontal"> ■(1)
      <TextBox x:Name="uritextBox" Text="http://jp.msn.com/" Height="77" Width="377" />
      <Button x:Name="uriGoButton" Content="実行"/>
    </StackPanel>
 
    <!--ContentPanel - place additional content here-->
    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <phone:WebBrowser Height="634" HorizontalAlignment="Left" Margin="6,6,0,0" Name="WebBrowser1" VerticalAlignment="Top" Width="444" IsScriptEnabled="True" /> ■(2)
    </Grid>
  </Grid>
  ~コード略~
</phone:PhoneApplicationPage>

全て配置すると図2のようになります。

図2:TextBox、Button、WebBrowserコントロールを配置した(クリックで拡大)

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています