I'm trying to restream with ffmpeg. I don't care if it will be mjpeg or whatever else, as long as it will be playable in modern browsers. But latency is critical, it would be great to have <5 sec delay added.
I was trying to make hls stream, then gave up and tried mjpeg.So far I came up with something like this:
ffmpeg -i input -an -c:v libx264 -crf 21 -preset veryfast -fflags nobuffer -flags low_delay -f hls -hls_time 6 -hls_list_size 10 -hls_flags delete_segments restreamed.m3u8
(I have this outputing to folder which is server via nginx, so I could test if I can play the stream in browser or vlc)
The main issue with this is that the m38u file is always missing the last segment: ffmpeg creates restreamed0.ts, there is no m3u8 file. After given time, the (restreamed)0.ts is done, and it starts another chunk 1.ts. At this point, m3u8 is created, but it only has 0.ts in it. When the 1.ts if finished, another chunk 2.ts is started, and the 1.ts is written to the m3u8 file, and so on. This obviously creates the delay of the length of one segment, which is too much.
I tried tweaking with the
-hls_list_size parameters and other flags I came across while Googling, but without any success. I've been trying to get this working for two days and it this point, I've completely lost track of what doesn't work at all, and what is somewhat working (usually it either takes insanely long for vlc to start playing the stream, or there is a huge delay, but I had no success creating perfect stream). I'm totally lost and I would appreciate some help.
I then gave up ad tried doing mjpeg stream, but it ended similar. My best result is this:
ffmpeg -i input -vcodec mjpeg -f segment -segment_time 10 -segment_list video.m3u8 -max_delay 0 out%d.mjpg
Input #0, mpjpeg, from '...': Duration: N/A, bitrate: N/A Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x480, 25 tbr, 25 tbn, 25 tbc Stream mapping: Stream #0:0 -> #0:0 (mjpeg (native) -> mjpeg (native)) Press [q] to stop, [?] for help [segment @ 0x1d62900] Opening 'out0.mjpg' for writing Output #0, segment, to 'out%d.mjpg': Metadata: encoder : Lavf58.20.100 Stream #0:0: Video: mjpeg, yuvj420p(pc), 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc Metadata: encoder : Lavc58.35.100 mjpeg Side data: cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1 [segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.403x [segment @ 0x1d62900] Opening 'out1.mjpg' for writing [segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x [segment @ 0x1d62900] Opening 'out2.mjpg' for writing [segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x [segment @ 0x1d62900] Opening 'out3.mjpg' for writing [segment @ 0x1d62900] Opening 'video.m3u8.tmp' for writingte=N/A speed=0.401x
I had no success loading that m3u8 file in vlc or in bowser (html video element). (However, if I try to play one of the .mjpg files, it's working as expected (except it plays faster, but I think that's caused by the source stream being 10fps, I can deal with this later)). The m3u8 file looks like this:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-ALLOW-CACHE:YES #EXT-X-TARGETDURATION:10 #EXTINF:10.000000, out0.mjpg #EXTINF:10.000000, out1.mjpg #EXTINF:10.000000, out2.mjpg
and apart from not being able to play it in vlc, neither in browser (I tried solutions offered in this question), it's always missing the last segment.
Could you please tell me what I'm doing wrong or point me in the right direction?