Frage

Gibt es eine Möglichkeit in C # Audio zu spielen (zB MP3) direcly von einem System.IO.Stream , dass zum Beispiel von einem WebRequest ohne die Daten zu speichern vorübergehend auf die Festplatte returend wurde?


Lösung mit NAudio

Mit Hilfe von NAudio 1.3 ist es möglich:

  1. Legen Sie eine MP3-Datei von einer URL in einen Memorystream
  2. Konvertieren von MP3-Daten in Wellendaten, nachdem sie vollständig geladen wurde
  3. Die Wiedergabe der Wellendaten mit NAudio 's WaveOut Klasse

Es wäre schön gewesen, der Lage sein, sogar eine Hälfte geladen MP3-Datei abspielen, aber dies scheint unmöglich zu sein, aufgrund der

War es hilfreich?

Lösung

Bearbeiten: Antwort aktualisiert, um Veränderungen in der letzten Versionen von NAudio

Es ist möglich, mit der NAudio Open-Source-.NET-Audio-Bibliothek, die ich geschrieben habe. Es sucht nach einem ACM-Codec auf dem PC, um die Konvertierung zu tun. Die Mp3FileReader mit NAudio geliefert erwartet derzeit in der Lage sein, innerhalb des Quellstrom neu zu positionieren (es einen Index von MP3-Frames aufbaut vorne), so ist es nicht geeignet für das Streaming über das Netzwerk. Sie können jedoch nach wie vor die MP3Frame und AcmMp3FrameDecompressor Klassen in NAudio verwenden gestreamten MP3 on the fly zu dekomprimieren.

Ich habe einen Artikel auf meinem Blog gepostet erklären wie einen MP3-Stream mit NAudio abzuspielen. Im Wesentlichen haben Sie einen Thread Download MP3-Frames, so dass sie zu dekomprimieren und sie in einem BufferedWaveProvider speichern. Ein anderer Thread dann spielt mit der BufferedWaveProvider als Eingang zurück.

Andere Tipps

Die Soundplayer Klasse kann dies tun. Es sieht aus wie alles, was Sie tun müssen, wird sein Strom Immobilien zum Strom, dann ruft Play.

Bearbeiten
Ich glaube nicht, dass obwohl MP3-Dateien abspielen kann; es scheint begrenzt .wav. Ich bin nicht sicher, ob es etwas gibt, im Rahmen, die direkt eine MP3-Datei abspielen können. Alles, was ich darüber finden beinhaltet entweder mit einer WMP-Steuerung oder der Interaktion mit DirectX.

Bass kann dies einfach. Wiedergabe von Byte [] im internen Speicher oder einem durch Datei Delegierten, wo Sie die Daten zurück, so mit, dass Sie spielen können, sobald Sie genügend Daten um die Wiedergabe zu starten ..

ich leicht modifiziert, um das Thema Starter Quelle, so dass es jetzt eine nicht-voll geladene Datei spielen kann. Hier ist es (beachten Sie, dass es nur eine Probe und ist ein Punkt aus zu starten, müssen Sie einige Ausnahme und Fehler tun Umgang hier):

