Laden...

MP3 Stream in Datei und gleichzeitig hören

Erstellt von SGT_BOB vor 18 Jahren Letzter Beitrag vor 18 Jahren 3.525 Views
S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren
MP3 Stream in Datei und gleichzeitig hören

Hallo Leute.

Sorry für den ungewöhnlichen Titel. Aber genauso ungewöhnlich ist auch mein Problem. 😁

Habe es jetzt geschafft, einen MP3-Stream aus dem Internet zu streamen und in eine Datei zu schreiben. Wenn diese Datei zu Ende geschrieben ist, kann ich diese auch anhören. Aber solange in die Datei geschrieben wird bekomme ich weder über MCI noch über AudioVideoPlayback einen Zugriff darauf.

Kann es sein das die Datei während des Schreibvorgangs gesperrt wird.

Vielleicht gibt es auch noch eine andere Möglichkeit.
Der Stream wird per HttpWebRequest und HttpWebResponse geholt. Es besteht kein direkter Zugriff auf eine Datei (z.B. www.musik.de/lied.mp3).
Welche Möglichkeit gibt es den MP3-Stream direkt zu spielen? (Stream nicht Datei)

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo SGT_BOB,

hm, finde ich gar nicht zu ungewöhlich das Problem. Auch der Titel ist doch voll ok.

Ob man auf eine Datei, die gerade geschrieben wird, lesend zugreifen kann, hängt vom Share-Modus ab. Diesen kann man bei einem FileStream als letzten Parameter vom FileStream-Konstruktor (String, FileMode, FileAccess, FileShare) festlegen.

herbivore

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Hallo herbivore.

Wie genau sollte das denn aussehen?

Habs momentan so:



private void RipStream()
{
...
byteOut = createNewFile(destPath, fileName);  // FileStream zum schreiben in Datei
Console.WriteLine("Aktuell gespielt: " + currentTrack); // Ausgabe zur Kontrolle
Microsoft.DirectX.AudioVideoPlayback.Audio.FromFile(currentTrack ,true); // Abspielen von currentTrack
...
}

