Curso Windows Phone – Como desenvolver uma APP para rádio online via Shoutcast

sc-logoOlá pessoal, tudo bom?

Nesse post demonstro como desenvolver uma APP para Windows Phone onde você possa ouvir uma rádio online que esteja hospedada no serviço Shoutcast.

Codeplex

No site do Codeplex há vários projetos OpenSource para acesso ao stream do servidor Shoutcast, sendo que o utilizado para esse exemplo chama-se Shoutcast MediaStreamSource. Faça o download do mesmo para que posteriormente ele seja integrado/referenciado ao seu projeto do Windows Phone.

Será necessário compilar o projeto citado acima para que o mesmo gere a DLL com as classes que iremos precisar.

Sua APP – XAML

No Visual Studio, crie uma APP para Windows Phone e nela faça referência à DLL do Shoutcast. Para esse exemplo, a DLL referenciada foi Silverlight.Media.Phone disponível na estrutura de diretórios ShoutcastMSS_v1_beta2SrcSilverlight.Media.ShoutcastBinDebug do projeto que baixou do Codeplex.

No arquivo MainPage.xaml, fiz uma interface simples apenas para demonstrar o uso da servidor Shoutcast. Veja o trecho de código abaixo:


<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
 <TextBlock Text="BLOG DO EDUARDO H. RIZO" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
 <TextBlock Text="shoutcast..." Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
 <Button Name="btnPlay" Content="Play" Click="btnPlay_Click" Width="150" />
 <Button x:Name="btnPause" Content="Pause" Click="btnPause_Click" Width="150" />
 </StackPanel>
 <ProgressBar Name="pbCarregando" IsIndeterminate="false" />
 <TextBlock Name="txtStatus" Text="" TextWrapping="Wrap" HorizontalAlignment="Center" />
</StackPanel>

No início do mesmo arquivo (MainPage.xaml) foram feitas declarações para controle dos status do MediaPlayer da página. Observe o trecho de código:

...
shell:SystemTray.IsVisible="True" Unloaded="PageUnloaded">
<phone:PhoneApplicationPage.Resources>
 <MediaElement x:Key="mediaPlayer" Volume="1.0" BufferingProgressChanged="MediaElement_BufferingProgressChanged"
 MediaFailed="MediaElement_MediaFailed" CurrentStateChanged="MediaElement_CurrentStateChanged" />
</phone:PhoneApplicationPage.Resources>
...

shoutcast-app-wp

Realizada a codificação da porção XAML, vamos ao C# e a implementação dos métodos necessários…

Sua APP – C#

Tendo realizada a implementação do código em XAML para composição do layout (nesse exemplo de forma muito simples), vejamos a implementação dos métodos para execução das ações desejadas.

Faça o using dos seguintes namespaces:

...
using System.Windows.Media;
using Silverlight.Media;
using System.Globalization;

Restante do código C#…

...
namespace ExemploShoutcast
{
 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Quando sair da página, o ShoutcastMediaStreamSource será retirado (disposed).")]
 public partial class MainPage : PhoneApplicationPage
 {
 /// <summary>
 /// Representa um sream do Shoutcast
 /// </summary>
 private ShoutcastMediaStreamSource source;

 /// <summary>
 /// Interrompe a atualização do status caso algum erro ocorra
 /// </summary>
 private bool errorOccured;

 /// <summary>
 /// Obtem o elemento Media da página
 /// </summary>
 private MediaElement MediaPlayer
 {
 get { return this.Resources["mediaPlayer"] as MediaElement; }
 }

 // Constructor
 public MainPage()
 {
 InitializeComponent();
 }

 private void MediaElement_BufferingProgressChanged(object sender, RoutedEventArgs e)
 {
 UpdateStatus();
 }

 private void MediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
 {
 errorOccured = true;
 txtStatus.Text = string.Format(CultureInfo.InvariantCulture, "Erro: {0}", e.ErrorException.Message);
 }

 private void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
 {
 UpdateStatus();
 }

