Пример простого онлайн-проигрывателя

Если вы ещё не знаете, как написать приложение, которое будет использовать RSS ленту как источник контента, за основу можно взять пример Работа с HTTP в 3 строчки, или делаем свой RSS Reader c WebClient и WebBrowser. Хотите добавить поддержку карт и использовать геолокационные данные, есть пример Карты и гелокационные данные на Windows Phone. После этого, с использованием статьи Обновления Live Tiles в фоновых агентах можно просто добавить подержку Live Tiles в ваше приложение. Если начали задумываться о моентизации - пора читать статью Монетизация приложений — где деньги лежат.

Кажется, что чего-то не хватает? Давайте добавим музыки в наше приложение! Напишем простой плеер, который будет проигрывать онлайн-радио.

Традиционно начнём с создания пустого приложения на основе шаблона Windows Phone Application. В качестве источника онлайнового звукового потока я буду использовать онлайн-вещание Радио Ultra. Я буду использовать 320Kbit-ный поток, и проигрывать буду с использованием MediaElement. Подробнее об использовании Media под Windows Phone можно прочитать в статье Media in Silverlight for Windows Phone.

Приступим собственно к созданию плеера. Добавим элемент управлеия MediaElement в XAML код основной страницы приложения, раскомментируем ApplicationBar и, используя Expression Blend (или вручную) добавим 2 иконки для кнопок ApplicationBar. В итоге, XAML код будет выглядеть следующим образом:

<!--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">
        <TextBlock x:Name="ApplicationTitle" Text="РАДИО УЛЬТРА" 
 Style='{StaticResource PhoneTextNormalStyle}'/>
        <TextBlock x:Name='PageTitle' Text='онлайн' Margin='9,-7,0,0' 
 Style='{StaticResource PhoneTextTitle1Style}'/>
    </StackPanel>
 
    <!--ContentPanel - place additional content here-->
    <Grid x:Name='ContentPanel' Grid.Row='1' Margin='12,0,12,0'>
        <MediaElement Name='RadioPlayer' AutoPlay='False'></MediaElement>            
    </Grid>
</Grid>
 
<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible='True' IsMenuEnabled='True'>
        <shell:ApplicationBarIconButton IconUri='/icons/appbar.transport.play.rest.png' 
 Text='Играть'/>                        
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

По умолчанию, как только у MediaElement появляется источник, он начинает играть. Чтобы этого не происходило, в его свойствах мы выставили значение AutoPlay в false.

Кроме этого, в проекте добавится папка icons с иконками play и pause:

А главная страница приложения будет выглядеть следующим образом:

Осталось добавить немного кода. Перед тем, как начнём писать код, добавим в using блок Microsoft.Phone.Shell, чтобы удобно работать с ApplicaionBarIconButton:

using Microsoft.Phone.Shell;

Первое, что мы добавим – это константу с URL по которому вещает радио. Дальше, необходимо добавить обработчики кнопок ApplicationBar и обработчик состояний MediaElement. Как обычно, я все эти процедуры выполняю в методе Loaded страницы.

const string RadioUltraOnlineURL = "http://188.127.243.169/ultra-320";
 
// Constructor
public MainPage()
{
    InitializeComponent();
    Loaded += new RoutedEventHandler(MainPage_Loaded);
}
 
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    RadioPlayer.Source = new Uri(RadioUltraOnlineURL);
    ApplicationBarIconButton PlayPauseButton = ApplicationBar.Buttons[0] as ApplicationBarIconButton;
    PlayPauseButton.Click += new EventHandler(PlayPauseButton_Click);
}
 
void PlayPauseButton_Click(object sender, EventArgs e)
{
    if (RadioPlayer.CurrentState == MediaElementState.Playing)
    {
        RadioPlayer.Pause();
        ApplicationBarIconButton PlayPauseButton = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
        PlayPauseButton.IconUri = new Uri("icons/appbar.transport.play.rest.png", UriKind.RelativeOrAbsolute);
        PlayPauseButton.Text = "играть";
 
    }
    else if (RadioPlayer.CurrentState != MediaElementState.Playing)
    {
        RadioPlayer.Play();
        ApplicationBarIconButton PlayPauseButton = this.ApplicationBar.Buttons[0] as ApplicationBarIconButton;
        PlayPauseButton.IconUri = new Uri("icons/appbar.transport.pause.rest.png", UriKind.RelativeOrAbsolute);
        PlayPauseButton.Text = "пауза";
    }
}

Собственно - это минимальный набор кода, без обработки ошибок и состояний буферизации и скачивания, который позволяет добавить проигрывание потоковой онлайн музыки в ваше приложение.

Чтобы не создавать у пользователя ощущения медленного приложения, можно по умолчанию сделать отключённой кнопку проигрывания, а для индинкации соединения и буферизации добавить обработку событий изменения состояния MediaElement - тогда XAML код будет выглядеть следующим образом:

<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBarIconButton IconUri="/icons/appbar.transport.play.rest.png" 
 Text="Играть"
 IsEnabled="false"/>                        
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

А код C# пополнится двумя обработчиками и дополнительным кодом инициализации в обработчике Loaded:

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    RadioPlayer.Source = new Uri(RadioUltraOnlineURL);
    RadioPlayer.MediaOpened += new RoutedEventHandler(RadioPlayer_MediaOpened);    
    RadioPlayer.CurrentStateChanged += new RoutedEventHandler(RadioPlayer_CurrentStateChanged);
 
    ApplicationBarIconButton PlayPauseButton = ApplicationBar.Buttons[0] as ApplicationBarIconButton;
    PlayPauseButton.Click += new EventHandler(PlayPauseButton_Click);
}
 
void RadioPlayer_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    if (RadioPlayer.CurrentState == MediaElementState.Buffering ||
        RadioPlayer.CurrentState == MediaElementState.Opening)
    {
        if (SystemTray.ProgressIndicator == null)
            SystemTray.ProgressIndicator = new ProgressIndicator();
 
        SystemTray.ProgressIndicator.IsIndeterminate = true;
        SystemTray.ProgressIndicator.IsVisible = true;
        SystemTray.ProgressIndicator.Text = "Соединяемся с Радио Ultra ...";
 
    }
    else
    {
        SystemTray.ProgressIndicator.IsIndeterminate = false;
        SystemTray.ProgressIndicator.IsVisible = false;
    }
}
 
void RadioPlayer_MediaOpened(object sender, RoutedEventArgs e)
{
    if (SystemTray.ProgressIndicator != null)
        SystemTray.ProgressIndicator.IsVisible = false;
 
    ((ApplicationBarIconButton)ApplicationBar.Buttons[0]).IsEnabled = true;
 
}

Этого уже достаточно, чтобы поведение приложения было более понятным пользователю. В качестве самостоятельно упражнения добавьте определения наличия сетевого соединения и обработку ошибок.

Проект приложения UltraPlayerDemo

Полезные ссылки: