mediamtx icon indicating copy to clipboard operation
mediamtx copied to clipboard

Allow a stream to be delayed for a specified number of seconds

Open rmwiseman opened this issue 3 years ago • 4 comments

Describe the feature

I can envisage situations where it would be useful to be able to delay an RTSP stream:

  • Perhaps a live stream needs to be delayed for safety/security reasons.
  • Perhaps recording needs to be triggered when something happens, but the previous X seconds of footage leading up to the trigger is required for the recording.

I'd therefore like to specify a delay for a given path, if possible.

I accept that this likely isn't simply a case of feeding the RTSP stream into a fixed size FIFO buffer it is processed by the server, so I'll understand if it's too large a feature to implement any time soon. (That said, if it's possible to estimate the required FIFO buffer size for the stream and the requested delay, I would be happy with the actual delay being only approximately what was requested!)

rmwiseman avatar Jan 05 '22 14:01 rmwiseman

Hello, you can already perform this with ffmpeg:

ffmpeg -i rtsp://original-source -vf tpad=start_duration=5 -f rtsp rtsp://new-delayed-source

aler9 avatar Jan 25 '22 14:01 aler9

Thanks for the tip! :-)

I've had some issues with this approach, unfortunately. I tried this yesterday and it seemed to work perfectly, but then when I tried it again later on the same machine, it didn't work!?

Now my ffmpeg's output is:

[rtsp @ 0x561ecbabc9c0] method SETUP failed: 461 Unsupported Transport
[AVFilterGraph @ 0x561ecbc30d60] No such filter: 'tpad'
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0

It definitely worked on the same machine earlier, so I don't know what's going on there. I've tried it on my laptop (sending the stream to the the server on the other machine) and that works, although the 5s delay is actually only 2 or 3 seconds.

Also, I didn't realise that using the delay would mean I couldn't use -vcodec copy so the stream has to be re-encoded, inevitably losing quality and increasing processor usage.

So whilst I can probably use this as a workaround (if I can ever get my server's ffmpeg to remember that it knows what tpad is!), it might not be sustainable in the long-term.


UPDATE: I've just tried using tpad=start_delay=60 for a 60 second delay, and (a) the delay is only about 7 seconds and (b) the output is not at all smooth, missing lots of frames and jumping backwards and forwards! So perhaps this might not be a feasible workaround after all.

rmwiseman avatar Jan 26 '22 08:01 rmwiseman

You can merge this and this, adding a time.Sleep(5 * time.Second) in between and you can do the job without re-encoding.

aler9 avatar Jan 27 '22 22:01 aler9

Thanks, I'll give that a go (if you'll excuse the pun).

UPDATE: I've been looking through the code and unfortunately, I'm not sure quite how to merge those two chunks of code. I think I'm nearly there, but I can't work out how to get the SPS & PPS from the read client. I am assuming I don't want to be listening on localhost:9000 because the RTSP stream isn't being pushed to me, I'm getting it from elsewhere...

rmwiseman avatar Jan 28 '22 13:01 rmwiseman

This feature can be achieved by using GStreamer or FFmpeg inside runOnReady, as mentioned in the README section about remuxing. For instance, in order to add a 5 seconds delay to a H264 stream:

paths:
  my_camera:
    source: rtsp://my-original-source
    runOnReady: >
      gst-launch-1.0 rtspsrc location=rtsp://127.0.0.1:8554/$MTX_PATH latency=0
      ! rtph264depay
      ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=5000000000
      ! rtspclientsink location=rtsp://127.0.0.1:8554/$MTX_PATH_delayed

The delayed stream will be available in path /my_camera_delayed.

Native support won't be developed.

aler9 avatar Jan 09 '24 12:01 aler9