 private void btnPlay_Click(object sender, RoutedEventArgs e)
 {
 if (MediaPlayer.CurrentState != MediaElementState.Paused)
 {
 ResetMediaPlayer();

 Uri uri = new Uri("http://74.111.222.121:99999"); //Ajuste de acordo com sua necessidade
 source = new ShoutcastMediaStreamSource(uri);
 source.MetadataChanged += source_MetadataChanged;
 MediaPlayer.SetSource(source);
 }
 MediaPlayer.Play();
 pbCarregando.IsIndeterminate = true;
 }

 private void btnPause_Click(object sender, RoutedEventArgs e)
 {
 if (MediaPlayer.CurrentState == MediaElementState.Playing || MediaPlayer.CurrentState == MediaElementState.Opening || MediaPlayer.CurrentState == MediaElementState.Buffering)
 MediaPlayer.Pause();
 }

 void source_MetadataChanged(object sender, RoutedEventArgs e)
 {
 UpdateStatus();
 }

 private void UpdateStatus()
 {
 if (errorOccured)
 return;
 else
 {
 MediaElementState state = MediaPlayer.CurrentState;
 string status = string.Empty;

 switch(state)
 {
 case MediaElementState.Buffering:
 status = string.Format(CultureInfo.InvariantCulture, "Buffering...{0:0%}", this.MediaPlayer.BufferingProgress);
 break;
 case MediaElementState.Playing:
 status = string.Format(CultureInfo.InvariantCulture, "Title: {0}", this.source.CurrentMetadata.Title);
 if (status.Trim() != "Titulo:")
 pbCarregando.IsIndeterminate = false;
 break;
 default:
 status = state.ToString();
 break;
 }

 txtStatus.Text = status;
 }
 }

 private void ResetMediaPlayer()
 {
 if ((this.MediaPlayer.CurrentState != MediaElementState.Stopped) &amp;&amp; (this.MediaPlayer.CurrentState != MediaElementState.Closed))
 {
 this.MediaPlayer.Stop();
 this.MediaPlayer.Source = null;
 this.source.Dispose();
 this.source = null;
 }

 this.errorOccured = false;
 }

 private void PageUnloaded(object sender, EventArgs e)
 {
 ResetMediaPlayer();
 }

Não é tão difícil, certo? Se tudo tiver ocorrido como esperado, ao clicar sobre o botão Play, você poderá ouvir as músicas da sua rádio online do Shoutcast.

shoutcast-app-wp-playing

Daqui para frente é só melhorar a interface e explorar outros projetos OpenSource para o Shoutcast que estão disponíveis no Codeplex.

diskette Download do Exemplo

 

Post Relacionado: 

Grande abraço,
Eduardo Henrique Rizo

[twitter-follow screen_name=’eduardorizo’ show_count=’yes’]

35 comentários em “Curso Windows Phone – Como desenvolver uma APP para rádio online via Shoutcast”

  1. Pingback: Free: Curso Windows Phone – Vários tópicos | Blog do Eduardo H. Rizo

  2. Pingback: [Desenvolvimento] Como desenvolver uma APP Windows Phone para rádio online via Shoutcast - Windows Phone Brasil

  3. Boa tarde Eduardo,
    estou com problemas para ouvir radios pelo Shoutcast:
    Há pouco tempo, bastava clicar em alguma estação que ela era reproduzida automaticamente. Atualmente, é baixado um arquivo (tunein-sation.pls) que não é reconhecido pelo player (WMP).
    Vc sabe o que mudou?
    Obrigado

      1. Ah sim, queria saber também, se existe algum método de eu mudar a URI da rádio. Por exemplo pra q eu possa adicionar varias opções de rádios para o usuário escolher, e a troca entre elas fosse dinâmica.

      2. Bom, nesse caso penso que a URI poderia ser um parâmetro (string) a ser informado a um determinado método de acordo com a seleção que a pessoa fizer.

        []s
        Eduardo

      3. Bem, se você observar o meu código verá que a chamada à URL ocorre dentro do click do botão btnPlay. No caso que te falei você poderia ter um método a ser chamado pela mesma ação do botão, mas nesse caso você iria selecionar a URL de acordo com ListBox, por exemplo, que iria apresentar as opções para o usuário da APP. Entendeu?

  4. Olá Eduardo, tudo bem?

