SimpleAudioPlayer CurrentPosition 和 Duration 始终为 0
SimpleAudioPlayer CurrentPosition and Duration are always 0
我正在尝试使用可以添加到 ListView
到其他 ListView
中的音频列表在 Xamarin Forms 中制作播放列表。
我正在使用 SimpleAudioPlayer plugin 来达到这个目的。
我想连续播放多个音频。
播放功能运行良好,Stream
没有抛出任何 Exception
。
现在,代码总是多次播放相同的音频。
为了达到连续的效果,我尝试使用 CurrentPosition
和 Duration
属性在 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));
}
}
}
我省略了 Command
s 以向播放列表添加元素或停止播放列表播放,因为我认为它们脱离了上下文。
现在,当我按下 "Play" 按钮时,我在调试器中看到我的 while
循环根本没有开始。因此,播放器在几毫秒内播放了播放列表中的所有元素,而人类唯一能听到的就是最后一个。那是因为我的 CurrentPosition
和 Duration
属性都设置为 0。为什么?
有人试过这样做吗?
如果有人感兴趣,我使用 PlaybackEnded
事件解决了这个问题。
for
循环内的每一段代码都被移动到 PlaybackEnded
处理程序函数内,不需要 while
。 Duration
值设置为 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);
}
我正在尝试使用可以添加到 ListView
到其他 ListView
中的音频列表在 Xamarin Forms 中制作播放列表。
我正在使用 SimpleAudioPlayer plugin 来达到这个目的。
我想连续播放多个音频。
播放功能运行良好,Stream
没有抛出任何 Exception
。
现在,代码总是多次播放相同的音频。
为了达到连续的效果,我尝试使用 CurrentPosition
和 Duration
属性在 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));
}
}
}
我省略了 Command
s 以向播放列表添加元素或停止播放列表播放,因为我认为它们脱离了上下文。
现在,当我按下 "Play" 按钮时,我在调试器中看到我的 while
循环根本没有开始。因此,播放器在几毫秒内播放了播放列表中的所有元素,而人类唯一能听到的就是最后一个。那是因为我的 CurrentPosition
和 Duration
属性都设置为 0。为什么?
有人试过这样做吗?
如果有人感兴趣,我使用 PlaybackEnded
事件解决了这个问题。
for
循环内的每一段代码都被移动到 PlaybackEnded
处理程序函数内,不需要 while
。 Duration
值设置为 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);
}