SimpleAudioPlayer CurrentPosition 和 Duration 始终为 0

SimpleAudioPlayer CurrentPosition and Duration are always 0

我正在尝试使用可以添加到 ListView 到其他 ListView 中的音频列表在 Xamarin Forms 中制作播放列表。 我正在使用 SimpleAudioPlayer plugin 来达到这个目的。 我想连续播放多个音频。

播放功能运行良好,Stream 没有抛出任何 Exception。 现在,代码总是多次播放相同的音频。 为了达到连续的效果,我尝试使用 CurrentPositionDuration 属性在 for 循环内为播放列表中的每个曲目制作一个 while 循环,但我没有找到关于这两个的任何自我说明文档属性。

using G.Models;
using Plugin.SimpleAudioPlayer;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Input;
using Xamarin.Forms;

namespace G.ViewModels
{
    class ABSViewModel : BaseViewModel{
        public ObservableCollection<PlayListItem> Playlist { get; set; }
        public ICommand PlayPlaylistCommand { get; set; }
        private PlayListItem playlistSelectedItem;
        public PlayListItem PlaylistSelectedItem
        { 
            get {
                return playlistSelectedItem;
            }
            set {
                playlistSelectedItem = value;
            }
        }

        public ABSViewModel()
        {
            audio = CrossSimpleAudioPlayer.CreateSimpleAudioPlayer();
            PlayButtonText = "PLAY";
            PlayButtonImage = "play_icon.png";
            PlayButtonFlag = "1";
            PlayPlaylistCommand = new Command(PlayPlaylist);
            Playlist = new ObservableCollection<PlayListItem>();
        }

        private async void PlayPlaylist()
        {
            if (PlayButtonFlag == "1")
            {
                PlayButtonText = "PAUSE";
                PlayButtonImage = "pause_icon.png";
                PlayButtonFlag = "0";
                int startPosition;

                if(PlaylistSelectedItem != null)
                {
                    startPosition = 0;
                }
                else
                {
                    startPosition = Playlist.IndexOf(playlistSelectedItem);
                }
                for(int i = 0; i < Playlist.Count; i++)
                {
                    if (audio.IsPlaying) audio.Stop();
                    PlaylistSelectedItem = Playlist[i];
                    OnPropertyChanged(nameof(Playlist));
                    audio.Load(GetStreamFromFile(Playlist[i].Name + ".wav"));
                    audio.Play();
                    while (audio.CurrentPosition != audio.Duration) {
                        Debug.WriteLine("Test");
                    }
                }
            }
            else
            {
                PlayButtonText = "PLAY";
                PlayButtonImage = "play_icon.png";
                PlayButtonFlag = "1";
                if (audio.IsPlaying) audio.Pause();
            }
            NotifyButtonChange();
        }


        Stream GetStreamFromFile(string filename)
        {
            var assembly = typeof(App).GetTypeInfo().Assembly;
            var stream = assembly.GetManifestResourceStream("G2019." + "RSNZBile.wav");
            return stream;
        }

        private void NotifyButtonChange()
        {
            OnPropertyChanged(nameof(PlayButtonText));
            OnPropertyChanged(nameof(PlayButtonImage));
            OnPropertyChanged(nameof(PlayButtonFlag));
        }

    }
}

我省略了 Commands 以向播放列表添加元素或停止播放列表播放,因为我认为它们脱离了上下文。 现在,当我按下 "Play" 按钮时,我在调试器中看到我的 while 循环根本没有开始。因此,播放器在几毫秒内播放了播放列表中的所有元素,而人类唯一能听到的就是最后一个。那是因为我的 CurrentPositionDuration 属性都设置为 0。为什么? 有人试过这样做吗?

如果有人感兴趣,我使用 PlaybackEnded 事件解决了这个问题。 for 循环内的每一段代码都被移动到 PlaybackEnded 处理程序函数内,不需要 whileDuration 值设置为 0 仍然是个谜。

private async void PlayPlaylist(string value)
{
    if (PlayButtonMode == 1)
    {
        int startPosition;
        //Playing playlist from selected item if user selected one. (first item if he didn't)
        if (PlaylistSelectedItem == null) startPosition = 0;
        else startPosition = Playlist.IndexOf(playlistSelectedItem);
        if (audio.IsPlaying) audio.Stop();
        PlaylistSelectedItem = Playlist[startPosition];
        audio.Load(GetStreamFromFile(PlaylistSelectedItem.Name + ".wav"));
        audio.Play();
        audio.PlaybackEnded += Audio_PlaybackEnded;
    }
    else if (PlayButtonMode == 2)
        audio.Play();
    else
    {
        if (audio.IsPlaying) audio.Pause();
    }
    ChangeButtonMode(PlayButtonMode);
}

private void ChangeButtonMode(int senderMode)
{
    if (senderMode == 1 || senderMode == 2)
    {
        PlayButtonText = "PAUSE";
        PlayButtonImage = "pause_icon.png";
        PlayButtonMode = 0;
    }
    else
    {
        PlayButtonText = "PLAY";
        PlayButtonImage = "play_icon.png";
        if (senderMode == 3) PlayButtonMode = 1; 
        else PlayButtonMode = 2;
    }
    NotifyButtonChange();
}

private void Audio_PlaybackEnded(object sender, EventArgs e)
{
    //Check if next playlist element exists
    if(Playlist.IndexOf(PlaylistSelectedItem) + 1 < Playlist.Count)
    {
        PlaylistSelectedItem = Playlist[Playlist.IndexOf(PlaylistSelectedItem) + 1];
        if (audio.IsPlaying) audio.Stop();
        audio.Load(GetStreamFromFile(PlaylistSelectedItem.Name + ".wav"));
        audio.Play();
        audio.PlaybackEnded += Audio_PlaybackEnded;
    }else if(audio.IsPlaying) audio.Stop();   
}


private void StopAudio()
{
    if (audio.IsPlaying)
        audio.Stop();
    ChangeButtonMode(3);
}