首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NAudio WaveOut.PlaybackState属性未更新

NAudio WaveOut.PlaybackState属性未更新
EN

Stack Overflow用户
提问于 2018-01-02 14:28:48
回答 2查看 1.1K关注 0票数 1

在C#中使用WPF框架编写应用程序(我对它真的很陌生,不要对我的编码风格太苛刻)。我希望在退出时播放一些“再见”音频(使用NAudio 1.8.4读取MPQ文件中的流),即使主窗口消失也不被中断;为此,我在一个名为PlayerThread的类中使用了前台线程。

我使用PlayerThread构造函数播放声音

代码语言:javascript
复制
 foregroundChannel = new PlayerThread(soundStream, null, null);

但是我以后不会跟踪它,我只是依靠PlayerThread来结束比赛后的“自然”。

下面是PlayerThread构造函数:

代码语言:javascript
复制
public PlayerThread(MpqFileStream stream, Action<PlayerThread> over, Dispatcher callerDispatcher)
    {
        noCallback = false;
        dispatcher = callerDispatcher;
        fadeOut = false;
        soundStream = stream;
        ThreadStart threadStart = RunThread;
        if (callerDispatcher != null)
        {
            callback = over;
            threadStart += () =>
            {
                dispatcher.Invoke(() =>
                {
                    Cleanup();
                });
            };
        }
        this.m_playerThread = new Thread(RunThread)
        {
            Name = "Audio Player Thread",
            IsBackground = false
        };
        this.m_playerThread.SetApartmentState(ApartmentState.STA);
        this.m_playerThread.Start();
    }

下面是它所做的工作:

代码语言:javascript
复制
private void RunThread()
    {
        internalPlayer = new WaveOut();
        Mp3FileReader mp3FileReader = new Mp3FileReader(soundStream);
        inputStream = new WaveChannel32(mp3FileReader);
        internalPlayer.Init(inputStream);
        internalPlayer.Play();
        while (internalPlayer.PlaybackState == PlaybackState.Playing && !fadeOut)
        {
            System.Threading.Thread.Sleep(100);
        }
        if (fadeOut)
        {
            while (((float)0F).CompareTo(inputStream.Volume) < 0)
            {
                System.Threading.Thread.Sleep(150);
                inputStream.Volume -= 0.1F;
            }
        }
        internalPlayer.Dispose();
        inputStream.Dispose();
        mp3FileReader.Dispose();
        soundStream.Dispose(); // Yeah I'm so desperate for a solution I'm just Disposing everything even though I don't think it helps
    }

单击“退出”时,将执行以下行:

代码语言:javascript
复制
soundEngine.FadeOutBackground();
soundEngine.PlayVoice(SoundNamesConstants.BYE);
soundEngine.WaveGoodbye();
Close();
soundEngine.WaitForTheCrewBeforeWeighingAnchor();

最后,这里是清除()内部的代码:

代码语言:javascript
复制
if (!noCallback)
            callback.Invoke(this);

回调在这里是非常不相关的,它是我用来在有淡出效果的音乐之间切换的东西。此外,由于我刚刚将noCallback设置为false,所以在这个实例中不会发生这种情况。

如果有任何用途,这是资源使用图表。红线是我按出口的时候。

UPDATE按照@sacha的建议添加了Thread.Join()同步:

代码语言:javascript
复制
public void WaitForTheCrewBeforeWeighingAnchor() // yes, every word matters
    {
        backgroundChannel.Join();

        foreach (PlayerThread pt in foregroundChannels)
            pt.Join();
    }

它与backgroundChannel线程连接没有问题,但从未与foregroundChannels中的唯一线程连接。将第3行与第5-6行倒置具有相同的结果,系统地失败了pt.Join();。这个PlayerThread是在单击exit时创建的。

更新2 --这不是线程问题。之所以会发生这种情况,只是因为条件internalPlayer.PlaybackState == PlaybackState.Playing并不总是满足(使用断点检查),所以我们只是停留在while循环中。目前,寻找一个更好的方式来检查播放已经结束。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-03 08:49:19

WaveChannel32构造函数创建了一个零填充缓冲区,这对于您要输入混频器的场景非常有用。在这种情况下,它只是使我的流“永不”结束。

增加:

代码语言:javascript
复制
inputStream.PadWithZeroes = false;

完全解决了我的问题。在这种情况下不需要加入。

欲了解更多信息:

永无休止的流问题 IWavePlayer的每个实现者决定是否应该自动停止回放的方式是,源IWaveProvider上的Read方法返回0(实际上,Read应该始终返回计数参数,除非流的末尾已经到达)。 然而,有一些WaveStreams / IWaveProviders在NAudio中永远不会停止返回音频。这不是一个bug --对于某些场景来说,这是相当正常的行为。也许BufferedWaveProvider是最好的例子--如果没有足够的排队数据来播放,它将返回一个零填充缓冲区。这对于来自网络的流非常有用,因为在网络中,数据到达的速度可能不够快,但是您不希望播放停止。类似地,WaveChannel32有一个名为PadWithZeroes的属性,允许您打开或关闭此行为,这对于您要输入混合器的场景非常有用。 来自:http://mark-dot-net.blogspot.be/2011/05/naudio-and-playbackstopped-problem.html

票数 1
EN

Stack Overflow用户

发布于 2018-01-02 15:06:23

听起来您需要同步您的线程,主线程应该在退出之前等待其他线程完成。看看Thread.Joinhttps://msdn.microsoft.com/en-us/library/95hbf2ta(v=vs.110).aspx

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48062741

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档