Есть ли способ в C # воспроизводить звук (например, MP3) непосредственно из System.IO.Stream, который, например, был воспроизведен из WebRequest без временного сохранения данных на диск?
Решение с NAudio
С помощью NAudio 1.3 можно:
- Загрузите файл MP3 из URL-адреса в MemoryStream
- Преобразуйте данные MP3 в данные волны после того, как они были полностью загружены
- Воспроизведение данных с использованием волновых NAudio класса WaveOut «ю.ш.
Было бы неплохо иметь возможность даже воспроизвести наполовину загруженный файл MP3, но это кажется невозможным из-за NAudio. библиотеки .
И вот функция, которая сделает всю работу:
public static void PlayMp3FromUrl(string url)
{
using (Stream ms = new MemoryStream())
{
using (Stream stream = WebRequest.Create(url)
.GetResponse().GetResponseStream())
{
byte[] buffer = new byte[32768];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
}
ms.Position = 0;
using (WaveStream blockAlignedStream =
new BlockAlignReductionStream(
WaveFormatConversionStream.CreatePcmStream(
new Mp3FileReader(ms))))
{
using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(blockAlignedStream);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing )
{
System.Threading.Thread.Sleep(100);
}
}
}
}
}
Ответы:
Изменить: ответ обновлен, чтобы отразить изменения в последних версиях NAudio
Это возможно с использованием написанной мной аудиобиблиотеки .NET с открытым исходным кодом NAudio . Он ищет кодек ACM на вашем ПК для преобразования. Mp3FileReader, поставляемый с NAudio, в настоящее время предполагает возможность изменения положения в исходном потоке (он заранее создает индекс кадров MP3), поэтому он не подходит для потоковой передачи по сети. Однако вы все равно можете использовать
MP3Frame
иAcmMp3FrameDecompressor
классы в NAudio распаковывать потоковым MP3 на лету.Я разместил в своем блоге статью, в которой объясняется, как воспроизводить поток MP3 с помощью NAudio . По сути, у вас есть один поток, загружающий кадры MP3, распаковывающий их и сохраняющий в файле
BufferedWaveProvider
. Затем другой поток воспроизводит, используя вBufferedWaveProvider
качестве входных данных.источник
Класс SoundPlayer может это сделать. Похоже, все, что вам нужно сделать, это установить свойство Stream для потока, а затем вызвать
Play
.edit
Я не думаю, что он может воспроизводить файлы MP3; похоже, ограничен .wav. Я не уверен, есть ли что-нибудь во фреймворке, которое может напрямую воспроизводить файл MP3. Все, что я нахожу об этом, связано либо с использованием элемента управления WMP, либо с взаимодействием с DirectX.
источник
Бас умеет именно это. Воспроизведение из байта [] в памяти или через делегаты файлов, в которые вы возвращаете данные, чтобы вы могли играть, как только у вас будет достаточно данных для начала воспроизведения.
источник
Я немного изменил исходный код для начала темы, поэтому теперь он может воспроизводить не полностью загруженный файл. Вот он (обратите внимание, что это всего лишь образец и точка для начала; здесь вам нужно выполнить некоторые исключения и обработку ошибок):
источник
Я настроил источник, опубликованный в вопросе, чтобы разрешить использование с Google TTS API, чтобы ответить на вопрос здесь :
Вызов с помощью:
Завершить с помощью:
Обратите внимание, что я использую
ParameterizedThreadDelegate
в приведенном выше коде, и поток запускается сplayThread.Start(10000);
. 10000 представляет собой максимум 10 секунд звука для воспроизведения, поэтому его нужно будет настроить, если для воспроизведения вашего потока требуется больше времени. Это необходимо, потому что текущая версия NAudio (v1.5.4.0), похоже, не может определить, когда закончится воспроизведение потока. Это может быть исправлено в более поздней версии или, возможно, есть обходной путь, на поиск которого я не нашел времени.источник
NAudio является оболочкой для API WaveOutXXXX. Я не смотрел на источник, но если NAudio предоставляет функцию waveOutWrite () таким образом, чтобы не останавливать воспроизведение автоматически при каждом вызове, тогда вы сможете делать то, что действительно хотите, а именно начать воспроизведение аудиопоток до того, как вы получите все данные.
Использование функции waveOutWrite () позволяет вам «читать вперед» и выгружать меньшие фрагменты звука в очередь вывода - Windows автоматически воспроизводит фрагменты без проблем. Ваш код должен взять сжатый аудиопоток и на лету преобразовать его в небольшие фрагменты WAV-аудио; эта часть будет действительно сложной - все библиотеки и компоненты, которые я когда-либо видел, конвертируют из MP3 в WAV весь файл за раз. Вероятно, ваш единственный реальный шанс - сделать это с помощью WMA вместо MP3, потому что вы можете написать простые оболочки C # вокруг мультимедийного SDK.
источник
Я обернул библиотеку декодера MP3 и сделал ее доступной для разработчиков .NET как mpg123.net. .
Включены образцы для преобразования файлов MP3 в PCM и чтения тегов ID3 .
источник
Я не пробовал его из WebRequest, но как Windows Media Player ActiveX, так и MediaElement (из WPF компоненты ) способны воспроизводить и буферизовать потоки MP3.
Я использую его для воспроизведения данных, поступающих из потока SHOUTcast, и он отлично работал. Однако я не уверен, сработает ли это в том сценарии, который вы предлагаете.
источник
Я всегда использовал FMOD для таких вещей, потому что он бесплатный для некоммерческого использования и хорошо работает.
Тем не менее, я бы с радостью переключился на что-то меньшее (FMOD ~ 300k) и с открытым исходным кодом. Супер бонусные баллы, если он полностью управляется, так что я могу скомпилировать / объединить его с моим .exe и не нужно особо заботиться о переносимости на другие платформы ...
(FMOD также обеспечивает переносимость, но вам, очевидно, понадобятся разные двоичные файлы для разных платформ)
источник