C# 在 NAudio 的内存流中将格式从 wav 更改为 mp3

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19058530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:59:59  来源:igfitidea点击:

change format from wav to mp3 in memory stream in NAudio

c#asp.netaudionaudio

提问by user2431114

Hi there iam trying to convert text to speech (wav) in the memorystream convert it to mp3 and then play it on the users page.so need i help what to do next?

嗨,我正在尝试将内存流中的文本转换为语音 (wav) 将其转换为 mp3,然后在用户页面上播放。所以需要我帮助下一步做什么?

here is my asmx code :

这是我的 asmx 代码:

[WebMethod]
public byte[] StartSpeak(string Word)
{
    MemoryStream ms = new MemoryStream();
    using (System.Speech.Synthesis.SpeechSynthesizer synhesizer = new System.Speech.Synthesis.SpeechSynthesizer())
    {
        synhesizer.SelectVoiceByHints(System.Speech.Synthesis.VoiceGender.NotSet, System.Speech.Synthesis.VoiceAge.NotSet, 0, new System.Globalization.CultureInfo("en-US"));
        synhesizer.SetOutputToWaveStream(ms);
        synhesizer.Speak(Word);
    }
    return ms.ToArray();

    }

Thanks.

谢谢。

采纳答案by Corey

You need an MP3 compressor library. I use Lame via the Yeti Lame wrapper. You can find code and a sample project here.

您需要一个 MP3 压缩器库。我通过 Yeti Lame 包装器使用 Lame。您可以在此处找到代码和示例项目。

Steps to get this working:

使这个工作的步骤:

  1. Copy the following files from MP3Compressorto your project:

    • AudioWriters.cs
    • Lame.cs
    • Lame_enc.dll
    • Mp3Writer.cs
    • Mp3WriterConfig.cs
    • WaveNative.cs
    • WriterConfig.cs


  2. In the project properties for Lame_enc.dllset the Copy to Outputproperty to Copy if neweror Copy always.

  3. Edit Lame.csand replace all instances of:

    [DllImport("Lame_enc.dll")]
    

    with:

    [DllImport("Lame_enc.dll", CallingConvention = CallingConvention.Cdecl)]`
    
  4. Add the following code to your project:

    public static Byte[] WavToMP3(byte[] wavFile)
    {
        using (MemoryStream source = new MemoryStream(wavFile))
        using (NAudio.Wave.WaveFileReader rdr = new NAudio.Wave.WaveFileReader(source))
        {
            WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(rdr.WaveFormat.SampleRate, rdr.WaveFormat.BitsPerSample, rdr.WaveFormat.Channels);
    
            // convert to MP3 at 96kbit/sec...
            Yeti.Lame.BE_CONFIG conf = new Yeti.Lame.BE_CONFIG(fmt, 96);
    
            // Allocate a 1-second buffer
            int blen = rdr.WaveFormat.AverageBytesPerSecond;
            byte[] buffer = new byte[blen];
    
            // Do conversion
            using (MemoryStream output = new MemoryStream())
            { 
                Yeti.MMedia.Mp3.Mp3Writer mp3 = new Yeti.MMedia.Mp3.Mp3Writer(output, fmt, conf);
    
                int readCount;
                while ((readCount = rdr.Read(buffer, 0, blen)) > 0)
                    mp3.Write(buffer, 0, readCount);
    
                mp3.Close();
                return output.ToArray();
            }
        }
    }
    
  5. Either add a reference to System.Windows.Formsto your project (if it's not there already), or edit AudioWriter.csand WriterConfig.csto remove the references. Both of these have a using System.Windows.Forms;that you can remove, and WriterConfig.cshas a ConfigControldeclaration that needs to be removed/commented out.

  1. 将以下文件复制MP3Compressor到您的项目中:

    • AudioWriters.cs
    • 跛脚
    • 跛脚_enc.dll
    • Mp3Writer.cs
    • Mp3WriterConfig.cs
    • WaveNative.cs
    • WriterConfig.cs


  2. 在项目属性Lame_enc.dll中将Copy to Output属性设置为Copy if newerCopy always

  3. 编辑Lame.cs并替换以下所有实例:

    [DllImport("Lame_enc.dll")]
    

    和:

    [DllImport("Lame_enc.dll", CallingConvention = CallingConvention.Cdecl)]`
    
  4. 将以下代码添加到您的项目中:

    public static Byte[] WavToMP3(byte[] wavFile)
    {
        using (MemoryStream source = new MemoryStream(wavFile))
        using (NAudio.Wave.WaveFileReader rdr = new NAudio.Wave.WaveFileReader(source))
        {
            WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(rdr.WaveFormat.SampleRate, rdr.WaveFormat.BitsPerSample, rdr.WaveFormat.Channels);
    
            // convert to MP3 at 96kbit/sec...
            Yeti.Lame.BE_CONFIG conf = new Yeti.Lame.BE_CONFIG(fmt, 96);
    
            // Allocate a 1-second buffer
            int blen = rdr.WaveFormat.AverageBytesPerSecond;
            byte[] buffer = new byte[blen];
    
            // Do conversion
            using (MemoryStream output = new MemoryStream())
            { 
                Yeti.MMedia.Mp3.Mp3Writer mp3 = new Yeti.MMedia.Mp3.Mp3Writer(output, fmt, conf);
    
                int readCount;
                while ((readCount = rdr.Read(buffer, 0, blen)) > 0)
                    mp3.Write(buffer, 0, readCount);
    
                mp3.Close();
                return output.ToArray();
            }
        }
    }
    
  5. 添加System.Windows.Forms对您的项目的引用(如果它还没有),或者编辑AudioWriter.csWriterConfig.cs删除引用。这两个都有一个using System.Windows.Forms;可以删除的,并且WriterConfig.cs有一个ConfigControl需要删除/注释掉的声明。

