📹

PythonでGStreamer(SRT受信)

に公開

こちらの発展形みたいな感じです。
https://zenn.dev/qua_robotics/articles/35e997c190289d
https://zenn.dev/qua_robotics/articles/71da4d7f7502da

Raspberry Pi Zero2 Wをサーバーとしたときのコードになります。
クライアントからの配信が終了してもサーバーは再び受信待機するようにしています。

sudo apt install python3-gi <-すでに入ってた。
import sys
import gi
gi.require_version('GLib', '2.0')
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib

pipeline = None
bus = None
message = None

# initialize GStreamer
Gst.init(sys.argv[1:])
loop = GLib.MainLoop()

def cb_message(bus, message): # 起動中、busからのメッセージ処理
    global pipeline
    global loop
    msg_type = message.type

    # ストリーム終了時
    if msg_type == Gst.MessageType.EOS: # 一旦EOS状態から抜け出す必要あり。
        print("EOS")
        pipeline.set_state(Gst.State.NULL) # リソース解放
        loop.quit()
        
    # エラー時
    elif msg_type == Gst.MessageType.ERROR: 
        print("ERROR")
        pipeline.set_state(Gst.State.NULL) # リソース解放
        loop.quit()

# build the pipeline
# -vは使えません
pipeline = Gst.parse_launch(
    "srtserversrc uri=srt://:15000?mode=listener latency=100 \
    ! decodebin ! videoconvert ! video/x-raw,colorimetry=bt709 \
    ! fpsdisplaysink video-sink=autovideosink sync=false"
)

# start playing
print("Starting pipeline...")
ret = pipeline.set_state(Gst.State.PLAYING)

# busの方での終了処理監視
bus = pipeline.get_bus()
bus.add_signal_watch() 
bus.connect("message", cb_message)
"""
# こっちを使うとCtrl+Cで終了できない。 強制終了: ps aux | grep python -> kill -9 プロセスID
msg = bus.timed_pop_filtered( 
    Gst.CLOCK_TIME_NONE,
    Gst.MessageType.ERROR | Gst.MessageType.EOS
)"""

try:
    while True:
        print("Waiting stream...")
        loop.run() # 受信ループ

        # 再構築
        # cb_messageの中で再構築すると2回目以降上手くいきませんでした。
        loop = GLib.MainLoop()
        pipeline = Gst.parse_launch(
            "srtserversrc uri=srt://:15000?mode=listener latency=100 \
            ! decodebin ! videoconvert ! video/x-raw,colorimetry=bt709 \
            ! fpsdisplaysink video-sink=autovideosink sync=false"
        )
        pipeline.set_state(Gst.State.PLAYING)
        bus = pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect("message", cb_message)
        
except KeyboardInterrupt:
    print("KeyboardInterrupt")
    loop.quit()
    pass

# free resources
print("Freeing pipeline...")
pipeline.set_state(Gst.State.NULL)
print("Finish")

Discussion