Bem pessoal, continuando a série de artigos, hoje vamos falar sobre execução de áudio no background. Um assunto importante para os desenvolvedores que trabalham com o Windows Phone, pois, apesar de já ser possível hoje integrarmos aplicações de terceiros com o hub Music + Videos e fazer uso de algumas ferramentas interessantes, não é possível rodar áudio no background, ou seja, se sua aplicação utiliza áudio internamente, não através do hub de música, assim que o usuário deixa a aplicação, o áudio não está mais disponível.

Para o Mango update, temos alguns novos templates, que você conheceu na parte 1. Um deles é o Windows Phone Audio Playback Agent, que irá nos possibilitar executar músicas que estão no Isolated Storage ou remotas, e que iremos conhecer hoje.

Mãos a obra!

O TEMPLATE

Como comentado no artigo anterior, o template Windows Phone Audio Playback Agent é um dos quatro novos templates disponíveis no Update Mango. Eles se juntam aos templates antigos para oferecer novas possibilidades ao desenvolvedor. O template que trabalharemos é responsável por todo o trabalho pesado de execução do áudio no background, usando o novo conceito de “agentes” (Background Agents). Desse template iremos gerar uma dll , que será referenciada e consumida em um projeto de aplicação Windows phone 7.

CRIANDO O PROJETO

Para começar, crie um novo projeto do tipo Windows Phone Audio Playback Agent no seu Visual Studio 2010.

image

 

 

 

O projeto, ao ser criado, já conta com uma classe AudioPlayer, que faz parte do novo namespace Microsoft.Phone.BackgroundAudio e herda da classe AudioPlayerAgent (que por sua vez herda de BackgroundAgent, mas está fora do nosso escopo), e essa é a classe que fará o trabalho sujo. Alguns eventos já estarão prontos e faremos um player muito simples, que apenas tocará a música, ou seja, Play e Stop. A idéia do artigo é apenas didática, mas um exemplo com mudança de faixas não adiciona complexidade nenhuma, pois envolve apenas algumas regras básicas de contadores e um pouco mais de código. Outro ponto importante é que não estamos utilizando uma classe “music” ou algo do gênero, com melhores práticas, mas que ocuparia muito espaço por aqui. Quem desejar saber mais ou ter um exemplo mais completo, entrem em contato ou acessem meu blog pessoal, pois escrevi esse exemplo em alguns webcasts e posso repassar a vocês O vídeo ou mesmo outros exemplos.

Primeiro passo, vamos escrever um método que tocará nossa música.

  1:         private void PlayMusic(BackgroundAudioPlayer player)
  2:         {
  3:             player.Track = new AudioTrack(new Uri("Stellar.wma",UriKind.Relative)
  4: , "Stellar", "Debutantes99", "Tempestade", null);
  5: 
  6:             player.Play();
  7:         }
  8: 

No exemplo, estamos usandoa instância de player que iremos receber por parâmetro e a propriedade Track (do tipo AudioTrack e que contém as informações da música executada) está sendo populada. Instanciamos uma nova AudioTrack, na ordem dos parâmetros, com a localização, nome, artista, álbum e imagem de capa.

Para que possamos saber como e qual música tocar quando o usuário desejar, e como fazer o Play/Stop, precisamos de código no evento “OnUserAction“, que já estará no arquivo AudioPlayer.cs. O bacana é que você verá inclusive um comentário sobre a necessidade de adicionar código para o handle da ação do usuário. É aqui que iremos chamar no método PlayMusic criado no código anterior. Faça o override, adicionado:

  1: switch (action)
  2: {
  3: case UserAction.Play:
  4: PlayMusic(player);
  5: break;
  6: case UserAction.Stop:
  7: player.Stop();
  8: break;
  9: }

Pontos importantes: a ação Play irá nos levar ao nosso método, já com o Stop estamos utilizando o evento padrão. O caminho é o seguinte: Usuário clica em Play na tela, a classe Audio Player será executada, o evento acima chamado e, por último, nosso PlayMusic é executado.

Pronto. Para uma aplicação simples com Play e Stop é tudo que criaremos nesse projeto. Agora precisamos o referenciar e escrever nosso código na tela.

ADICIONANDO O PROJETO WINDOWS PHONE APPLICATION

Crie um novo projeto Windows Phone Application. Tela mais simples possível, apenas para verificar o processo de execução de áudio.

Adicione a referência ao projeto. Botão direito, add reference, projects e selecione nosso projeto de background criado anteriormente.

image

 

 

Seu arquivo de música deve ser adicionado ao projeto. Após adicionar um arquivo existente de música, botão direito, properties, mude o build action para “content”, conforme figura abaixo.

image

 

 

Não esqueça que, caso esteja usando Isolated Storage, o arquivo precisa ser adicionado, caso contrário, o processo não funciona. O passo não está mostrado aqui, mas adicione a música como sendo um arquivo qualquer de Isolated Storage. Mais um ponto importante, estamos utilizando apenas uma página, sem o conceito de MVVM aplicado. É importante que estude o pattern e possa aplicar em soluções reais.

Após isso, precisamos apenas criar os botões na tela e chamar nosso projeto de áudio. No MainPage.xaml adicione dois botões dentro do grid Content Panel. Também adicione um TextBlock, que irá mostrar ao usuário qual é a música sendo executada. O seu código ficará assim:

  1: <!--ContentPanel - place additional content here-->
  2: <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  3:   <StackPanel>
  4:     <TextBlock x:Name="currentMusic" Foreground="{StaticResource PhoneAccentBrush}" Height="50" FontStyle="Italic"></TextBlock>
  5:     <Button Content="TOCAR" x:Name="btnPlay" Click="btnPlay_Click"></Button>
  6:     <Button Content="STOPAR" x:Name="btnStop" Click="btnStop_Click"></Button>
  7:   </StackPanel>
  8: </Grid>
  9: 

 

Duplo clique nos botões e você irá gerar o evento de ambos. A listagem abaixo mostra o código do arquivo MainPage.xaml.cs:

  1: public partial class MainPage : PhoneApplicationPage
  2:     {
  3:         // Constructor
  4:         public MainPage()
  5:         {
  6:             InitializeComponent();
  7: 
  8:             BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);
  9:         }
 10: 
 11:         protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
 12:         {
 13:             if (BackgroundAudioPlayer.Instance.PlayerState == PlayState.Playing)
 14:             {
 15:                 this.currentMusic.Text = BackgroundAudioPlayer.Instance.Track.Artist + " - " + BackgroundAudioPlayer.Instance.Track.Title + " from album " + BackgroundAudioPlayer.Instance.Track.Album;
 16:             }
 17: 
 18:         }
 19: 
 20:         void Instance_PlayStateChanged(object sender, EventArgs e)
 21:         {
 22:             AudioTrack track = BackgroundAudioPlayer.Instance.Track;
 23:             
 24:             if (track != null)
 25:             {
 26:                 this.currentMusic.Text = track.Artist + " - " + track.Title + " from album " + track.Album;
 27:             }
 28:         }
 29: 
 30:         private void btnPlay_Click(object sender, RoutedEventArgs e)
 31:         {
 32:             BackgroundAudioPlayer.Instance.Play();
 33:         }
 34: 
 35:         private void btnStop_Click(object sender, RoutedEventArgs e)
 36:         {
 37:             BackgroundAudioPlayer.Instance.Stop();
 38:         }
 39:     }

Pontos importantes a destacar:

- O event handler no construtor, para que possamos obter a faixa quando o usuário a executar e enviar a mesma ao tetblock.

-O override do OnNavigatedTo. Esse evento é executado quando a navegação vem para a página atual, ou seja, sabemos que o evento rodará quando nosso MainPage for acionado. Dessa forma, vamos tentar obter a música tocando, se o player estiver sendo executado, iremos adicionar os dados ao TextBlock. Isso é importante, pois como nosso áudio funcionará no Background e aplicação pode não estar mais sendo executada (mas o áudio sim), ao voltarmos a ela quero que o texto mostre qual a música atual.

-Os eventos de play e stop nada mais são do que chamadas ao BackgroundAudioPlayer. Mas e quanto aos nossos métodos e eventos criados no projeto anterior? Lembre-se que o que fizemos foi um override no evento que define mudanças de ação do usuário, ou seja, na hora que tivermos um Play por parte do usuário, o OnUserAction será disparado, iremos ver que é um Play e nosso método PlayMusic será executado, fechando o ciclo.

Ao executar a aplicação, temos o resultado:

image

 

CONCLUSÃO

Nesse artigo podemos ver como é fácil na versão Mango rodar um áudio no background, utilizando o poder do framework e do novo template. Temos disponível, assim como o Play e Stop mostrado, o método de Pause, Skip, etc, sendo extremamente fácil adicionar essas funções. Sigam o que viram aqui, criem suas classes para conter uma lista de músicas que desejam executar, utilizem o padrão MVVM para ter um modelO e também código separado da interface, e criem os players dentro da aplicação de forma fácil. Em caso de dúvida, entrem em contato!

LINKS ÚTEIS

MSDN Library
http://msdn.microsoft.com/en-us/library/ff402529(v=VS.92).aspx

 
Podcast Windows Phone
http://www.conexaowindows.com

Blog pessoal
http://www.rodolphomarques.com