Изменить формат с WAV на MP3 в потоке памяти в NAudio

Привет, я пытаюсь преобразовать текст в речь (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();

    }

Благодарю.

7 ответов

Решение

Вам нужна библиотека компрессора MP3. Я использую Lame через упаковку Yeti 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 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.cs а также WriterConfig.cs удалить ссылки. Оба из них имеют using System.Windows.Forms; что вы можете удалить, и WriterConfig.cs имеет ConfigControl декларация, которая должна быть удалена / закомментирована.

После того, как все это будет сделано, вы должны иметь функциональный конвертер волновых файлов в MP3 в память, который вы можете использовать для преобразования файла WAV, который вы получаете из SpeechSynthesizer в MP3.

Просто хотел опубликовать мой пример тоже с помощью 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();
            }


        }

Сейчас это немного устарело, но так как вы не приняли ответ, который я ранее предоставил...

Недавно я создал расширение для NAudio, которое инкапсулирует библиотеку LAME для упрощенного кодирования MP3.

Используйте менеджер пакетов NuGet, чтобы найти NAudio.Lame, Базовый пример его использования доступен here,

Предполагая, что вы пытаетесь преобразовать вывод в MP3, вам нужно что-то, что может справиться с перекодированием звука. Доступно множество инструментов, но я предпочитаю FFmpeg. Это инструмент командной строки, поэтому вам нужно будет принять это во внимание, но в остальном его очень просто использовать.

В Интернете много информации, но вы можете начать с проверки их документации здесь.

У меня было аналогичное требование в.net4.0 для преобразования 8 бит 8 кГц моно 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 скомпилировала библиотеку йети (чтобы получить ее, загрузите эту старую ( http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip) и преобразуйте ее в.net4.0, затем соберите решение для получить новую версию dll)
  2. скачайте библиотеки NAudio (так как Lame поддерживает 16-битный пример WAV, мне нужно было сначала преобразовать его из 8-битного в 16-битный WAV)

Я использовал размер буфера 64 кбит / с (мое пользовательское требование)

Предполагая, что вы установили NAudio и NAudio.Lame из NuGet:

      using (var reader = new AudioFileReader(@"C:\Temp\Test0001.wav"))
using (var writer = new LameMP3FileWriter(@"C:\Temp\Test0001.mp3", reader.WaveFormat, LAMEPreset.STANDARD))

попробуй:

      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(); 
} 
Другие вопросы по тегам