从 MemoryStream 打开音频 (wav) 文件以确定持续时间
有没有办法在框架内或通过使用 P/Invoke 来确定 MemoryStream 中保存的 wav 文件的持续时间?
我已经看过托管 DirectX 和另一个类似问题,但一切似乎都与路径一起工作,而不是提供任何传递流的方式。我引用的问题中的链接之一(A simple C# Wave editor< /a>....) 非常清楚地表明我可以解析 MemoryStream 来确定 wav 文件的持续时间。理想情况下,我不想重新发明轮子。
Is there a way, either within the Framework or by using P/Invoke to determine the duration of a wav file that's held in a MemoryStream?
I've already had a look at Managed DirectX and another similar question, but everything seems to work with paths, rather than providing any way to pass in a stream. One of the links in the question I've referenced (A simple C# Wave editor....) makes it fairly clear that I could parse the MemoryStream
to determine the duration of the wav file. Ideally I'd like to not re-invent the wheel.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我同意亚历克斯的观点。
我花时间编写了一个包含三行代码的小程序,用于打印 wav 文件的持续时间。
下载 NAudio 库:您将在包中找到 NAudio.dll。
只需在您的项目中引用 NAudio.dll 即可。
在撰写本文时,它的版本是 1.3。
正如作者在博客中所说,WaveFileReader 也接受 Stream ;不仅仅是文件路径。
请记住,1.3 版本是为 x86 构建的。如果您希望它在 x64 上运行,您需要强制您的项目使用 x86。
如果您想要 x64 的 NAudio.dll(像我一样),您需要使用“任何 cpu”重新编译。
对我来说,这两种解决方案都很有效。
I agree with Alex.
I took the time to put together a small program with three lines of code that prints the duration of a wav file.
Download NAudio library: you will find NAudio.dll in the package.
Just reference NAudio.dll in your project.
At time of writing it's release 1.3.
Like the author says on his blog, WaveFileReader accept a Stream too; not just a file path.
Remember that version 1.3 is built for x86. If you want it to work on x64 you need to force your project to x86.
If you want NAudio.dll for x64 (like me) you need to recompile with 'any cpu'.
For me both solutions worked like a charm.
尝试以下计算
streamSize == headerSizeIfAny + playTime *抽样*singleSampleSize - >
playTime = (streamSize[以字节为单位] - headerSizeIfAny) / (采样[每秒采样数] * singleSampleSize[字节])
Try following calculation
streamSize == headerSizeIfAny + playTime * sampling * singleSampleSize ->
playTime = ( streamSize[in bytes] - headerSizeIfAny ) / ( sampling [samples per second] * singleSampleSize[bytes])
看看这个:
http://www.sonicspot.com/guide/wavefiles.html
所以
你有你的内存流... 寻找 0x10 (跳过 Riff 头) + 0x08 (用于格式头) = 24
你就在上面的结构中。
使用
stream.ReadInt16()
和stream.ReadInt32()
读取想要的结构成员。然后,查找 54,读取一个
DWORD
,这些字节就是您的示例数据。然后根据这些变量计算出您的持续时间。
注意:这仅适用于存储在内存流中的最简单的 PCM 波形文件。对于其他人,您必须尊重标头并正确解析它们,找到数据块并根据其大小计算持续时间。
Check this out:
http://www.sonicspot.com/guide/wavefiles.html
and this
So you have your memorystream... Seek to 0x10 (to skip Riff header) + 0x08 (for format header) = 24
And you are in the structure above.
Use
stream.ReadInt16()
andstream.ReadInt32()
to read wanted structure members.Then, seek to 54, read one
DWORD
, and that many bytes is your sample data.Then figure out your duration from this variables.
NOTE: that will work for ONLY THE SIMPLEST PCM wave files stored in your memorystream. For others, you'll have to honor headers and properly parse them, finding the data chunk and calculating duration according to it's size.