Konzeptionelle Frage: Audio Stream pausieren

  • Hi,


    Ich habe folgendes Problem, bzw folgenden Wunsch:


    Ich streame mp3 dateien mithilfe der Bibliothek libshout zu einem Icecast Server.


    Jetzt würde ich gerne die Musik pausieren. Wie geht man da am besten vor?



    Idee 1: Statt der Chunks aus der mp3 einfach andere Daten an Icecast senden.
    Problem: Ich weiß nicht an welcher Stelle der mp3-Datei, absgesehen von dem Offset der Rohdaten, ich bin. Irgendwann irgendwelche daten oder auch nur eine Sekunde Stille einspielen würde den Decoder des Zuhörers stören.


    Idee 2.1: Komplett die Verbindung zu Icecast beenden.
    Problem: Sehr hässlich und unelegant.


    Idee 2.2: Einfach aufhören die Daten zu senden. Icecast beendet dann die Verbindung und ich bekomme ein Timeout error.
    Problem: Noch schlimmer als Idee 2.1


    Idee 3: Den angebrochenen Song zuende streamen, und dann eine Sekunde Stille streamen bis das pausieren aufgehoben wurde.
    Problem: Man verzögert die Reaktion um die Zeit bis zum Ende des Lieds, anstatt nur um die Größe der Buffer.



    Habt ihr weitere Ideen, oder Erfahrung mit diesem Problem?

  • Die vermuteten Probleme sind alle aufgetreten.
    Beim beenden der Verbindung zu Icecast, beendet Icecast auch alle verbindungen zu den Listenern. Das macht diese Lösung nicht nur im Code hässlich.
    Die Lösung war entsprechend etwas aufwändiger:


    mp3 Dateien sind in unabhängige Teile zerlegt - Frames. Jeder Frame enthält ein paar millisekunden audio material.
    Um nun einen pausierbaren Stream bereit zu stellen reicht es nicht aus, einfach ein paar kilobyte aus der datei zu laden und zu Icecast zu senden. Man muss die Datei Frameweise übertragen.
    Wenn jetzt der Stream pausiert werden soll, kann man einfach anstatt des nächsten Frames aus der mp3-Datei einen Frame übertragen, der nur Stille enthält.


    Bei diesen stillen Frame muss man darauf achten, dass er exakt die Codierung (bitrate, mode) hat, wie auch die Frames aus den mp3-Files.
    Ich habe einen solchen Frame wie folgt erstellt:

    Bash
    ffmpeg -filter_complex aevalsrc=0 -acodec libmp3lame -ab 320k -t 1 monosilence.mp3
    ffmpeg -i monosilence.mp3 -ab 320k -ac 2 stereosilence.mp3


    Dann konnte ich mit dem Code, den ich schrieb um eine mp3-Datei Frameweise einzulesen den 1. Frame aus der stereosilence.mp3 extrahieren. (Code ist unten verlinkt)


    Der algorithmus sieht nun wie folgt aus:


    Code
    for each frame in mp3-file
        if not muted
            stream frame
        else
            stream silence


    Hier noch drei interessante Links die mir geholfen haben das ganze zu implementieren:

    Und zuletzt noch der daraus entstandene Code:

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!