private Stream ms = new MemoryStream();
public void PlayMp3FromUrl(string url)
{
    new Thread(delegate(object o)
    {
        var response = WebRequest.Create(url).GetResponse();
        using (var stream = response.GetResponseStream())
        {
            byte[] buffer = new byte[65536]; // 64KB chunks
            int read;
            while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
            {
                var pos = ms.Position;
                ms.Position = ms.Length;
                ms.Write(buffer, 0, read);
                ms.Position = pos;
            }
        }
    }).Start();

    // Pre-buffering some data to allow NAudio to start playing
    while (ms.Length < 65536*10)
        Thread.Sleep(1000);

    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 hüllt den WaveOutXXXX API. Ich habe nicht an der Quelle gesucht, aber wenn NAudio die waveOutWrite () Funktion in einer Weise aussetzt, die nicht automatisch die Wiedergabe auf jedem Anruf ist noch, dann sollten Sie in der Lage sein zu tun, was Sie wirklich wollen, was der Anfang ist spielen Audio-Stream, bevor Sie alle Daten erhalten.

die waveOutWrite () Funktion ermöglicht es Ihnen, auf „Read-Ahead“ und Dump kleinere Stücke von Audio in die Ausgabewarteschlange - Windows wird automatisch die Stücke nahtlos spielen. Der Code würde den komprimierten Audiostream nehmen und es zu kleinen Stücken von WAV-Audio-on-the-fly zu konvertieren; dieser Teil wäre wirklich schwierig sein - alle Bibliotheken und Komponenten die ich je tun in einer Zeit, eine ganze Datei MP3-to-WAV Konvertierung gesehen habe. Wahrscheinlich Ihre einzige realistische Chance, statt MP3 dies mit WMA zu tun, weil Sie einfach C # Wrapper um den Multimedia-SDK schreiben können.

Ich habe die Quelle in der Frage gepostet gezwickt Verwendung mit Google-TTS-API, um die Frage zu beantworten zu erlauben hier :

bool waiting = false;
AutoResetEvent stop = new AutoResetEvent(false);
public void PlayMp3FromUrl(string url, int timeout)
{
    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.PlaybackStopped += (sender, e) =>
                {
                    waveOut.Stop();
                };
                waveOut.Play();
                waiting = true;
                stop.WaitOne(timeout);
                waiting = false;
            }
        }
    }
}

Rufen Sie mit:

var playThread = new Thread(timeout => PlayMp3FromUrl("http://translate.google.com/translate_tts?q=" + HttpUtility.UrlEncode(relatedLabel.Text), (int)timeout));
playThread.IsBackground = true;
playThread.Start(10000);

Terminate mit:

if (waiting)
    stop.Set();

Beachten Sie, dass ich die ParameterizedThreadDelegate in dem obigen Code bin mit, und der Faden mit playThread.Start(10000); gestartet. Die 10000 stellt maximal 10 Sekunden Ton abgespielt werden, so dass es gezwickt werden muß, wenn Ihr Strom länger dauert als das zu spielen. Dies ist notwendig, weil die aktuelle Version von NAudio (v1.5.4.0) scheint die Bestimmung, ein Problem zu haben, wenn der Strom zu spielen ist getan. Es kann in einer späteren Version behoben werden oder vielleicht gibt es eine Abhilfe, die ich nicht die Zeit nehmen, haben zu finden.

wickelte ich die MP3-Decoder-Bibliothek und machte es für .NET Entwickler als < a href = "http://sourceforge.net/projects/mpg123net/" rel = "nofollow noreferrer"> mpg123.net .

Enthalten sind die Proben von MP3-Dateien zu konvertieren, um PCM und lesen ID3 Tags.

ich immer FMOD für Dinge wie diese verwendet haben, weil es kostenlos für nicht-kommerzielle Nutzung ist und funktioniert gut.

Das heißt, ich gerne etwas wechseln würde, die kleiner ist (BMVg ist ~ 300k) und Open-Source. Super-Bonuspunkte, wenn es vollständig verwaltet wird, so dass ich kompilieren kann / merge es mit meinem Exe und nicht habe extra darauf zu achten, Portabilität auf andere Plattformen zu bekommen ...

(BMVg tut auch Portabilität aber müssen Sie natürlich eine andere Binärdateien für verschiedene Plattformen)

Ich habe es nicht von einem WebRequest versucht, aber sowohl die Windows Media Player < a href = "http://en.wikipedia.org/wiki/ActiveX" rel = "nofollow noreferrer"> ActiveX und die Media (von WPF ) Komponenten sind in der Lage zu spielen und Pufferung MP3-Streams.

Ich benutze es, Daten von einem Shoutcast Strom und es funktionierte großartig. Allerdings bin ich nicht sicher, ob es in dem Szenario arbeiten Sie vorschlagen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top