如何重新加载播放列表BackgroundAudioPlayer?播放列表、加载、BackgroundAudioPlayer

2023-09-06 16:37:31 作者:张灿会幸福

我有一个解决方案,其中包括2个项目:主要progect和PlayListFilePlayBackAgent。

在主体工程,在一个MainPage的有一个列表框,显示不同的内容。某些内容有AudioFormat的,当我看到标题和表演在列表框中的项目 - 我点击这个列表框的项目按钮播放。此按钮使某些操作(以轨道的网址某些服务器),比去页AudioPage。在AudioPage一些方法,使从这些网址播放列表,比其isolatedStorage保存在XML格式(连载)。 这里是PlayList.cs

 公共类播放列表
{
    公共播放列表()
    {
        曲目=新的名单,其中,PlaylistTrack>();
    }

    [的XmlElement(的ElementName =音轨)
    公开名单< PlaylistTrack>轨道{设置;得到; }
    [的XmlElement(的ElementName =TrackCount)]
    公众诠释TrackCount {设置;得到; }

    公共静态播放列表加载(字符串文件名)
    {
        播放列表播放列表= NULL;

        使用(IsolatedStorageFile存储= IsolatedStorageFile.GetUserStoreForApplication())
        {
            使用(IsolatedStorageFileStream流= storage.OpenFile(文件名,FileMode.Open))
            {
                XmlSerializer的XmlSerializer的=新的XmlSerializer(typeof运算(播放列表));
                播放列表= xmlSerializer.Deserialize(流)为播放列表;
            }
        }
        返回播放列表;
    }

    公共无效保存(字符串文件名)
    {
        使用(IsolatedStorageFile存储= IsolatedStorageFile.GetUserStoreForApplication())
        {
            使用(IsolatedStorageFileStream流= storage.CreateFile(文件名))
            {
                XmlSerializer的XmlSerializer的=新的XmlSerializer(typeof运算(播放列表));
                xmlSerializer.Serialize(流,这一点);
            }
        }
    }
}
 

和一个PlayBackAgent比反序列化这个XML到播放列表,并播放。

网页播放器问题,如下图

这一切都很好,但是当我要听其不在列表框中的这些项目曲目我有一个问题。 我回到我的列表框,不是我选择一些跟踪和按钮播放。在按钮处理程序,我 .Clear(); 我的收藏,利用新的轨道新的网址,去AudioPage,并作出新的播放列表。但在模拟器我看到相同的音乐,我听before.I认为这个问题是在PlayListFilePlayBackAgent不更新从isolatedStorade播放列表。但是,当我点击不同按钮玩 - 场TrackCount改变(不介意它的名字,它只是说什么曲目播放列表号必须打的球员),我可以看到它在输出的时候写的Debug.WriteLine(Convert.ToString(playlist.TrackCount)); AudioPlayer.cs 。所以,我有什么:一个audioplayer,它播放音乐只是从我给他的第一个播放列表。当我要听另一个播放列表 - 在AudioPage我看到老的播放列表,只能从那些老的播放列表听音乐。我想:一个audioplayer可以改变播放列表每次当我按下按钮,玩,而且可以播放这种音乐

PS:我用PlayListFilePlayBackAgent,因为它可以播放音乐,即使我关闭这个应用程序。如果您需要更多code - 只是告诉我。谢谢你。

更新: 按钮处理程序

 私人无效Audio_Button_Click(对象发件人,RoutedEventArgs E)
    {
        字符串的uri = NULL;
        文本框TB = NULL;
        VAR电网=(网格)((按钮)发送方).Parent;
        的foreach(VAR孩子在grid.Children)
        {
            如果(孩子是文本框和放大器;及(串)((文本框)的孩子).TAG ==URL)
            {
                TB =(文本框)子女;
            }
        }
        URI = tb.Text;
        BackgroundAudioPlayer.Instance.SkipNext();

        //MessageBox.Show(uri);

        字符串URL =的String.Format(https://api.vk.com/method/audio.getById.xml?audios={0}&access_token={1},URI,App.AccessToken);

        变种C =新的Web客户端();
        c.OpenReadCompleted + =(sender1,E1)=>
        {
            的XDocument XML = XDocument.Load(e1.Result);
            的MessageBox.show(xml.ToString());
            VAR INF =从u在​​xml.Descendants(音频)
                      选择U;
            AudioPage.audios.Clear();
            的foreach(在INF VAR项)
            {
                AudioPage.audios.Add(新AudioAttachment((串)item.Element(URL),(串)item.Element(标题),(串)item.Element(艺术家)));
            }
            串目的地=的String.Format(/ AudioPage.xaml);
            NavigationService.Navigate(新的URI(目标,UriKind.Relative));
            AudioPage.count = 0;

        };
        c.OpenReadAsync(新的URI(URL));
    }
 

OnUseraction.cs

 保护覆盖无效OnUserAction(BackgroundAudioPlayer球员,AudioTrack轨道,UserAction行动,对象参数)
    {
        开关(动作)
        {
            案例UserAction.Play:
                如果(player.Track == NULL)
                {
                    从独立存储//装载播放列表
                    如果(播放列表== NULL)
                        播放列表= 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();
                }
                其他
                {
                    player.Play();
                }
                打破;

            案例UserAction.Pause:
                player.Pause();
                打破;

            案例UserAction.SkipNext:
                如果(currentTrack< playlist.Tracks.Count  -  1)
                {
                    currentTrack + = 1;
                    player.Track = playlist.Tracks [currentTrack] .ToAudioTrack();
                }
                其他
                {
                    player.Track = NULL;
                }
                打破;

            案例UserAction.Skip previous:
                如果(currentTrack大于0)
                {
                    currentTrack  -  = 1;
                    player.Track = playlist.Tracks [currentTrack] .ToAudioTrack();
                }
                其他
                {
                    player.Track = NULL;
                }
                打破;

            案例UserAction.Seek:
                player.Position =(时间跨度)参数;
                打破;
        }
        NotifyComplete();
    }
 

解决方案

如果你改变你的播放列表中的用户界面,你将需要信令,它需要改变它是什么打的代理一些方法,否则会继续玩下去当前曲目。

当用户点击播放按钮,叫 BackgroundAudioPlayer.Instance.SkipNext 从您的应用程序,当你得到 OnUserAction 在代理code事件中,你就可以重新检查你的播放列表的XML文件。

I have a solution, which includes 2 projects: main progect, and PlayListFilePlayBackAgent.

in main project, in MainPage a have a listBox, which shows different content. Some content has audioformat, and when i see title, and performer in listbox's item - i click button "play" in this listbox's item. This button make some operations(take track's urls from some server) and than go to page AudioPage. In AudioPage some method make a playlist from those urls, than its saves in isolatedStorage in xml format(serialized). Here is 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);
            }
        }
    }
}

