9

I'm currently looking for the solution of my problem since my audio file (.wav) is in the resources of my solution. I need to detect how long it would play.

How can I calculate the duration of the audio in my resources?
Is there a way to detect how long will it take to play a certain audio file in my resource?

Vogel612
  • 5,620
  • 5
  • 48
  • 73
bRaNdOn
  • 1,060
  • 4
  • 17
  • 37
  • You will either have to pre-store that information along with the WAV in the resource, or extract the WAV at runtime and determine the audio length using the Windows API. Do you need to know how to use the Windows API to find the audio length of a WAV file? I can post it as an answer if so. – Matthew Watson Aug 15 '14 at 10:57
  • who would i pre-store that information along with the wav file? and get it in run time? – bRaNdOn Aug 15 '14 at 11:00
  • For example you could add a string resource which just had the length. You would get at the string the normal way (via auto-generated code in Resources.Designer.cs) and int.Parse() it to get the length. – Matthew Watson Aug 15 '14 at 11:05

2 Answers2

6

You can use NAudio to read the resource stream and get the duration

using NAudio.Wave;
...
WaveFileReader reader = new WaveFileReader(MyProject.Resource.AudioResource);
TimeSpan span = reader.TotalTime;

You can also do what Matthew Watson suggested and simply keep the length as an additional string resource.

Also, this SO question has tons of different ways to determine duration but most of them are for files, not for streams grabbed from resources.

Soleil
  • 6,404
  • 5
  • 41
  • 61
Benjamin Trent
  • 7,378
  • 3
  • 31
  • 41
6

Ive got a way better solution for your problem, without any library. First read all bytes from the file. (optionally you can also use a FileSteam to only read the necessary bytes)

byte[] allBytes = File.ReadAllBytes(filePath);

After you got all bytes from your file, you need to get the bits per second. This value is usually stored in the bytes at indices 28-31.

int byterate = BitConverter.ToInt32(new[] { allBytes[28], allBytes[29], allBytes[30], allBytes[31] }, 0);

Now you can already get the duration in seconds.

int duration = (allBytes.Length - 8) / byterate;
Leonhard P.
  • 119
  • 2
  • 3