从 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 音频的正确方法是啥?