0

I'm not quite sure where to start on this one so wanted to ask for some help.

In a Blazor web app, I am downloading an MP3 audio file from S3 without any problems. It's kept in memory only at the moment via a MemoryStream (for further processing).

I now need to figure out the duration of the audio eg. 90 seconds or whatever.

Is it possible to do this via the MemoryStream ? Or do I need to download and write the file to disk, then inspect it ? Also what library can I use to inspect the MP3 file so as to determine the duration of the audio ?

Here's the relevant piece of code which is downloading (from S3) the file:

MemoryStream ms = null;

GetObjectRequest getObjectRequest = new GetObjectRequest
{
    BucketName = bucketName,
    Key = fileName 
};

using (var response = await s3Client.GetObjectAsync(getObjectRequest))
{
   if (response.HttpStatusCode == HttpStatusCode.OK)
   {
      using (ms = new MemoryStream())
      {
          await response.ResponseStream.CopyToAsync(ms);
      }
   }
}
          
return ms;
ajonno
  • 2,140
  • 4
  • 20
  • 33
  • As far as I know you don't need to download the whole mp3 file to get duration. The duration info is stored into mp3 file header, and it is enough to just read mp3 header to determine its duration time. – Rafael May 23 '22 at 04:37
  • Check this link: https://stackoverflow.com/a/34518350/12576990 – Rafael May 23 '22 at 06:02

1 Answers1

0

Figured it out. With the help of this library (there are many but this worked well): https://github.com/Zeugma440/atldotnet

Once you've got the MemoryStream, you need to convert it to a FileStream. From there, the library will help to provide the Duration (which is the only thing I needed in this case).

Here's the method I'm using.

private static double GetMediaDuration(MemoryStream ms)
{
    using FileStream stream = File.Create("<any-file-name-u-like-here>.mp3");
    stream.Write(ms.ToArray(), 0, ms.ToArray().Length);
        
    Track theTrack = new Track(stream, mimeType: "audio/mp3", null);

    return theTrack.Duration;
}
ajonno
  • 2,140
  • 4
  • 20
  • 33
  • FYI, `ATL.Track` has an alternate constructor that takes a generic `Stream` and a mime-type as input. You don't need to create an artificial `FileStream`. – Paul W Sep 02 '22 at 11:59