【问题标题】:Is there any way to convert .mp4 format audio to .wav format just in memory?有什么方法可以将 .mp4 格式的音频转换为 .wav 格式,只是在内存中?
【发布时间】:2019-07-16 11:22:07
【问题描述】:

我正在开发一个 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 文件,任何建议都会有所帮助?

【问题讨论】:

  • 也许你可以从 github 获取代码并尝试将构造函数添加到 MediaFoundationReader 类以获取流。我想,一旦它获取文件,它无论如何都会打开流,所以你可以传递一个流并从那里继续。
  • 是的,我已经检查过那个库的代码,修改代码不会那么容易,也许我会试试,谢谢

标签: c# wpf audio audio-converter


【解决方案1】:

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

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

【讨论】:

  • 是的,我在问题中发布的示例代码正在执行此转换。也许我不是很清楚,我不想将音频数据写入硬盘中的文件。甚至几毫秒! MediaFoundationReader 的问题是我可以仅使用文件路径参数进行实例化。在您提供的示例中,每个示例都在从文件进行转换。那么你知道如何不使用文件直接从内存中进行操作吗?
【解决方案2】:

最后我找到了一个转换为.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 中找到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2013-02-06
    • 1970-01-01
    • 2022-07-11
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多