Once all of that is done you should have a functional in-memory wave-file to MP3 converter that you can use to convert the WAV file that you are getting from the SpeechSynthesizerinto an MP3.

完成所有这些后,您应该有一个功能强大的内存波形文件到 MP3 转换器,您可以使用它来将您从SpeechSynthesizer.

回答by James Johnson

Assuming you're trying to convert the output into MP3, you need something that can handle transcoding the audio. There are a number of tools available, but my personal preference is FFmpeg. It's a command line tool so you will need to take that into account, but otherwise it's very easy to use.

假设您正在尝试将输出转换为 MP3,您需要一些可以处理音频转码的东西。有许多可用的工具,但我个人更喜欢FFmpeg。它是一个命令行工具,因此您需要考虑到这一点,但除此之外它非常易于使用。

There's lots of information online, but you can start by checking out their documentation here.

网上有很多信息,但您可以先在这里查看他们的文档。

回答by Corey

This is a bit old now, but since you haven't accepted the answer I previously provided...

这现在有点旧了,但是由于您还没有接受我之前提供的答案...

I have recently built an extension for NAudio that encapsulates the LAME library to provide simplified MP3 encoding.

我最近为 NAudio 构建了一个扩展,它封装了 LAME 库以提供简化的 MP3 编码。

Use the NuGet package manager to find NAudio.Lame. Basic example for using it available here.

使用 NuGet 包管理器查找NAudio.Lame. 使用它的基本示例可用here

回答by geekbytes0xff

I had a similar requirement in .net4.0 to convert 8bit 8Khz mono wav and used the following code

我在 .net4.0 中有类似的要求来转换 8bit 8Khz mono wav 并使用以下代码

public void WavToMp3(string wavPath, string fileId)
    {
        var tempMp3Path = TempPath + "tempFiles\" + fileId + ".mp3";
        var mp3strm = new FileStream(tempMp3Path, FileMode.Create);
        try
        {
            using (var reader = new WaveFileReader(wavPath))
            {
                var blen = 65536;
                var buffer = new byte[blen];
                int rc;
                var bit16WaveFormat = new WaveFormat(16000, 16, 1);
                using (var conversionStream = new WaveFormatConversionStream(bit16WaveFormat, reader))
                {
                    var targetMp3Format = new WaveLib.WaveFormat(16000, 16, 1);
                    using (var mp3Wri = new Mp3Writer(mp3strm, new Mp3WriterConfig(targetMp3Format, new BE_CONFIG(targetMp3Format,64))))
                    {
                        while ((rc = conversionStream.Read(buffer, 0, blen)) > 0) mp3Wri.Write(buffer, 0, rc);
                        mp3strm.Flush();
                        conversionStream.Close();
                    }
                }
                reader.Close();
            }
            File.Move(tempMp3Path, TempPath + fileId + ".mp3");
        }
        finally
        {
            mp3strm.Close();
        }
    }

Prerequists:

先决条件:

  1. .net 4 compiled yeti library (to obtain it download this older one (http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip) and convert it to .net4.0 then build the solution to obtain the new version dlls)
  2. download the NAudio libraries (as Lame support 16bit wav sample only i had to first convert it from 8bit to 16bit wav)
  1. .net 4 编译的 Yeti 库(要获得它,请下载这个较旧的库(http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip)并将其转换为 .net4.0 然后构建解决方案获取新版本的dll)
  2. 下载 NAudio 库(因为 Lame 仅支持 16 位 wav 样本,所以我必须先将其从 8 位转换为 16 位 wav)

I have used a buffer size of 64kpbs (my custom requirement)

我使用了 64kpbs 的缓冲区大小(我的自定义要求)

回答by Wjdavis5

Just wanted to post my example too using NAudio.Lame:

只是想使用 NAudio.Lame 发布我的示例:

NuGet:

纽格:

Install-Package NAudio.Lame

Code Snip: Mine obviously returns a byte[] - I have a separate save to disk method b/c I think it makes unit testing easier.

代码片段:我的显然返回一个字节 [] - 我有一个单独的保存到磁盘方法 b/c 我认为它使单元测试更容易。

public static byte[] ConvertWavToMp3(byte[] wavFile)
        {

            using(var retMs = new MemoryStream())
            using (var ms = new MemoryStream(wavFile))
            using(var rdr = new WaveFileReader(ms))
            using (var wtr = new LameMP3FileWriter(retMs, rdr.WaveFormat, 128))
            {
                rdr.CopyTo(wtr);
                return retMs.ToArray();
            }


        }