为啥 PlaybackState 在 PlaybackStopped 触发后仍保持在 Playing 状态?

Posted

技术标签:

【中文标题】为啥 PlaybackState 在 PlaybackStopped 触发后仍保持在 Playing 状态?【英文标题】:Why does PlaybackState remain at Playing after PlaybackStopped fires?为什么 PlaybackState 在 PlaybackStopped 触发后仍保持在 Playing 状态? 【发布时间】:2012-04-20 08:50:46 【问题描述】:

我对使用 NAudio 有点陌生,所以我肯定错过了一些重要的东西,因此提出了这个问题。

从示例/演示代码开始,我整理了一个尽可能简单的类来播放 MP3 或 WAV 文件:

public class AudioPlayer : IDisposable

    WaveStream _waveStream; // sound data stream
    WaveChannel32 _waveChannel32; // sound channel ??
    IWavePlayer _iWavePlayer; // sound output driver

    public bool IsPlaying
    
        get  return _iWavePlayer != null 
                     && _iWavePlayer.PlaybackState 
                         != Wave.PlaybackState.Stopped; 
    

    public PlaybackState PlaybackState
    
        get  return _iWavePlayer.PlaybackState; 
    

    public void LoadMp3(byte[] mp3Bytes)
    
        Load(CreateInputStreamFromMp3Bytes(mp3Bytes));
    

    public void LoadFile(string filename)
    
        Load(CreateInputStream(filename));
    

    void Load(WaveStream waveStream)
    
        if (_iWavePlayer != null)
            Dispose();
        _iWavePlayer = new WaveOut();
        _iWavePlayer.PlaybackStopped += 
            new EventHandler(_iWavePlayer_PlaybackStopped);
        _waveStream = waveStream;
        _waveChannel32 = new WaveChannel32(_waveStream);
        _waveChannel32.PadWithZeroes = false;
        _iWavePlayer.Init(_waveChannel32);
    

    void _iWavePlayer_PlaybackStopped(object sender, EventArgs e)
    
        Stop();
    

    static WaveStream CreateInputStreamFromMp3Bytes(byte[] mp3Bytes)
    
        return new Mp3FileReader(new MemoryStream(mp3Bytes), false);
    

    static WaveStream CreateInputStream(string fileName)
    
        if (fileName.EndsWith(".wav"))
            return new WaveFileReader(fileName);
        else if (fileName.EndsWith(".mp3"))
            return new Mp3FileReader(fileName);
        else
            throw new InvalidOperationException("Unsupported extension");
    

    public void Play()
    
        _iWavePlayer.Play();
    

    public void Stop()
    
        if (_iWavePlayer != null 
                && _iWavePlayer.PlaybackState != PlaybackState.Stopped)  
            _iWavePlayer.Stop();
            _waveStream.Position = 0;
        
    

    public void Dispose()
    
        Stop();
        if (_iWavePlayer != null) 
            _iWavePlayer.Dispose();
            _iWavePlayer = null;
        
        if (_waveChannel32 != null) 
            _waveChannel32.Dispose();
            _waveChannel32 = null;
        
        if (_waveStream != null) 
            _waveStream.Dispose();
            _waveStream = null;
        
    

我正在使用相关代码播放 MP3 文件(不是 WAV)。

它在大多数情况下都可以正常工作,考虑到我将能够在我的项目中替换 MediaElements,这非常棒。我遇到的问题是 PlaybackState 停留在 Playing 而不是在 PlaybackStopped 触发后更改为 Stopped。为了解决这个问题,我订阅了PlaybackStopped 并从那里致电Stop()

我必须像这样打电话给Stop() 是否正常,还是我在这里遗漏了什么?

【问题讨论】:

不是我熟悉的类,但是许多对象在播放时会引发“Stopped”事件,如果您想取消,它会使状态更改更简单。活动可以取消吗? 【参考方案1】:

看起来像一个错误。如果您查看 NAudio 代码,WaveOut 不会更改 RaisePlaybackStoppedEvent 中的 PlaybackState。但是DirectSoundOut 会将其更改为停止。有点疯狂。

【讨论】:

DirectSoundOut 有什么缺点吗?您是否碰巧有一些可以播放 MP3 的代码可以分享:-)? 别管样本,我只是用 DirectSoundOut 替换 WaveOut,它确实在完成时将状态设置为停止。【参考方案2】:

试试这个:

在 Load 方法中更改这一行:

_iWavePlayer = new WaveOut(); 

通过这个:

_iWavePlayer = new WaveOut(WaveCallbackInfo.FunctionCallback());

【讨论】:

以上是关于为啥 PlaybackState 在 PlaybackStopped 触发后仍保持在 Playing 状态?的主要内容,如果未能解决你的问题,请参考以下文章

NAudio WaveOut.PlaybackState 属性未更新

Xcode 11 beta -playbackState 仅在 iOS 13.0 或更新版本中可用

使用逻辑 ||带有枚举值

ExoPlayer 监听播放器播放完成 播放孔娜

是否可以从应用程序控制 iTunes(使其播放暂停的歌曲)?

Android TV 播放器在 PlaybackTransportRowPresenter.createRowViewHolder 上充气错误