Gibt es in C # eine Möglichkeit, Audio (z. B. MP3) direkt von einem System.IO.Stream abzuspielen , das beispielsweise von einer WebRequest zurückgegeben wurde, ohne die Daten vorübergehend auf der Festplatte zu speichern?
Lösung mit NAudio
Mit Hilfe von NAudio 1.3 ist Folgendes möglich:
- Laden Sie eine MP3-Datei von einer URL in einen MemoryStream
- Konvertieren Sie MP3-Daten nach dem vollständigen Laden in Wave-Daten
- Spielen Sie die Wellendaten mit der WaveOut -Klasse von NAudio ab
Es wäre schön gewesen, sogar eine halb geladene MP3-Datei abspielen zu können, aber dies scheint aufgrund des NAudio- Bibliotheksdesigns unmöglich zu sein .
Und dies ist die Funktion, die die Arbeit erledigt:
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);
}
}
}
}
}
Antworten:
Bearbeiten: Die Antwort wurde aktualisiert, um Änderungen in den letzten Versionen von NAudio widerzuspiegeln
Es ist möglich, die von mir geschriebene NAudio Open Source .NET- Audiobibliothek zu verwenden . Es sucht nach einem ACM-Codec auf Ihrem PC, um die Konvertierung durchzuführen. Der mit NAudio gelieferte Mp3FileReader erwartet derzeit eine Neupositionierung innerhalb des Quelldatenstroms (er erstellt einen Index von MP3-Frames im Voraus), sodass er nicht für das Streaming über das Netzwerk geeignet ist. Sie können die Klassen
MP3Frame
undAcmMp3FrameDecompressor
in NAudio jedoch weiterhin verwenden, um gestreamte MP3-Dateien im laufenden Betrieb zu dekomprimieren.Ich habe in meinem Blog einen Artikel veröffentlicht, in dem erklärt wird, wie ein MP3-Stream mit NAudio wiedergegeben wird . Im Wesentlichen haben Sie einen Thread, der MP3-Frames herunterlädt, dekomprimiert und in einem speichert
BufferedWaveProvider
. Ein anderer Thread wird dann mit demBufferedWaveProvider
als Eingabe wiedergegeben.quelle
Die SoundPlayer- Klasse kann dies tun. Es sieht so aus, als müssten Sie nur die Stream- Eigenschaft auf den Stream setzen und dann aufrufen
Play
.bearbeiten
Ich glaube nicht, dass es MP3-Dateien abspielen kann; es scheint auf .wav beschränkt zu sein. Ich bin nicht sicher, ob es irgendetwas im Framework gibt, das eine MP3-Datei direkt abspielen kann. Alles, was ich dazu finde, beinhaltet entweder die Verwendung eines WMP-Steuerelements oder die Interaktion mit DirectX.
quelle
Bass kann genau das. Spielen Sie von Byte [] im Speicher oder von einem Through-File-Delegaten, bei dem Sie die Daten zurückgeben, damit Sie spielen können, sobald Sie über genügend Daten verfügen, um die Wiedergabe zu starten.
quelle
Ich habe die Starterquelle des Themas leicht geändert, damit jetzt eine nicht vollständig geladene Datei abgespielt werden kann. Hier ist es (beachten Sie, dass es sich nur um ein Beispiel handelt und ein Ausgangspunkt ist; Sie müssen hier einige Ausnahmen und Fehler behandeln):
quelle
Ich habe die in der Frage veröffentlichte Quelle optimiert, um die Verwendung mit der TTS-API von Google zu ermöglichen, um die Frage hier zu beantworten :
Rufen Sie auf mit:
Beenden mit:
Beachten Sie, dass ich das
ParameterizedThreadDelegate
im obigen Code verwende und der Thread mit gestartet wirdplayThread.Start(10000);
. Der 10000 repräsentiert maximal 10 Sekunden Audio, das abgespielt werden muss. Daher muss er optimiert werden, wenn die Wiedergabe Ihres Streams länger dauert. Dies ist erforderlich, da die aktuelle Version von NAudio (v1.5.4.0) Probleme zu haben scheint, festzustellen, wann der Stream abgespielt wird. Möglicherweise wurde es in einer späteren Version behoben, oder es gibt eine Problemumgehung, für deren Suche ich mir nicht die Zeit genommen habe.quelle
NAudio umschließt die WaveOutXXXX-API. Ich habe mir die Quelle nicht angesehen, aber wenn NAudio die Funktion waveOutWrite () so verfügbar macht, dass die Wiedergabe nicht bei jedem Aufruf automatisch gestoppt wird, sollten Sie in der Lage sein, das zu tun, was Sie wirklich wollen, nämlich die Wiedergabe zu starten Audiostream, bevor Sie alle Daten erhalten haben.
Mit der Funktion waveOutWrite () können Sie "weiterlesen" und kleinere Audioblöcke in die Ausgabewarteschlange stellen. Windows spielt die Blöcke automatisch nahtlos ab. Ihr Code müsste den komprimierten Audiostream nehmen und ihn im laufenden Betrieb in kleine Teile von WAV-Audio konvertieren. Dieser Teil wäre wirklich schwierig - alle Bibliotheken und Komponenten, die ich je gesehen habe, führen eine MP3-zu-WAV-Konvertierung für jeweils eine ganze Datei durch. Wahrscheinlich besteht Ihre einzige realistische Chance darin, WMA anstelle von MP3 zu verwenden, da Sie einfache C # -Wrapper um das Multimedia-SDK schreiben können.
quelle
Ich habe die MP3-Decoder-Bibliothek verpackt und sie für .NET- Entwickler als mpg123.net verfügbar gemacht .
Enthalten sind die Beispiele zum Konvertieren von MP3-Dateien in PCM und zum Lesen von ID3- Tags.
quelle
Ich habe es nicht von einem WebRequest versucht, aber sowohl der Windows Media Player ActiveX und das Mediaelement (von WPF ) Komponenten ist in der Lage zu spielen und MP3 - Streams Pufferung.
Ich verwende es, um Daten aus einem SHOUTcast- Stream abzuspielen, und es hat großartig funktioniert. Ich bin mir jedoch nicht sicher, ob es in dem von Ihnen vorgeschlagenen Szenario funktioniert.
quelle
Ich habe FMOD immer für solche Dinge verwendet, weil es für nichtkommerzielle Zwecke kostenlos ist und gut funktioniert.
Trotzdem würde ich gerne zu etwas wechseln, das kleiner (FMOD ist ~ 300k) und Open Source ist. Super Bonuspunkte, wenn es vollständig verwaltet wird, damit ich es mit meiner EXE-Datei kompilieren / zusammenführen kann und nicht besonders vorsichtig sein muss, um die Portabilität auf andere Plattformen zu gewährleisten ...
(FMOD bietet auch Portabilität, aber Sie benötigen offensichtlich unterschiedliche Binärdateien für unterschiedliche Plattformen.)
quelle