如何在使用 NAudio 流式传输 mp3 时获取当前时间?

Posted

技术标签:

【中文标题】如何在使用 NAudio 流式传输 mp3 时获取当前时间?【英文标题】:How to get current time while streaming mp3 using NAudio? 【发布时间】:2016-09-17 15:21:56 【问题描述】:

我有一个从 url 流式传输 mp3 的代码。我想在 UI 中显示 mp3 播放器的当前时间。我尝试使用WaveOut.GetPosition,但它对我不起作用。 我该怎么做?

我的代码:

do
 
    //..codes to get url stream,to create BufferedWaveProvider

    int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
    provider.AddSamples(buffer, 0, decompressed);
    if (provider.BufferedDuration.Seconds > 2 && waveOut == null)
    
       waveOut = new WaveOut();
       waveOut.Init(provider);
       waveOut.Play();
    
    if (waveOut != null)
    
       currentTime = (int)(waveOut.GetPosition() * 1d / AvgBytesPerSec);
    
 
 while (bytesRead > 0 || waveOut.PlaybackState == PlaybackState.Playing);

【问题讨论】:

provider是什么类型? provider 是 BufferedWaveProvider,waveOut 是 WaveOut。如果你需要,我可以放整个代码。 怎么不工作了?它是否在播放音频? 它返回的数字太大。我在想它显示了提供者的读取位置,但事实并非如此。另外BufferedWaveProvider 是从CircularBuffer 派生的,因此它本身会循环,并且不能包含像普通流或缓冲区这样的位置。我找不到正确的公式来使用GetPosition 计算当前时间。所以我目前正在使用仅在WaveOut.PlaybackState == PlaybackState.Playing 的情况下运行的 Timer.Tick 来计算时间位置。 【参考方案1】:

我认为您需要对代码进行的唯一更改是使用waveOut.OutputWaveFormat.AverageBytesPerSecond 而不是您当前使用的AvgBytesPerSec 属性。 IWavePosition 接口(这是您在此处实际使用的)以硬件术语“思考”,因此如果您使用的格式必须在硬件可以使用之前进行转换,则硬件字节速率将不同于您的源字节率。

请注意,GetPosition() 返回的位置仅是自上次开始播放以来。如果调用waveOut.Stop(),则在重新开始播放时位置重置为0。将位置映射到源由调用者决定(这非常简单;只需跟踪您上次在源上开始播放的位置并将其添加到返回的位置。缓冲使其更复杂,但仍然完全可行)。

我为 NAudio 编写了原始的 IWavePosition 接口和实现。它在我为其构建的项目中效果很好。 :)

【讨论】:

效果很好。我的值 AvgBytesPerSecMp3WaveFormat.AverageBytesPerSecond 使用 Mp3Frame 属性构造的。我认为不同之处在于解压缩帧。因为在解压一帧时会增加字节长度。感谢@ioctILR 的帮助。【参考方案2】:

你试过房产当前时间和房产位置了吗?

mp3Reader = new Mp3FileReader("example.mp3");

waveOut.Init(mp3Reader);

waveOut.Play();

// reposition to five seconds in
mp3Reader.CurrentTime = TimeSpan.FromSeconds(5.0);

所以mp3Reader.CurrentTime应该给你我认为你需要的东西

希望对你有帮助

【讨论】:

但我需要从 url 源流式传输它。我知道 Mp3FileReader 仅适用于保存的文件。有流媒体解决方案吗? 来自codeplex BufferedWaveProvider.BufferedDuration,github.com/naudio/NAudio/blob/master/NAudio/Wave/WaveProviders/…,通过浏览代码,你可能会找到方法,也可以编辑源代码 源码里面依赖的类太多了,我试试看。感谢您的建议。

以上是关于如何在使用 NAudio 流式传输 mp3 时获取当前时间?的主要内容,如果未能解决你的问题,请参考以下文章

Unity中使用NAudio创建AudioClip,读取数据时卡顿1-2秒

如何使用 NAudio 从 mp3 中获取音频样本数据

如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?

使用 NAudio,如何获取 MP3 文件的幅度和节奏?

如何以 mp3 格式从麦克风流式传输声音?

如何使用 Naudio 和 c# 修剪 mp3 帧的标题和边信息