private FileStream createNewFile(String destPath, String filename)
{
...
currentTrack = destPath + filename + ".mp3";  // string (Bsp.: "D:\TestStream\track.mp3")
return new FileStream(destPath + filename + ".mp3", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
...
}

Der Rückgabewert meiner Funktion ist also ein FileStream. Das schreiben funktioniert auch aber wie gesagt, mit dem Lesen haperts. Vielleicht mach ich was falsch?

currentTrack speichert, laut Console-Ausgabe, auch den korrekten Pfad und Titel des Tracks, der gerade geschrieben wird.

Aber per "Microsoft.DirectX.AudioVideoPlayback.Audio.FromFile(currentTrack ,true);" kann ich einfach nicht darauf zugreifen. Gebe ich einen Namen von einem fertigem MP3-File mit, funzt es.

Weiß nicht mehr weiter. 🙁

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Leider hänge ich noch immer an dem Problem. 🙁

Ich bekomme selbst keinen Zugriff auf die zum schreiben geöffneten Dateien. Habs per AudioVideoPlayback, MCI und auch über die QuartzTypeLib versucht.

Wie oben im Code schon gezeigt, habe ich den Zugriffsmodus auf "FileShare.Read" gesetzt. Eigentlich sollte das doch auch richtig sein. Leider bekomme ich außer mit dem VLC-Mediaplayer mit keinem anderen Player Zugriff auf eine zum schreiben geöffnete Datei. Ich bekomme nur eine Fehlermeldung, daß ein anderer Prozess auf diese Datei zugreift und sie deswegen nicht geöffnet werden kann.

Weiß evtl. jemand Rat oder vielleicht sogar wie der VLC-Player die Daten liest.

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

1.549 Beiträge seit 2004
vor 18 Jahren

ich denke das er intern mit einer kopie arbeitet

Wir Arbeiten eigendlich nicht wir nehmen nur das geld

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Erst mal danke für die schnelle Antwort.

Das Problem bei dieser Methode wäre aber, wie soll ich diese abspielen.

Momentan läuft es so: Ich erstelle eine Datei, diese wird in einer Schleife über den Stream gefüllt. Sobald die Datei erstellt ist und ca. 100 kb groß ist wird versucht über eine der oben genannten Methoden, diese abzuspielen.
D.h. ich starte das Abspielen ja nur einmal !!!

Wenn ich richtig verstanden habe, soll ich also eine temporäre Datei erstellen. Diese soll dann innerhalb meiner Schleife aktuallisiert werden. Die temporäre Datei wird also dann während des Abspielens ersetzt, was ja beinhaltet, daß sie erst gelöscht wird und dann neu erstellt.

Ich weiß nicht recht wie das funktionieren soll. Vielleicht hab ich dich auch nicht richtig verstanden.

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

4.221 Beiträge seit 2005
vor 18 Jahren

Original von SGT_BOB
Wie oben im Code schon gezeigt, habe ich den Zugriffsmodus auf "FileShare.Read" gesetzt.

Mach doch mal FileShare.ReadWrite (im Extremfall schiesst Du ein File ab.... aber ev. kannst Du so die Player überlisten)

Alternativ-Idee

Du legst parallel zum geschriebenen File mit denselben Bytes pro 100 KB ein File an... wenn Du dann jedes neu erstellte File wieder dem Player übergibst (Queueing) sollte er auch alles brav spielen.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Hallo Programmierhans.

OK. 1. Lösung war schnell probiert (hatte es glaube ich auch schon mal) aber hat leider nicht geklappt.

Leider weiß ich mit deiner Alternativ-Lösung nix anzufangen. Wie soll das denn mit dem Queueing aussehen. Sorry aber ich stehe etwas auf dem Schlauch. 🙁

Mfg SGT_BOB

//edit:

Falls das noch unklar ist, mein Programm ist selbst der Player (oder sollte es zum mindest sein 😉 )

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

4.221 Beiträge seit 2005
vor 18 Jahren

Ist:

Byte[] ---> "CoolSound.mp3"

Soll:
Byte[] ---> "CoolSound.mp3"

zusätzlich

Byte[] "1" --> 1.mp3 (100 KB)
Play "1.mp3"
Byte[] "2" --> 2.mp3 (100 KB)
Play "2.mp3"
..
..
..

Anstelle von Play wäre Enqueue besser wenn es so was gibt 🙂 .... bei der Widergabe mit MCI ist es ja auch möglich eine Benachrichtigung zu erhalten wenn das eine File fertig gespielt ist ... dann sofort den nächsten Teil des Sounds starten.

So kriegt man bei MCI mit wann der Sound fertig ist: Mp3 Stream abspielen

Den Rest des MCI Codes findest Du auch dort... ein wenig weiter vorne

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Entweder bin ich echt zu blöd oder ... 😁

OK. Jetzt mal langsam.

Ich kapier das nicht so ganz:

Ist:

Byte[] ---> "CoolSound.mp3"

Soll:
Byte[] ---> "CoolSound.mp3"

zusätzlich

Byte[] "1" --> 1.mp3 (100 KB)
Play "1.mp3"
Byte[] "2" --> 2.mp3 (100 KB)
Play "2.mp3"
..
..
..

Soll ich den Stream gleichzeitig abwechselnd in zwei weitere temporäre Dateien umleiten und dann immer das andere nach und nach abspielen lassen.

Sorry das ich mich so doof anstelle, aber ich hänge jetzt schon solange an dieser einen Stelle.

.... bei der Widergabe mit MCI ist es ja auch möglich eine Benachrichtigung zu erhalten wenn das eine File fertig gespielt ist ... dann sofort den nächsten Teil des Sounds starten.

Weißt du evtl. auch wie ich diese Nachricht erhalte?

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

4.221 Beiträge seit 2005
vor 18 Jahren

Original von SGT_BOB
Entweder bin ich echt zu blöd oder ... 😁

OK. Jetzt mal langsam.

Ich kapier das nicht so ganz:

Ist:

Byte[] ---> "CoolSound.mp3"

Soll:
Byte[] ---> "CoolSound.mp3"

zusätzlich

Byte[] "1" --> 1.mp3 (100 KB)
Play "1.mp3"
Byte[] "2" --> 2.mp3 (100 KB)
Play "2.mp3"
..
..
..

Soll ich den Stream gleichzeitig abwechselnd in zwei weitere temporäre Dateien umleiten und dann immer das andere nach und nach abspielen lassen.

ich würde mal so mit ca 100 files beginnen

Denn das Schreiben der Files und das hören ist ja eh auch leicht verzögert... und wird sich eventuell bei längeren Aufnahmen noch mehr verzögern

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

4.221 Beiträge seit 2005
vor 18 Jahren

Original von SGT_BOB

Weißt du evtl. auch wie ich diese Nachricht erhalte?

Mfg SGT_BOB

Den Link habe ich weiter oben schon gepostet.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

OK, dann hab ich es also doch (fast) richtig verstanden. 😉

Ich hätte da noch eine Frage zu der Möglichkeit ein File direkt über die URL abzuspielen.

Ich bekomme aber leider nix im Format "http://radioserver.de/musik.mp3" aus den Metadaten des Radioservers. Irgendwo muss aber dieses File rumfliegen, sonst könnte es ja nicht abgespielt werden.

Irgendeine Idee???

Mfg SGT_BOB

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo SGT_BOB,

was den Share-Modus anbelangt, habe ich folgendes Mini-Test-Programm geschrieben. FileShare.Read hat wirklich nicht gereicht, aber wenn beide "Seiten" mit FileShare.ReadWrite arbeiten dann geht es. Entsprechend werden die Player, die die Datei nicht öffnen können, nicht den richtigen Share-Mode verwenden.


using System;
using System.IO;
using System.Text;
using System.Threading;

abstract class App
{
   public static int Main (string [] astrArg)
   {
      if (astrArg.Length > 0) {
         using (FileStream fs = new FileStream ("share.txt",
                                                FileMode.OpenOrCreate,
                                                FileAccess.Write,
                                                FileShare.ReadWrite)) {
         using (StreamWriter sw = new StreamWriter (fs, Encoding.Default)) {

         for (int i = 0; i < 20; ++i) {
            sw.WriteLine (astrArg [0]);
            sw.Flush ();
            Thread.Sleep (1000);
         }

         }
         }
      } else {
         using (FileStream fs = new FileStream ("share.txt",
                                                FileMode.Open,
                                                FileAccess.Read,
                                                FileShare.ReadWrite)) {
         using (StreamReader sr = new StreamReader (fs, Encoding.Default)) {

         String strLine;
         while ((strLine = sr.ReadLine ()) != null) {
            Console.WriteLine (sr.ReadLine ());
         }

         }
         }
      }


      return 0;
   }
}

Was das Abspielen einer URL angeht, müssen die Daten nicht als Datei zwischengespeichert werden und werden das bei den meisten Player vermutlich auch nicht. Stattdessen werden die Daten direkt aus dem Netz gesaugt und direkt abgespielt. Oder meinst du was anderes?

herbivore

S
SGT_BOB Themenstarter:in
125 Beiträge seit 2005
vor 18 Jahren

Hallo herbivore.

Nee, genau das meinte ich. Aber AudioVideoPlayback z.B. bietet eine Audio.FromUrl-Methode an. Leider funktioniert diese nicht auf der weiter oben genannten Url.

Eine Url wie "http://radioserver.de/musik.mp3" wird problemlos abgespielt. Da dort der direkte Zugriff auf das File gegeben ist. Wie gesagt eine Url wie "http://64.236.34.4:80/stream/1039" bietet mir leider keinen direkten Zugriff auf ein File, sondern sendet mir bei richtiger Anfrage nur den entsprechenden Stream, den ich selbstverständlich in ein File umleiten kann. Doch AudioVideoPlayback oder auch MCI bieten von sich aus keine Möglichkeiten diesen Stream direkt abzuspielen.

Vielleicht hat da einer eine Idee. Vielleicht weiß sogar jemand wie zum Beispiel Winamp das macht. 😉

Mfg SGT_BOB

PS: Die Methode mit den verschiedenen Temp-Files wäre auch machbar. Werde ich auch nochmal überdenken. Aber trotzdem würde ich gerne wissen ob und wie das anders geht.

//EDIT:

FileShare.ReadWrite funzt leider auch nicht. Keine Ahnung warum. Hab aber schon alles durchprobiert. MCI hat Probleme mit einem zum schreiben geöffneten File.

*************************
Ich bin root, ich darf das... 😜
root>_
*************************