有什么方法可以将内存中的 .mp4 格式音频转换为 .wav 格式?

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

我正在开发一个 WPF 应用程序,我必须在其中播放音频。我收到 .mp4 格式的音频数据(在字节数组中),唯一的限制是我不能把它写到硬盘上。

我找到了几个播放 .mp4 格式的解决方案,例如 WMPLib.WindowsMediaPlayer,但我无法提供字节数组或流式传输到此库来播放音频。它只接受文件路径。

然后我找到了 System.Media.SoundPlayer,它可以播放流中的音频,但只能是 .wav 格式。我开始寻找从 mp4 转换为 wav 的解决方案。我找到了 NAudio 库,我可以通过以下方式进行转换:

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

问题在于我可以仅使用文件路径参数实例化 MediaFoundationReader。我没有找到任何不使用文件来创建它的方法。我认为这也是一个死胡同。

因此,关于如何在内存中转换音频,或者如何直接从字节数组或流播放 .mp4 文件,任何建议都会有所帮助?

您可以使用 NAudio 转换任何音频格式

查看示例,例如:How to convert a MP3 file to WAV with NAudio in WinForms C# 使用多种方法,例如 MediaFoundationReader

最后我找到了一个解决方案,它可以转换为 .mp3 格式,但它也可以转换为 .wav。我可以通过以下方式使用 uwp 转码 API:

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);
    }
}

进口:

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

MemoryRandomAccessStream 只是 IRandomAccesStream 接口的一个实现,可以在 here.

中找到