Опубликован: 11.01.2013 | Доступ: свободный | Студентов: 623 / 124 | Длительность: 12:06:00
Лекция 5:

Лабораторный практикум 4

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >

Лабораторная работа №18. Проигрыватель музыки

Задание

Создать приложение для Windows Phone 7, проигрывающее музыку в фоне. Предусмотреть возможность перехода к предыдущей/следующей песне и постановки на паузу. Добавить для приложения тайл, который будет меняться при проигрывании песни.

Освоение

  • фоновое воспроизведение музыки
  • тайлы

Описание

Создадим новый проект Silverlight for Windows PhoneWindows Phone Application.

Добавим в него папку Audio, а в нее несколько аудио-файлов, формат которых поддерживает Windows Phone 7. Установим значение свойства "Build Action" в "Content", а "Copy to Output Directory" в "Copy if newer".

Добавим два изображения размера 173x173 (для тайлов). Назовем их, например, "Tile1.png" и "Tile2.png". Установим для данных изображений свойство "Build Action" в "Content".

Примечание: тайлы – это изображения, отображающиеся на главной странице Windows Phone 7. Они могут иметь пояснительные надписи и обратную сторону – другое изображение, которое будет периодически появляться. Для того чтобы добавить тайл приложения на главную страницу, в списке приложений нажмите на ваше приложение и удерживайте. В появившемся контекстном меню выберете "pin to start" Рис. 5.3 :

Отображение тайла приложения на главной странице

Рис. 5.3. Отображение тайла приложения на главной странице

В код главной страницы добавим функцию установки тайла. При проигрывании мелодии в параметр IsPlay будем передавать true, в противном случае – false.

private void SetTile(bool IsPlay = false)
        {
            ShellTile apptile = ShellTile.ActiveTiles.First();

            StandardTileData appTileData = new StandardTileData();
            appTileData.Title = "";
            appTileData.Count = 0;

            if (IsPlay)
            {
                appTileData.BackgroundImage = new Uri("/Tile2.png", UriKind.RelativeOrAbsolute);
            }
            else
            {
                appTileData.BackgroundImage = new Uri("/Tile1.png", UriKind.RelativeOrAbsolute);
            }

            apptile.Update(appTileData);
        }

В конструктор класса добавим:

SetTile();

Также в коде должна быть добавлена директива:

using Microsoft.Phone.Shell;

Теперь добавим в решение (solution) новый проект Silverlight for Windows PhoneWindows Phone Audio Playback Agent. В наш основной проект добавим ссылку на данный проект: Add Reference… – Projects - <имя проекта аудио-плейера>.

В файл AudioPlayer.cs добавим директиву:

using System.Collections.Generic;

Затем в класс добавим две глобальные переменные: номер текущей песни и список песен. В список песен сразу добавим имена файлов наших песен. Также можно указать название, автора и альбом.

private static int currentTrackNumber = 0;

        private static List<AudioTrack>_playList = new List<AudioTrack>
        {
            new AudioTrack(new Uri("Elena Gheorghe - Balkan Girls.mp3", UriKind.Relative), 
                            "Balkan Girls", 
                            "Elena Gheorghe", 
                            "Eurovision 2010", 
                            null),

            new AudioTrack(new Uri("Lara Fabian - I Guess I Loved You.mp3", UriKind.Relative), 
                            "I Guess I Loved You", 
                            "Lara Fabian", 
                            "Unknown", 
                            null),

            new AudioTrack(new Uri("velvet-prodavec_kukol.mp3", UriKind.Relative), 
                            "Продавец кукол", 
                            "Вельвет", 
                            "Unknown", 
                            null),

            //remote URI
            new AudioTrack(new Uri("http://traffic.libsyn.com/wpradio/WPRadio_29.mp3", UriKind.Absolute), 
                            "Episode 29", 
                            "Windows Phone Radio", 
                            "Windows Phone Radio Podcast", 
                            null)
        };

Добавим в класс три метода:

private void PlayNextTrack(BackgroundAudioPlayer player)
        {
            if (++currentTrackNumber >= _playList.Count)
            {
                currentTrackNumber = 0;
            }

            PlayTrack(player);
        }

        private void PlayPreviousTrack(BackgroundAudioPlayer player)
        {
            if (--currentTrackNumber < 0)
            {
                currentTrackNumber = _playList.Count - 1;
            }

            PlayTrack(player);
        }

        private void PlayTrack(BackgroundAudioPlayer player)
        {
            // Sets the track to play. When the TrackReady state is received, 
            // playback begins from the OnPlayStateChanged handler.
            player.Track = _playList[currentTrackNumber];
        }

Изменим функции OnPlayStateChanged() и OnUserAction() :

protected override void OnPlayStateChanged(BackgroundAudioPlayer player, 
AudioTrack track, PlayState playState)
        {
            switch (playState)
            {
                case PlayState.TrackReady:
                    // The track to play is set in the PlayTrack method.
                    player.Play();
                    break;

                case PlayState.TrackEnded:
                    PlayNextTrack(player);
                    break;
            }

            NotifyComplete();
        }

        protected override void OnUserAction(BackgroundAudioPlayer player, 
          AudioTrack track, UserAction action, object param)
        {
            switch (action)
            {
                case UserAction.Play:
                    if (isPaused)
                        player.Play();
                    else
                        PlayTrack(player);
                    
                    isPaused = false;
                    break;

                case UserAction.Pause:
                    player.Pause();
                    isPaused = true;
                    break;

                case UserAction.SkipPrevious:
                    PlayPreviousTrack(player);
                    isPaused = false;
                    break;

                case UserAction.SkipNext:
                    PlayNextTrack(player);
                    isPaused = false;
                    break;
            }

            NotifyComplete();
        }