    Estou com uma dificuldade. Você mostrou que precisa importar o Silverlight.Media, porém quando tento importar, ocorre um erro. Há algum lugar para que eu possa estar baixando o .dll?

    Obrigado pela ajuda!
    😀

      1. Na verdade são 2 erros, dizem que os namespaces de Silverlight e ShoutcastMediaStreamSource não estão sendo encontrados.

        Você utilizou quais referencias no projeto?

        Obrigado pela ajuda!

      2. Então, você tem que fazer o download do projeto Shoutcast que está no codeplex e compilá-lo. Depois disso, faça a referência da DLL resultante no seu projeto.

        Abraços,
        Eduardo

  5. Opa, boa noite, como faço para fazer a referencia? Pois quando eu coloco o local do arquivo q vc pediu o programa da erro dizendo “A diference for a higher version or incompatible assembly cannot be added to the project.”

  6. Não consigo referenciar o shoutcast no meu projeto. Não sei o que estou fazendo de errado. Pode me ajudar por favor?
    Abraços

  7. Olá professor!

    Na verdade, não há mensagem de erro, simplesmente não sei como fazer essa referência.
    Clico com o botão direito do mouse em meu projeto, escolho a opção adicionar referência, depois clico em Browser, mas o sistema não localiza esse diretório Bin como consta abaixo

    ShoutcastMSS_v1_beta2SrcSilverlight.Media.ShoutcastBinDebug

    Se poder me ensinar como faço para adicionar o Shoutcast ao meu projeto agradeço.

    Abraço!

    1. Ulisses, bom dia!
      Se não me engano, é necessário que você abra o projeto do Shoutcast no Visual Studio e o compile. Depois disso, faça a referência da DLL em sua APP.

      Abraços,
      Eduardo H. Rizo

  8. Boa tarde professor!

    Consegui fazer a integração ao projeto, mas surgiu um outro problema.
    Mesmo mudando o final do endereço http://74.111.222.121:99999, não toca nenhuma música. Ocorre a mensagem de erro: “Erro: 3108 The remote server returned na error: NotFound.”

    Pesquisei muito na Internet, mas não encontrei nada a respeito. Onde o senhor encontrou este endereço http://74.111.222.121:99999?

    Abraços

  9. Hola! muy buena la aplicativo, pero me this costando Que funcione en Segundo plano, nos podrias dar una ayuda? o subirnos algun ejemplo de Como hacer en that funcione Segundo plano?((background task, lockscreen task)

  10. Bom dia Eduardo,
    Novamente parabéns pelo Blog,
    ótimo exemplo de rádio, porem a mesma não é executada quando por exemplo o celular é bloqueado, poderia demostrar algum exemplo ou indicar alguma forma para que a Radio funcione em segundo plano?

  11. Bom dia Eduardo. Estou tentando criar esse app a um tempo e não venho tendo sucesso. Baixei o seu exemplo e não funciona no meu emulador.
    Com o shoutcast do projeto ele retorna que a URI está vazia. Com o shoutcast que estou usando ele retorna que o formato da URI não pode ser determinado. E passando a url do listen.pls do shoutcast ele retorna que os bytes inicias da stream é zero. Poderia me ajudar? Espero respostas, abraços.

    1. Me lembro de ter tido problemas para criar meu exemplo também. Parece que a plataforma não é tão estável assim…
      Bem, me mande um trecho de código da sua APP para eu poder analisar.

      []s
      Eduardo H. Rizo

      1. Eu usei exatamente o mesmo código do projeto anexado ao tópico, que está disponível no one drive. Só alterei o endereço de shoutcast para http://sd.dnip.com.br:10302/. Mas nem o shoutcast que vem no projeto e nem o dessa rádio funcionam. Poderia dar uma olhada no projeto?

    1. Olá, tudo bom?

      No caso, esse código seria específico para o shoutcast, mas o que você gostaria de fazer exatamente?

      Abraços,
      Eduardo H. Rizo

    1. Olá Bruno, tudo bom?

      Infelizmente não tenho nenhum exemplo sobre background task no blog. Vou tentar produzir algo sobre isso e te aviso.

      Abraços,
      Eduardo H. Rizo

Deixe um comentário para ehrizo Cancelar resposta