Изменить формат с 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. Вы можете найти код и пример проекта здесь.
Шаги, чтобы заставить это работать:
Скопируйте следующие файлы из
MP3Compressor
к вашему проекту:- AudioWriters.cs
- Lame.cs
- lame_enc.dll
- Mp3Writer.cs
- Mp3WriterConfig.cs
- WaveNative.cs
- WriterConfig.cs
В свойствах проекта для
Lame_enc.dll
установитьCopy to Output
собственность наCopy if newer
или жеCopy always
,редактировать
Lame.cs
и заменить все экземпляры:[DllImport("Lame_enc.dll")]
с:
[DllImport("Lame_enc.dll", CallingConvention = CallingConvention.Cdecl)]`
Добавьте следующий код в ваш проект:
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(); } } }
Либо добавить ссылку на
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:
- .net 4 скомпилировала библиотеку йети (чтобы получить ее, загрузите эту старую ( http://www.codeproject.com/KB/audio-video/MP3Compressor/MP3Compressor.zip) и преобразуйте ее в.net4.0, затем соберите решение для получить новую версию dll)
- скачайте библиотеки 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();
}