Rtmpsrc input detection

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?

I’m a bit confused about your setup and inputs (OBS? rtmpsrc?) Could you perhaps post some pipeline diagrams (SVGs or PNGs) from before/after?

Are you saying rtmpsrc does not send an EOS when the stream stops, but just stops sending data? Or does the server send a black image or?

(Apologies in advance if I’m completely misunderstanding the issue at hand)

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!)

See also Probes and Events

deleted - because it was completely wrong

I’ve got this “partly working”, so are these unsupported tags relevant?

0:05:26.046273136 65254 0x7f80ac002880 ERROR                   rtmp :0:: WriteN, RTMP send error 32 (42 bytes)
0:05:26.046321256 65254 0x7f80ac002880 ERROR                   rtmp :0:: RTMP_ReadPacket, failed to read RTMP packet body. len: 26639
0:05:26.599296454 65254 0x7f80ac002880 WARN                flvdemux gstflvdemux.c:2072:gst_flv_demux_parse_tag_type:<flvdemux0> unsupported tag type 70
0:06:25.829917677 65254 0x7f80ac002880 WARN                flvdemux gstflvdemux.c:2072:gst_flv_demux_parse_tag_type:<flvdemux0> unsupported tag type 196
0:08:25.851981071 65254 0x7f80ac002880 WARN                flvdemux gstflvdemux.c:2072:gst_flv_demux_parse_tag_type:<flvdemux0> unsupported tag type 81

Note: there are 2 queues - audio & video

Shouldn’t be critical. If it causes any issues consider posting an issue in the gitlab issue tracker though.

Note: there are 2 queues - audio & video

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.

With some help from CoPilot I got this working in a stand-alone test app, but making use of it reveals another problem to solve.

For my use case, RTMP is only one of many sources, so the pipeline must not be interrupted. The pipeline must run continuously.

The pipeline becomes blocked while rtmpsrc is sat waiting for someone to send. Is there a way to make it wait in the background?