===== 23.9.0.1.5 Umsetzung einer Signal-Aufspaltung in Pipelines (TEE) =====

In einigen Fällen ist die Aufspaltung eines Signals erforderlich. So können Sie zum Beispiel einen Zweig dafür verwenden, ihn auf dem Lautsprecher auszugeben, während der andere das Signal in einer Datei abspeichert und damit aufzeichnet. Für solche Zwecke sieht das GStreamer-Framework das sogenannte tee-Element vor. Eine Pipeline mit einem tee-Element sieht dann so aus:

BILD_4

Abbildung 23.9.0.1.4: Pipeline zum Hören und Aufzeichnen von Web-Radio-Streams

Die o.a. Pipeline gibt eine Webradio-Station auf dem Lautsprecher aus und zeichnet das Audiosignal parallel in einer Datei im MP3-Format ab. Es folgt das entsprechende GStreamer-CLI-Kommando und kann in der Konsole ausprobiert werden.

<code>
gst-launch-1.0 uridecodebin uri="http://icecast.ndr.de/ndr/ndrinfo/schleswigholstein/mp3/128/stream.mp3" ! audioconvert ! tee name=radio ! queue ! autoaudiosink radio. ! queue ! lamemp3enc target=bitrate bitrate=128 cbr=true ! filesink location="/home/username/output.mp3"
</code>

Ab Gambas 3.19 könnte eine Umsetzung in Gambas so aussehen:

<code gambas>
    Private pl As MediaPipeline
'-- Declarations for source
    Private src As MediaControl
    Private tee As MediaControl
    Private cnv As MediaControl
'-- Declarations for branch 1
    Private que1 As MediaControl
    Private snk1 As MediaControl
'-- Declarations for branch 2
    Private que2 As MediaControl
    Private enc2 As MediaControl
    Private snk2 As MediaControl

Public Sub Form_Open()

    pl = New MediaPipeline
'-- Source
    src = New MediaControl(pl, "uridecodebin")
    src["uri"] = "http://icecast.ndr.de/ndr/ndrinfo/schleswigholstein/mp3/128/stream.mp3"
    cnv = New MediaControl(pl, "audioconvert")
    tee = New MediaControl(pl, "tee")
'-- Branch 1
    que1 = New MediaControl(pl, "queue")
    snk1 = New MediaControl(pl, "autoaudiosink")
'-- Branch 2
    que2 = New MediaControl(pl, "queue")
    enc2 = New MediaControl(pl, "lamemp3enc")
    enc2["target"] = "bitrate"
    enc2["bitrate"] = 128
    enc2["cbr"] = True
    snk2 = New MediaControl(pl, "filesink")
    snk2["location"] = User.Home & "/radio_rec.mp3"

'-- Link source elements
    src.LinkLaterTo(cnv)
    cnv.LinkTo(tee)

'-- Link to TEE and link branch 1 elements
    tee.LinkTo(que1)
    que1.LinkTo(snk1)

'-- Link to TEE and link branch 2 elements
    tee.LinkTo(que2)
    que2.LinkTo(enc2)
    enc2.LinkTo(snk2)

    pl.Play()

End

Public Sub Form_Close()

  pl.Stop()
  pl.Close()

End
</code>

In allen früheren Gambas-Versionen < 3.19 werden Sie feststellen, dass die mp3-Datei nach Beendigung des Programms geleert wird. Dies ist auf einen Bug zurück zu führen, für den Sie folgende Workarounds einsetzen können:

• Setzen Sie das Property 'Location' des Elements 'filesink' vor Beendigung des Programms auf Null oder
• schreiben Sie die Audio-Daten in eine temporäre Datei und sichern sie diese unter einem anderen Namen, bevor Sie das Programm beenden.

Bitte beachten Sie, das GStreamer-Pipelines mit Buffern arbeiten, die u.U. ordentlich beendet werden müssen, um eine gültige Aufzeichnungsdatei zu erhalten. Es kann also notwendig sein weitere Maßnahmen zu ergreifen, die hier nicht weiter behandelt werden.
