如何停止从另一个 ViewModel 按钮播放音频
Posted
技术标签:
【中文标题】如何停止从另一个 ViewModel 按钮播放音频【英文标题】:How can I stop the playing audio from another ViewModel's button 【发布时间】:2019-07-01 20:31:37 【问题描述】:使用 MVVM,我有一个带有 3 个视图模型的窗口。2 个呈现数据和一个音频播放器 ViewModel。与其中 2 个的 UI 交互应触发音频设备的停止命令,即
PlaybackDevice.Stop();
因为我有相同的“播放”和“停止”按钮,所以播放/停止事件可以通过同一个按钮的相同命令进行管理。但不是从任何其他按钮。 我试图实例化 Player 类并调用包含 PlaybackDevice.Stop(); 的 Stop 方法。没用,所以我创建了一个静态 PlaybackDevice 设备并直接从 ViewModels 调用它 - 仍然不起作用。我应该如何做到这一点?
玩家视图模型:
#region Commands
public ICommand PlayStopTrack get; set;
// public ICommand
#endregion
#region Classes
HardwareManager hm = new HardwareManager();
public Mp3FileReader TrackMp3 get; set;
public WaveFileReader TrackWav get; set;
#endregion
#region Properties
private static string trackToPlay;
public static string TrackToPlay
get return trackToPlay;
set
trackToPlay = value;
//public string TrackToPLay get; set;
public string DidTrackStopget;set;
public static WasapiOut PlaybackDevice get; set;
public PlayerVM()
PlayStopTrack = new RelayCommand(PlayPressed, CanExecute);
private bool CanExecute(object obj)
return true;
//take the default audio device
void GetDevice()
Console.WriteLine("Prepare Device");
if (PlaybackDevice == null)
PlaybackDevice = hm.InitialiseAudioPlaybackDevice();
public void PlayTrackFromBeginning(string trackFullPath)
if (trackFullPath != null )
string fileExtension = Path.GetExtension(trackFullPath);
switch (fileExtension)
case ".mp3":
try
Console.WriteLine("Init Playing");
TrackMp3 = new Mp3FileReader(trackFullPath);
if (PlaybackDevice == null)
GetDevice();
PlaybackDevice.PlaybackStopped += OnPlaybackStopped;
if (PlaybackDevice.PlaybackState == PlaybackState.Stopped)
PlaybackDevice.Init(TrackMp3);
PlaybackDevice.Play();
GetTrackLength();
//
//catch (Exception e)
//
// MessageBox.Show(e.Message + " 1- " + e.InnerException);
//
break;
case ".wav":
//try
//
Console.WriteLine("Init Playing");
GetDevice();
PlaybackDevice.PlaybackStopped += OnPlaybackStopped;
//TODO implement wav reader.
TrackWav = new WaveFileReader(trackFullPath);
PlaybackDevice.Init(TrackWav);
PlaybackDevice.Play();
GetTrackLength();
//
//catch (Exception e)
//
// MessageBox.Show(e.Message + " - " + e.InnerException);
//
break;
ButtonLabel = "Stop";
//the actual stop method
private void OnPlaybackStopped(object sender, StoppedEventArgs e)
if (TrackMp3 != null)
Console.WriteLine("Init StopEvent");
TrackMp3.Dispose();
PlaybackDevice.Dispose();
TrackMp3 = null;
Position = 0;
CurrentTime = "00:00";
isPlaying = false;
if (TrackWav != null)
TrackWav.Dispose();
PlaybackDevice.Dispose();
TrackWav = null;
Position = 0;
CurrentTime = "00:00";
isPlaying = false;
ButtonLabel = "Play";
public void PlayPressed(object o)
if (Path.GetExtension(TrackToPlay) == ".mp3")
if (isPlaying == false
&& TrackMp3 == null
&& TrackToPlay != null)
PlayTrackFromBeginning(TrackToPlay);
// IsTrackPlaying = true;
isPlaying = true;
Timer.Start();
else if (PlaybackDevice.PlaybackState==PlaybackState.Playing)
MessageBox.Show("Stopping ama kur!");
PlaybackDevice.Stop();
isPlaying = false;
//Thread.Sleep(1000);
// PlayTrackFromBeginning(TrackToPLay);
if (Path.GetExtension(TrackToPlay) == ".wav")
if (isPlaying == false
&& TrackWav == null
&& TrackToPlay != null)
PlayTrackFromBeginning(TrackToPlay);
// IsTrackPlaying = true;
isPlaying = true;
Timer.Start();
else if (isPlaying == true)
PlaybackDevice.Stop();
isPlaying = false;
//Thread.Sleep(1000);
// PlayTrackFromBeginning(TrackToPLay);
【问题讨论】:
【参考方案1】:我不确定是否理解正确,但我会尽力帮助您。 Firstable 你的 PlayPressed 方法在哪里?您使用 PlayPressed 和 CanExecute 在 ctor 中实例化 RelayCommand 但我看不到第一种方法的代码?
【讨论】:
嗨,卢卡斯!太好了,你会尽力帮助我的。我使用 PlayPressed 方法和顶部的更多属性定义更新了代码。等待你的结果! :) 所以我的第一个问题:当你在调试时,你是否达到了这个 playPressed 方法?您是否使用特殊的框架来实现 MVVM 模式? 嗨 Lucas,没有像 MVVMLite 这样的框架,如果这是你的意思。我总是使用 PlayPressed 方法。通过 PlayDevice.Stop() 命令但音频没有停止。 卢卡斯,你提议的这件事是否需要更多帮助,或者我应该找到其他方法来解决问题?【参考方案2】:我用单例类解决了我的问题。这样,我总是使用最初播放音乐并通过另一个 ViewModel 的播放/停止按钮停止音乐的相同对象。
【讨论】:
以上是关于如何停止从另一个 ViewModel 按钮播放音频的主要内容,如果未能解决你的问题,请参考以下文章