Is there any way to convert .mp4 format audio to .wav format just in memory?

2.3k Views Asked by At

I'm developing a WPF application, where I have to play audio. I receive the audio data in .mp4 format (in a byte array) and the only restriction is that I can't write it out to the hard disk.

I found couple of solutions for playing the .mp4 format, for example with WMPLib.WindowsMediaPlayer, but I can't give a byte array, or stream to this library, to play the audio. It just accepts the file path.

Then I found the System.Media.SoundPlayer, which can play audio from a stream, but just in .wav format. I started to search for solutions to convert from mp4 to wav. I found the NAudio library and I could make the conversion the following way:

using (var data = new MediaFoundationReader(filePath)) {
  var stream = new MemoryStream();
  WaveFileWriter.WriteWavFileToStream(stream, data);
}

The problem with this is that I can instantiate the MediaFoundationReader just with a file path parameter. I didn't find any way to create it without using files. I think this was also a dead end.

So, any suggestion would be helpful about how can I convert audio in memory, or maybe how can I play directly the .mp4 file from a byte array or stream?

2

There are 2 best solutions below

0
Attila Szász On BEST ANSWER

Finally I found a solution which converts to an .mp3 format, but it can also convert to .wav. I could use the uwp transcode API the following way:

public static async void ConvertMp4ToMp3(byte[] mp4Data, Action<Stream> doneCallback) {
    MediaEncodingProfile profile = MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High);
    var inputStream = new MemoryRandomAccessStream(mp4Data);
    var outputStream = new InMemoryRandomAccessStream();
    MediaTranscoder transcoder = new MediaTranscoder();

    PrepareTranscodeResult prepareOperation = await transcoder.PrepareStreamTranscodeAsync(inputStream, outputStream, profile);
    if (prepareOperation.CanTranscode) {
        //start to convert
        var transcodeOperation = prepareOperation.TranscodeAsync();

        //registers completed event handler 
        transcodeOperation.Completed += (IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status) => {
            asyncInfo.GetResults();
            var stream = outputStream.AsStream();
            stream.Position = 0;
            doneCallback(stream);
        };
    } else {
        doneCallback(null);
    }
}

The imports:

using System;
using System.IO;
using Windows.Foundation;
using Windows.Media.MediaProperties;
using Windows.Media.Transcoding;
using Windows.Storage.Streams;

And the MemoryRandomAccessStream is just an implementation of the IRandomAccesStream interface and can be found here.

1
aureval On

You can convert any audio formats witn NAudio

See samples like :How to convert a MP3 file to WAV with NAudio in WinForms C# with several methods like MediaFoundationReader