DevsDicas

[Desenvolvimento] Como desenvolver uma APP Windows Phone 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_beta2\Src\Silverlight.Media.Shoutcast\Bin\Debug 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:


  
  




  
    

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">

  

...

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
  {
  /// 
  /// Representa um sream do Shoutcast
  /// 
  private ShoutcastMediaStreamSource source;

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

  /// 
  /// Obtem o elemento Media da página
  /// 
  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("https://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) && (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.

Post Relacionado: 

Grande abraço,
Eduardo Henrique Rizo (@eduardorizo)

Fonte: Blog do Eduardo H. Rizo