Теперь откроем файл App.xaml основного проекта.

Добавим 2 директивы:

using System.IO.IsolatedStorage;
using System.Windows.Resources;

Поскольку фоновый аудио-проигрыватель умеет воспроизводить музыку только из изолированного проигрывателя, добавим в класс App функцию, которая будет копировать в проигрыватель песни из ресурсов. Вызов функции добавим в конструктор класса.

        private void CopyToIsolatedStorage()
        {
            using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                string[] files = new string[] { "Elena Gheorghe - Balkan Girls.mp3",
                                                "Lara Fabian - I Guess I Loved You.mp3",
                                                "velvet-prodavec_kukol.mp3" };

                foreach (var _fileName in files)
                {
                    if (!storage.FileExists(_fileName))
                    {
                        string _filePath = "Audio/" + _fileName;
                        StreamResourceInfo resource = Application.GetResourceStream(new Uri(_filePath, UriKind.Relative));

                        using (IsolatedStorageFileStream file = storage.CreateFile(_fileName))
                        {
                            int chunkSize = 4096;
                            byte[] bytes = new byte[chunkSize];
                            int byteCount;

                            while ((byteCount = resource.Stream.Read(bytes, 0, chunkSize)) > 0)
                            {
                                file.Write(bytes, 0, byteCount);
                            }
                        }
                    }
                }
            }
        }

Вернемся к главной странице. В файл разметки добавим несколько текстовых блоков для вывода информации о текущей песне и меню, состоящее из 3 кнопок: назад, воспроизведение/пауза, вперед.

Теперь перейдем к коду главной страницы. Добавим директиву:

using Microsoft.Phone.BackgroundAudio;

В конструкторе подпишемся на изменение состояния воспроизведения:

 BackgroundAudioPlayer.Instance.PlayStateChanged += new EventHandler(Instance_PlayStateChanged);

Добавим обработчик события:

        void Instance_PlayStateChanged(object sender, EventArgs e)
        {
            switch (BackgroundAudioPlayer.Instance.PlayerState)
            {
                case PlayState.Playing:
                    ((ApplicationBarIconButton)ApplicationBar.Buttons[1])
                     .IconUri = new Uri(PATH_TO_PAUSE_IMG, UriKind.Relative);
                    SetTile(true);
                    break;

                case PlayState.Paused:
                case PlayState.Stopped:
                    ((ApplicationBarIconButton)ApplicationBar.Buttons[1])
                      .IconUri = new Uri(PATH_TO_PLAY_IMG, UriKind.Relative);
                    SetTile(false);
                    break;
            }

            if (null != BackgroundAudioPlayer.Instance.Track)
            {
                txtAuthor.Text = BackgroundAudioPlayer.Instance.Track.Artist;
                txtAlbum.Text = BackgroundAudioPlayer.Instance.Track.Album;
                txtDur.Text = String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Minutes) + ":" +
                                String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Seconds);

                PageTitle.Text = BackgroundAudioPlayer.Instance.Track.Title;

                ...
            }
        }

Обработчики нажатий на кнопки меню:

              private void Menu1_Click(object sender, EventArgs e)
        {
            BackgroundAudioPlayer.Instance.SkipPrevious();
        }

        private void Menu2_Click(object sender, EventArgs e)
        {
            if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
            {
                BackgroundAudioPlayer.Instance.Pause();
            }
            else
            {
                BackgroundAudioPlayer.Instance.Play();

            }
        }

        private void Menu3_Click(object sender, EventArgs e)
        {
            BackgroundAudioPlayer.Instance.SkipNext();
        }

При закрытии приложения музыка будет продолжать воспроизводиться. При повторном открытии приложения будем выдавать пользователю информацию о текущей песне. Для этого переопределим метод OnNavigatedTo() главной страницы:

      protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            //если при хагрузке приложения уже играет музыка
            if (PlayState.Playing == BackgroundAudioPlayer.Instance.PlayerState)
            {
                txtAuthor.Text = BackgroundAudioPlayer.Instance.Track.Artist;
                txtAlbum.Text = BackgroundAudioPlayer.Instance.Track.Album;
                txtDur.Text = String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Minutes) + ":" +
                                String.Format("{0:00}", BackgroundAudioPlayer.Instance.Track.Duration.Seconds);

                PageTitle.Text = BackgroundAudioPlayer.Instance.Track.Title;
                ((ApplicationBarIconButton)ApplicationBar.Buttons[1])
                      .IconUri = new Uri(PATH_TO_PAUSE_IMG, UriKind.Relative);

                ...
            }
            else
            {
                txtAuthor.Text = "";
                txtAlbum.Text = "";
                txtDur.Text = "";

                PageTitle.Text = PAGE_DEFAULT_TITLE_TEXT;
                ((ApplicationBarIconButton)ApplicationBar.Buttons[1]).IconUri =
                      new Uri(PATH_TO_PLAY_IMG, UriKind.Relative);

                ...
            }
        }
< Лекция 4 || Лекция 5: 12345 || Лекция 6 >