14

嗨,我正在尝试将内存流中的文本转换为语音(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();

    }

谢谢。

4

6 回答 6

60

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

NuGet:

Install-Package NAudio.Lame

代码片段:我的显然返回一个字节 [] - 我有一个单独的保存到磁盘的方法 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();
            }


        }
于 2014-04-06T01:53:19.237 回答
13

您需要一个 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 OutputCopy 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需要删除/注释掉的声明。

一旦所有这些都完成了,你应该有一个功能性的内存波形文件到 MP3 转换器,你可以使用它来将你从文件中获取的 WAV 文件转换SpeechSynthesizer为 MP3。

于 2013-10-01T07:19:44.553 回答
11

这现在有点老了,但是由于您尚未接受我之前提供的答案...

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

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

于 2013-11-04T06:16:14.823 回答
1

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

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

于 2013-09-27T19:49:18.463 回答
1

我在 .net4.0 中有类似的要求来转换 8bit 8Khz 单声道 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();
        }
    }

先决条件:

  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)

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

于 2014-01-07T10:31:14.437 回答
0

试试:

using (WaveStream waveStream = WaveFormatConversionStream.CreatePcmStream(new     
Mp3FileReader(inputStream))) 
using (WaveFileWriter waveFileWriter = new WaveFileWriter(outputStream, waveStream.WaveFormat)) 
{ 
    byte[] bytes = new byte[waveStream.Length]; 
    waveStream.Position = 0;
    waveStream.Read(bytes, 0, waveStream.Length); 
    waveFileWriter.WriteData(bytes, 0, bytes.Length); 
    waveFileWriter.Flush(); 
} 
于 2021-06-01T06:59:39.540 回答