从 MemoryStream 打开音频 (wav) 文件以确定持续时间

Posted

技术标签:

【中文标题】从 MemoryStream 打开音频 (wav) 文件以确定持续时间【英文标题】:Opening an audio (wav) file from a MemoryStream to determine the duration 【发布时间】:2011-03-30 23:11:29 【问题描述】:

有没有办法在框架内或使用 P/Invoke 来确定 MemoryStream 中保存的 wav 文件的持续时间?

我已经看过Managed DirectX 和另一个similar question,但一切似乎都适用于路径,而不是提供任何方式来传递流。我引用的问题中的一个链接 (A simple C# Wave editor....) 清楚地表明我可以解析 MemoryStream 来确定 wav 文件的持续时间。理想情况下,我不想重新发明***。

【问题讨论】:

【参考方案1】:

试试下面的计算

streamSize == headerSizeIfAny + playTime * 采样 * singleSampleSize ->

playTime = (streamSize[in bytes] - headerSizeIfAny) / (samples [samples per second] * singleSampleSize[bytes])

【讨论】:

除非我解析了文件,否则计算对我来说完全没用。正如我已经说得很清楚的那样,我宁愿not re-invent the wheel.。事实上,就我的目的而言,编写代码来解析 wav 文件是行不通的。 @Rob:这个计算应该在没有任何解析的情况下工作,文件的比特率必须可以在不读取 wav 本身的情况下访问我很确定 Windows 资源管理器可以告诉我比特率。我想你也许可以 p/invoke 文件属性来挖掘它,甚至可能没有 p/invoke... 500k 文件,没有标题,有 100k 比特率,这是每秒的速率 = 5 秒。 @Jimmy,对不起,真的不是我想要的。无论多么简单,我都不想进行 any 计算。我正在寻找可以提供内存流的东西,它会告诉我里面的 wav 的持续时间。计算音频文件的持续时间不是我的代码的内容,所以我不打算开始 =) 就目前而言,资源管理器(无论如何是 Win7)告诉我持续时间以及比特率,使比特率对我来说更加无用;-)【参考方案2】:

看看这个:

http://www.sonicspot.com/guide/wavefiles.html

还有这个

typedef struct 
  WORD wFormatTag; 
  WORD nChannels; 
  DWORD nSamplesPerSec; 
  DWORD nAvgBytesPerSec; 
  WORD nBlockAlign; 
  WORD wBitsPerSample; 
  WORD cbSize; WAVEFORMATEX; 

所以你有你的内存流...寻找 0x10(跳过 Riff 标头)+ 0x08(用于格式标头)= 24

你在上面的结构中。

使用stream.ReadInt16()stream.ReadInt32() 读取想要的结构成员。

然后,寻找到 54,读取一个DWORD,那么多字节就是你的样本数据。

然后从这些变量中计算出你的持续时间。

注意:这仅适用于存储在内存流中的最简单的 PCM 波形文件。对于其他人,您必须尊重标头并正确解析它们,找到数据块并根据其大小计算持续时间。

【讨论】:

【参考方案3】:

我同意亚历克斯的观点。 我花时间编写了一个包含三行代码的小程序,用于打印 wav 文件的持续时间。

        var stream=new MemoryStream(File.ReadAllBytes("test.wav"));
        var wave = new WaveFileReader(stream);
        Console.WriteLine(wave.TotalTime); // wave.TotalTime -> TimeSpan

下载NAudio库:你会在包中找到NAudio.dll。

只需在您的项目中引用 NAudio.dll。

在撰写本文时,它是 1.3 版。

正如作者在他的博客中所说,WaveFileReader 也接受 Stream;不仅仅是文件路径。

请记住,1.3 版是为 x86 构建的。如果您希望它在 x64 上工作,您需要强制您的项目使用 x86。 如果您想要 x64 的 NAudio.dll(像我一样),您需要使用“任何 cpu”重新编译。 对我来说,这两种解决方案都很有魅力。

【讨论】:

以上是关于从 MemoryStream 打开音频 (wav) 文件以确定持续时间的主要内容,如果未能解决你的问题,请参考以下文章

在 MemoryStream 中拆分 mp3 音频的正确方法是啥?

即时将原始音频字节从 NAudio 转换为 wav 字节

使用 NAudio 读取包含作品音频的 MemoryStream

wav文件中奇怪的滴答声

使用 MediaPlayer 类从内存播放 WAV 文件

求ffmpeg音频压缩代码(wav压缩成wma)