I have a bin, set to receive an RTMP stream. When a stream arrives, it links to a queue as intended, and just works. However, I can’t find a way to detect when the stream stops. I need to know this so I can unlink and re-start listening and wait for another stream to arrive.
Some will say, listen for an EOF event, but many sources don’t send EOF - including OBS.
rtmpsrc doesn’t appear to offer a way, so I hope to discover another way. Any offers please?
OBS (Open Broadcast Server) sends H.264/ACC over RTMP.
rtmpsrc is a Gstreamer Plug-in.
rtmpsrc → decodebin → queue → etc
I’m saying OBS doesn’t send an EOF when the user stops the stream. Therefore the pads between the decoder and queue are not unlinked. IE. decodebin.ConnectPadRemoved isn’t called.
The code is only a small part of a large application which facilitates half-duplex communication over an Internet link.
IIRC decodebin does not remove pads when the stream receives EOS, because one could still seek to play in a loop (when there is a seekable source).
Detecting the end of the stream via ConnectPadRemoved is not correct, you rather want to install a pad probe on a pad in the chain, similar to this:
pad.AddProbe(gst.PadProbeTypeEventDownstream, func(pad gst.Pad, ppi *gst.PadProbeInfo) gst.PadProbeReturn {
ev := ppi.GetEvent()
if ev != nil && ev.GetType() == gst.EventEOS {
// do something here, but keep in mind that this is the streaming thread and blocking here will block dataflow in the pipeline
}
}
// not a blocking probe, so this passes the data to the next probe or pad
return gst.PadProbeOK
})
Be very careful with memory leaks here, because if your handler references the pad strongly, then the probe will not be automatically cleaned up (Manual cleanup is possible via RemoveProbe).
I’m grateful for your help and for taking time out from gst.go, but once again I’m out of my depth. Please could you explain where to place this code and what to do with it?
If this is the chain where you want to detect an EOS, then retrieve any pad on in (element.GetStaticPad(“<padname>”)) and call AddProbe like above on that pad. You will be able to intercept the dataflow, meaning Buffers and Events. The event you need to detect the end of the stream is EOS, aka End Of Stream. (not to confuse with the io.EOF error from go!)
You should be able to put the probes in front of the decodebin, before demuxing. That lets you watch only one pad, if that makes it more convenient. The EOS should appear nonetheless.