流媒体播放音乐时CPU贪婪循环

本文关键字:贪婪 循环 CPU 媒体播放 音乐 | 更新日期: 2023-09-27 18:27:21

为了提供一些上下文,我正在开发一个开源的替代桌面Spotify客户端,其核心是可访问性。你还会在这里看到一些NAudio。

播放一开始,我就注意到CPU使用非常频繁。即使在暂停时,CPU也很高。

我运行了Visual Studio的内置探查器,试图了解可能发生的任何资源占用。正如我所怀疑的,问题出在我的播放管理器的流媒体循环中。

探查器标记为最丰富样本之一的代码如下:

const int secondsToBuffer = 3;
    private void GetStreaming(object state)
    {
        this.fullyDownloaded = false;
        // secondsToBuffer is an integer to represent how many seconds we should buffer up at once to prevent choppy playback on slow connections
        try
        {
            do
            {
                if (bufferedWaveProvider == null)
                {
                    this.bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(44100, 2));
                    this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
                    Logger.WriteDebug("Creating buffered wave provider");
                    this.gatekeeper.MinimumSampleSize = bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * secondsToBuffer;
                }
                // this bit in particular seems to be the hot point
                if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
                {
                    Logger.WriteDebug("Buffer getting full, taking a break");
                    Thread.Sleep(500);
                }
                // do we have at least double the buffered sample's size in free space, just in case
                else if (bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes > bufferedWaveProvider.WaveFormat.AverageBytesPerSecond * (secondsToBuffer * 2))
                {
                    var sample = gatekeeper.Read();
                    if (sample != null)
                    {
                        bufferedWaveProvider.AddSamples(sample, 0, sample.Length);
                    }
                }
            } while (playbackState != StreamingPlaybackState.Stopped);
            Logger.WriteDebug("Playback stopped");
        }
        finally
        {
            // no post-processing work here, right?
        }
    }

NAudio样本是我用这种方法处理流媒体的灵感来源。要查找完整文件的源代码,您可以在此处查看:http://blindspot.codeplex.com/SourceControl/latest#Blindspot.Playback/PlaybackManager.cs

我是一个分析的新手,也不是流媒体的年度专家(两者可能都很明显)。

有什么办法可以减少这个循环的资源密集度吗。在缓冲区已满的if块中增加睡眠量会有帮助吗?还是我找错树了。看起来会的,但我本以为半秒钟就足够了。

感谢您的帮助。

流媒体播放音乐时CPU贪婪循环

基本上,您已经创建了一个无限循环,直到缓冲区满为止。你用标记的部分

// this bit in particular seems to be the hot point

可能是因为if语句中的计算只是一次又一次地重复;它们中的任何一个能移出循环吗?

我会在while语句之前加一个Thread.Sleep(50)来防止颠簸,看看这是否有什么不同(我怀疑会的)。