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

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

这是我的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(); } 

谢谢。

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

让这个工作的步骤:

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

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

  2. Lame_enc.dll的项目属性中,将“ Copy to Output属性设置为Copy if newer Copy alwaysCopy 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声明。

完成所有这些后,你应该有一个function内存波形文件到MP3转换器,你可以用来将你从SpeechSynthesizer获得的WAV文件转换为MP3。

我想用NAudio.Lame发布我的例子:

的NuGet:

 Install-Package NAudio.Lame 

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

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

现在这有点旧了,但是因为你还没有接受我之前提供的答案……

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

使用NuGet包管理器查找NAudio.Lamehere使用它的基本示例。

假设您正在尝试将输出转换为MP3,则需要能够处理音频转码的内容。 有许多工具可供选择,但我个人的偏好是FFmpeg 。 它是一个命令行工具,因此您需要考虑到这一点,但否则它非常容易使用。

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

我在.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编译的yeti库(获取它下载这个旧的( http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip )并将其转换为.net4.0然后构建解决方案获取新版本的dlls)
  2. 下载NAudio库(因为Lame支持16bit wav样本,我必须先将它从8bit转换为16bit wav)

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