Как перезагрузить плейлист в BackgroundAudioPlayer?

У меня есть решение, которое включает в себя 2 проекта: основной проект и PlayListFilePlayBackAgent. введите здесь описание изображения

в основном проекте в MainPage есть listBox, который показывает различный контент. Некоторый контент имеет аудиоформат, и когда я вижу название и исполнителя в элементе списка - я нажимаю кнопку "воспроизвести" в этом элементе списка. Эта кнопка выполняет некоторые действия (берет URL-адреса треков с какого-либо сервера), а затем переходит на страницу AudioPage. В AudioPage некоторый метод создает список воспроизведения из этих URL-адресов, а затем сохраняет его в изолированном хранилище в формате xml (сериализованном). Вот PlayList.cs

 public class Playlist
{
    public Playlist()
    {
        Tracks = new List<PlaylistTrack>();
    }

    [XmlElement(ElementName = "Track")]
    public List<PlaylistTrack> Tracks { set; get; }
    [XmlElement(ElementName = "TrackCount")]
    public int TrackCount { set; get; }

    public static Playlist Load(string filename)
    {
        Playlist playlist = null;

        using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            using (IsolatedStorageFileStream stream = storage.OpenFile(filename, FileMode.Open))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Playlist));
                playlist = xmlSerializer.Deserialize(stream) as Playlist;
            }
        }
        return playlist;
    }

    public void Save(string filename)
    {
        using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            using (IsolatedStorageFileStream stream = storage.CreateFile(filename))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Playlist));
                xmlSerializer.Serialize(stream, this);
            }
        }
    }
}

И PlayBackAgent затем десериализует этот xml в список воспроизведения и воспроизводит его.

Это все хорошо, но когда я хочу прослушать треки, которых нет в этом списке, у меня возникает проблема. Я возвращаюсь в свой список, затем выбираю трек и нажимаю кнопку «воспроизвести». В обработчике кнопки я .Clear(); мою коллекцию, беру новые URL-адреса новых треков, иду на AudioPage и создаю новый плейлист. Но в эмуляторе я вижу ту же музыку, которую слушал раньше. Я думал, что проблема в том, что PlayListFilePlayBackAgent не обновляет плейлист из изолированного хранилища. Но когда я нажимаю разные кнопки "играть" - поле TrackCount меняется (не обращайте внимания на его название, оно просто говорит, какой номер трека в плейлисте должен играть проигрыватель), я вижу его в выводе, когда записываю Debug.WriteLine(Convert.ToString(playlist.TrackCount)); в AudioPlayer.cs. Итак, что у меня есть: аудиоплеер, который воспроизводит музыку только из первого плейлиста, который я ему дал. Когда я хочу прослушать другой плейлист - в AudioPage я вижу старый плейлист и могу слушать музыку только из этого старого плейлиста. Что я хочу: аудиоплеер, который может менять список воспроизведения каждый раз, когда я нажимаю кнопку "воспроизведение", и может воспроизводить эту музыку.

PS: я использую PlayListFilePlayBackAgent, потому что он может воспроизводить музыку, даже если я закрою это приложение. Если вам нужно больше кода - просто скажите мне. Спасибо.

Обновление: обработчик кнопок

        private void Audio_Button_Click(object sender, RoutedEventArgs e)
    {
        string uri = null;
        TextBox tb = null;
        var grid = (Grid)((Button)sender).Parent;
        foreach (var child in grid.Children)
        {
            if (child is TextBox && (string)((TextBox)child).Tag == "URL")
            {
                tb = (TextBox)child;
            }
        }
        uri = tb.Text;
        BackgroundAudioPlayer.Instance.SkipNext();

        //MessageBox.Show(uri);

        string url = string.Format("https://api.vk.com/method/audio.getById.xml?audios={0}&access_token={1}", uri, App.AccessToken);

        var c = new WebClient();
        c.OpenReadCompleted += (sender1, e1) =>
        {
            XDocument xml = XDocument.Load(e1.Result);
            MessageBox.Show(xml.ToString());
            var inf = from u in xml.Descendants("audio")
                      select u;
            AudioPage.audios.Clear();
            foreach (var item in inf)
            {
                AudioPage.audios.Add(new AudioAttachment((string)item.Element("url"), (string)item.Element("title"), (string)item.Element("artist")));
            }
            string destination = string.Format("/AudioPage.xaml");
            NavigationService.Navigate(new Uri(destination, UriKind.Relative));
            AudioPage.count = 0;

        };
        c.OpenReadAsync(new Uri(url));
    }

