sergey-dryabzhinsky / nginx-rtmp-module

NGINX-based Media Streaming Server
http://nginx-rtmp.blogspot.com
BSD 2-Clause "Simplified" License
1.02k stars 217 forks source link

Stream with 30m delay: some sort of hidden buffer? #359

Closed Tralapo closed 11 months ago

Tralapo commented 1 year ago

This repo hasn't been very active lately, but I hope there are still some people hanging around here that can maybe help me or point me in the right direction.

TL;DR

I have securitycameras that I stream 24/7 live, but with a 30m delay because of reasons. Somehow though, this sometimes increases up to a 60m delay, although I can not find the raw footage on the server. How is this even possible?

Config

I created a workflow where, when nginx starts, it starts recording the camera and saves a .flv every 30m. I then rename that to just 'stream.flv' to create a source for continious streaming. If the buffer file does not exist at first, it will show a waiting screen. This workflow is based on my own issue #312 from a few years ago.

This works fine, apart from the fact the stream ends up anywhere between 30 up to 60 minutes behind. When I manually download the .flv file and play it, it's just the past 30 minutes. The footage that is shown through HLS at that moment, for example from 56 minutes ago, is not in there.

How is that even possible? Is there some kind of hidden tmp used by nginx/nginx-rtmp?

It's not because of unexpected restarts of nginx, because it also happens when it will be up and running for days.

Hope there's someone who knows where this strange behaviour comes from, or maybe knows a better way to do this.

nginx.conf

rtmp {
  server {

    application live {
        live on;
        record off;

        hls on;
        hls_path /mnt/hls;
        hls_fragment 5s;
        hls_playlist_length 30s;
        hls_continuous on;
        hls_nested off;
        hls_cleanup on;
        hls_fragment_naming system;
        hls_type live;

        allow publish 127.0.0.1;
        deny publish all;

    ## Stream with a 30m delay
    exec_static stream-30m.sh cam-1;
        exec_static stream-30m.sh cam-2;

    }

    application buffer-30 {
        live on;
        record video;
        record_path /recordings;
        record_suffix -%H%M.flv;
        record_append off;
        record_interval 30m;

        allow publish 127.0.0.1;
        allow play 127.0.0.1;
        deny publish all;
        deny play all;

    exec_static ffmpeg -i rtsp://1.2.3.4:1234/live -vcodec copy -f flv -an rtmp://localhost:1935/buffer-30/cam-1;
    exec_static ffmpeg -i rtsp://5.6.7.8:1234/live -vcodec copy -f flv -an rtmp://localhost:1935/buffer-30/cam-2;
    exec_record_done rename.sh $basename;

    }
  }
}

stream-30m.sh

#!/bin/bash

# Test if buffer is there
if test -f "/recordings/$1.flv"; then
        # If yes, start stream like normal
        /usr/bin/ffmpeg -i rtmp://localhost:1935/vod/$1.flv -vcodec copy -f flv rtmp://localhost:1935/live/$1;
else
        # Start waiting screen
        /usr/bin/ffmpeg -loop 1 -i buffer.jpg -vcodec libx264 -pix_fmt yuv420p -an -f flv rtmp://localhost:1935/live/$1 &

        # Save wainting screen PID
        BUFFER_PID=$!

        # Wait for buffer to build
        sleep 30m

        # Kill waiting screen
        kill $BUFFER_PID

        # Start actual stream, delayed
        /usr/bin/ffmpeg -i rtmp://localhost:1935/vod/$1.flv -vcodec copy -f flv rtmp://localhost:1935/live/$1;
fi

rename.sh

#!/bin/bash

# Catch stream name, delete -HHMM part from filename
CAM=$1
CAM_STRIPPED=${CAM::-5}

# Delete old .flv file just to be sure old footage does not stick around
rm /recordings/$CAM_STRIPPED.flv

# Rename new footage 
mv /recordings/$CAM.flv /recordings/$CAM_STRIPPED.flv

# Delete footage older than 60 minutes, just to keep everything clean in case of previous errors
/usr/bin/find /recordings/*.flv -type f -mmin +60 -delete
Tralapo commented 11 months ago

I "fixed" this by changing rename.sh so that it will now kill the active stream and start a new one with the just saved recording. This prevents the stream from running behind. Only thing is the videoplayer will always stop and the page has to be refreshed to get the new stream.