And a PlayBackAgent than deserializes this xml into playlist, and plays it.

That's all good, but when i want to listen tracks which were not in those item of listbox i have a problem. I go back to my listbox, than i select some track and push button "play". In button handler, i .Clear(); my collection, take new urls of new tracks, go to AudioPage and make a new playlist. But in emulator i see the same music i listen before.I thought the problem was in that PlayListFilePlayBackAgent do not update a playlist from isolatedStorade. But when i click different buttons "play" - field TrackCount changes(don't mind to its name, it just says what number of track in playlist must play player), i can see it in output when write Debug.WriteLine(Convert.ToString(playlist.TrackCount)); in AudioPlayer.cs. So what I have: an audioplayer, which plays music only from first playlist I gave to him. When I want to listen another playlist - in AudioPage i see old playlist and can listen music only from those old playlist. What I want: an audioplayer which can change playlist everytime when I push button "play", and can play this music.

PS: I use PlayListFilePlayBackAgent because it can play music even if i close this application. If you need more code - just tell me. Thanks.

Update: Button handler

        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();
    }

解决方案

If you change your playlist in the UI you will need some way of signalling to the agent that it needs to change what it is playing, otherwise it will continue playing the current track.

When user hits the play button, call BackgroundAudioPlayer.Instance.SkipNext from your app, and when you get the OnUserAction event in your agent code you'll be able to recheck your playlist XML file.