OnUseraction.cs

        protected override void OnUserAction(BackgroundAudioPlayer player, AudioTrack track, UserAction action, object param)
    {
        switch (action)
        {
            case UserAction.Play:
                if (player.Track == null)
                {
                    // Load playlist from isolated storage
                    if (playlist == null)
                        playlist = Playlist.Load("playlist.xml");
                 //   Debug.WriteLine(playlist.Tracks[0].Title);
                    Debug.WriteLine(Convert.ToString(playlist.TrackCount));
                    currentTrack = playlist.TrackCount;
                    player.Track = playlist.Tracks[currentTrack].ToAudioTrack();
                }
                else
                {
                    player.Play();
                }
                break;

            case UserAction.Pause:
                player.Pause();
                break;

            case UserAction.SkipNext:
                if (currentTrack < playlist.Tracks.Count - 1)
                {
                    currentTrack += 1;
                    player.Track = playlist.Tracks[currentTrack].ToAudioTrack();
                }
                else
                {
                    player.Track = null;
                }
                break;

            case UserAction.SkipPrevious:
                if (currentTrack > 0)
                {
                    currentTrack -= 1;
                    player.Track = playlist.Tracks[currentTrack].ToAudioTrack();
                }
                else
                {
                    player.Track = null;
                }
                break;

            case UserAction.Seek:
                player.Position = (TimeSpan)param;
                break;
        }
        NotifyComplete();
    }

person eg01st    schedule 14.12.2012    source источник


Ответы (3)


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

Когда пользователь нажмет кнопку воспроизведения, вызовите BackgroundAudioPlayer.Instance.SkipNext из вашего приложения, и когда вы получите событие OnUserAction в коде своего агента, вы сможете перепроверить XML-файл списка воспроизведения.

person Paul Annetts    schedule 15.12.2012
comment
Я не уверен, что понимаю. Я обновил сообщение с некоторым кодом. А когда нажимаю плей - слышу следующий трек из старой коллекции. Можете ли вы написать какой-нибудь пример? - person eg01st; 15.12.2012
comment
Помните, что агент и основное приложение работают в разных процессах и не могут совместно использовать список воспроизведения в памяти. В основном поместите что-то похожее на то, что у вас есть в OnUserAction для воспроизведения в SkipNext (учет изменения дорожки и определение того, изменился ли файл списка воспроизведения). - person Paul Annetts; 16.12.2012

if (playlist == null)
    playlist = Playlist.Load("playlist.xml");

Где вы устанавливаете плейлист обратно на Null?

Чувак, я чувствую твою боль. У меня точно такая же ситуация, и я использовал точно такой же подход (за исключением того, что я использовал коллекцию IsolatedStorageSettings.ApplicationSettings вместо записи в файл).

Он отлично работает для 1-го запуска.

Поведение действительно странное. Я видел обновление данных в приложении переднего плана, но чтение тех же настроек из проигрывателя не дало мне новых данных. Я также пытался писать с новым ключом настроек (на случай, если BAP кэширует результаты или что-то в этом роде), но получил нестабильные результаты, когда он работал до 2-5 обновлений, а затем просто перестал видеть новые ключи настроек в коллекции. Сводит меня с ума...

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

Пожалуйста, дайте мне знать, если вам повезет с этой проблемой.

person Kirill    schedule 03.01.2013

Пожалуй, одна из самых подробных сведений о воспроизведении аудио на Windows Phone. Проверьте проект здесь http://developer.nokia.com/community/wiki/Streaming_MP3_player_in_WP7 .

Однако я должен сказать, что в моем случае мне пришлось загружать базу данных и извлекать информацию, перебирая списки без использования JSON. Ниже приведен код;

private void LoadPlayListFromIsolatedStorage(BackgroundAudioPlayer player)
    {
        // clear previous playlist
        _playList.Clear();
        // access to isolated storage
        IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication();
        using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("AlbumsData.dat", FileMode.OpenOrCreate, isoStore))
        {
            if (stream.Length > 0)
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(List<Album>));
                List<Album> strm = serializer.ReadObject(stream) as List<Album>;
                List<Song> _songs = strm[0].Songs;
                for (int i = 0; i < _songs.Count; i++)
                {
                    AudioTrack audioTrack = new AudioTrack(
                            new Uri(_songs[i].Directory, UriKind.Absolute), // URL
                            _songs[i].Title,         // MP3 Music Title
                            "Artist",        // MP3 Music Artist
                            "Album",         // MP3 Music Album name
                            new Uri(_songs[i].AlbumArt, UriKind.Absolute)    // MP3 Music Artwork URL
                            );

                    _playList.Add(audioTrack);
                }
            }
            else
            {
                // no AudioTracks from Isolated Storage
            }
            // start playing
            PlayTrack(player);

        }
person desw    schedule 22.10.2014