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:
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:
Hier noch drei interessante Links die mir geholfen haben das ganze zu implementieren:
- http://mpgedit.org/mpgedit/mpeg_format/MP3Format.html
- https://www.w3.org/2000/10/swap/pim/mp3/mp3info.py
- https://hydrogenaud.io/index.p…85125.msg747716#msg747716
Und zuletzt noch der daraus entstandene Code:
- Die Klasse zum lesen und analysieren der mp3-Datei: https://github.com/rstemmer/mu…ob/develop/lib/mp3file.py
- Die Methode StreamFile nutzt diese Klasse dann: https://github.com/rstemmer/mu…ob/develop/lib/icecast.py