NAudio:当使用AudioFileReader和WaveOutEvent更改播放位置时,如何准确获取当前播放位置

时间:2019-03-05 11:22:25

标签: naudio

我正在创建一个应用程序,该应用程序需要允许用户在播放音频文件时选择音频文件的播放位置。但是,一旦位置更改,我就无法确定当前位置。

这是一个示例程序,显示了我的工作方式。

using NAudio.Utils;
using NAudio.Wave;
using System;

namespace NAudioTest
{
    class Program
    {
        static void Main()
        {
            var audioFileReader = new AudioFileReader("test.mp3");
            var waveOutEvent = new WaveOutEvent();
            waveOutEvent.Init(audioFileReader);
            waveOutEvent.Play();

            while (true)
            {
                var key = Console.ReadKey(true);

                if (key.Key == ConsoleKey.Enter)
                {
                    var playLocationSeconds = 
                        waveOutEvent.GetPositionTimeSpan().TotalSeconds;
                    Console.WriteLine(
                        "Play location is " + playLocationSeconds + "seconds");
                }
                else if (key.Key == ConsoleKey.RightArrow)
                {
                    audioFileReader.CurrentTime = 
                        audioFileReader.CurrentTime.Add(TimeSpan.FromSeconds(30));
                }
                else
                {
                    break;
                }
            }
        }
    }
}

重现问题的步骤

  1. 启动程序:音频文件开始播放
  2. 按Enter键:当前播放时间已写入控制台
  3. 按向右箭头键:播放的音频(大概)会跳到预期的位置
  4. 再次按Enter键:将播放时间写入到 控制台,但它看起来是从音频开始到现在的时间 开始播放,而不是当前播放位置的时间。

我尝试获取AudioFileReader.CurrentTime的值,而不是在WaveOutEvent上调用GetPositionTimeSpan。这种方法的问题在于AudioFileReader.CurrentTime值会跳转,这可能是因为此基础流与WaveOutEvent一起使用时会被缓冲,因此CurrentTime不能准确地反映播放位置,只反映基础流中的位置。

我如何支持任意比赛位置,但仍能在当前时间继续获得准确的比赛位置?

1 个答案:

答案 0 :(得分:1)

音频文件阅读器的“ CurrentTime”属性足以判断当前的播放位置,特别是在延迟不是很高的情况下。我发现它与waveOutEvent.GetPositionTimeSpan()之间的差异为100-200毫秒。最多。

您确实在使用CurrentTime属性的setter在流中重新定位。使用吸气剂然后查询当前位置也是一致的。如果您担心精度,则可以使用较低的延迟。

扩展方法“ GetPositionTimeSpan()”似乎返回到目前为止的总播放长度,而不是流中的位置。诚然,我不知道为什么会这样。