问题
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.
回答1:
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.
var stream=new MemoryStream(File.ReadAllBytes("test.wav"));
var wave = new WaveFileReader(stream);
Console.WriteLine(wave.TotalTime); // wave.TotalTime -> TimeSpan
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.
回答2:
Try following calculation
streamSize == headerSizeIfAny + playTime * sampling * singleSampleSize ->
playTime = ( streamSize[in bytes] - headerSizeIfAny ) / ( sampling [samples per second] * singleSampleSize[bytes])
回答3:
Check this out:
http://www.sonicspot.com/guide/wavefiles.html
and this
typedef struct {
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
WORD cbSize;} WAVEFORMATEX;
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()
and stream.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.
来源:https://stackoverflow.com/questions/3502408/opening-an-audio-wav-file-from-a-memorystream-to-determine-the-duration