如何停止从另一个 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 按钮播放音频的主要内容,如果未能解决你的问题,请参考以下文章

播放和停止声音(2 次观看)

如何停止 HTML5 的音频标签播放的音频

如何在播放/暂停控制功能中停止无限循环

为啥我的停止按钮在这个 javascript 音频播放器上不起作用?

按下后退按钮时音频停止播放

SwiftUI 的播放/停止按钮