RTP livestream to browser using FFMPEG/nginx - nginx

I have a streaming transcoder which converts a high bandwidth fiber stream to a multicast RTP stream. I want to be able to show this stream to a client in a browser. There are 2 issues if I understand correctly:
The client most likely does not support multicast over his network
RTP cannot be played in a browser, so this needs to be converted to another format
What I have done so far (using FFMPEG):
Method 1: copy the stream to a .m3u8 without muxing, then hosting it with a Webserver (Nginx)
ffmpeg -protocol_whitelist file,udp,rtp -i ./stream.sdp -c:v copy -c:a copy -bufsize 50k -flags -global_header -hls_time 1 -f hls -hls_playlist_type event -hls_list_size 3 ./video/stream.m3u8
Method 2: enable HLS on Nginx and convert the stream to RTMP
ffmpeg -protocol_whitelist file,udp,rtp -i ./stream.sdp -vcodec libx264 -vprofile baseline -acodec aac -strict -2 -f flv rtmp://localhost/show/stream
Both of these methods result in a working livestream, but the delay remains around 5 seconds.
Is there any way to make the livestream faster? The multicast livestream has around a 1 second delay at max.

Both of these methods result in a working livestream, but the delay remains around 5 seconds.
Thats actually really good for HLS. Yes, there are ways to be faster within things Luke WebRTC and CTE. But nothing standard, You would have to develop the player and a chunk of infrastructure yourself.

Related

ffmpeg and nginx - restream with audio reencoding

I use nginx and ffmpeg to restream video from my provider. Previously I use ffmpeg with arguments where I reencoding video and reencoding audio, because my server is to slow I resigned from reencoding.
So now, I use that command :
ffmpeg -re -i http://link.somelink.com:6565/21d12d1/17233 -map 0 -c copy -bsf:a aac_adtstoasc -f flv -flvflags no_duration_filesize rtmp://test_ip/canal/stream
This works only when my provider streaming with aac audio codec, but sometimes my provider change audio codec to ac3. And then this doesn't work. I try something like this :
ffmpeg -thread_queue_size 32768 -re -i http://link.somelink.com:6565/21d12d1/17233 -c:v copy -c:a aac -f flv -flvflags no_duration_filesize rtmp://test_ip/canal/stream
And it all looks like it's all right in console with ffmpeg, but my restreaming video doesn't work. Ngnix throws 304 exception sometime.
Any suggestions?
Please help,
It's very important for me...
Ac3 is not in supported codecs list. You should encode your stream accordingly.
RTMP supports only a limited number of codecs. The most popular RTMP video codecs are H264, Sorenson-H263 (aka flv) and audio codecs AAC, MP3, Nellymoser, Speex. If your video is encoded with these codecs (the most common pair is H264/AAC) then you do not need any conversion. Otherwise you need to convert video to one of supported codecs.
https://github.com/arut/nginx-rtmp-module/wiki/Getting-started-with-nginx-rtmp

ffmpeg or vlc playlist to rtmp stream?

So, I've read all the articles here and unfortunately I can't seem to find the answers I'm looking for. I've gotten close, but the certain magic strings allude me.
I'm running hls live streaming (nginx) on ubuntu 17.10 server. In short, I can get the server running one video at a time fine with ffmpeg (with subtitles) using the following:
ffmpeg -re -i "1.mkv" -vcodec libx264 -vprofile baseline -g 30 -b:v 1000k -s 852x480 -acodec aac -strict -2 -b:a 192k -ac 2 -vf subtitles=1.srt -f flv rtmp://localhost:1935/show/stream
Though, I cannot find a solution to run a playlist using this method. It seems impossible, and when I try vlc via sout (internally, or externally) I reveive either buffer problems, or the aac experimental codec error:
[aac # 0xb162e900] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.
Example string that spits that error:
vlc "1.mkv" --sout '#transcode{soverlay,vb=1000,vcodec=h264,width=853,height=480,acodec=mp4a,ab=128,channels=2,samplerate=44100}:std{access=rtmp,mux=ffmpeg{mux=flv},dst=rtmp://localhost:1935/show/stream}'
Every other audio codec doesn't work with flv. I'm at a loss, I've tried almost every combination I could think of and digout just to get to this point. The best functioning out of them has been ffmpeg: it doesn't buffer video at all, plays smoothly, but just can't play a playlist. Whereas vlc can play a playlist but buffers, and has no sound (internally). I've tried aenc=ffmpeg{strict=-2}, batch pipes, etc, etc. I need help. Nothing works. Is there any solution? All I want is to run a playlist of 25 videos, all different variations, on a loop to the m3u8 for embedding.
A friend of mine mentioned he used bash scripts to have a seamless playlist like viewing feature. Hopefully that points you in the direction you need. I can try digging them up if you want to work together on this, coz I too am interested in finding out more about it.

FFmpeg -> JSMpeg Websocket Closes Repeatedly

I'm trying to create a fairly simple streaming server/site. Here's the current flow:
OBS streams to an RTMP URL
Nginx accepts the RTMP stream and uses exec-push to have FFmpeg pick up the stream and transcode it
FFmpeg transcodes the stream and outputs it to a JSMpeg application, which displays the stream on a webpage.
When I have my exec_push statement as follows, everything seems to work perfectly, except the browser says Possible garbage data. Skipping. on every frame it receives:
exec_push /usr/bin/ffmpeg -re -i rtmp://127.0.0.1:1935/$app/$name -f mpeg1video http://localhost:8080/supersecret;
This behavior is understandable, because JSMpeg must receive MPEG-TS data, not MPEG1 data. It sees the MPEG1 frames and thinks they're garbage.
So through some online research, I found this:
exec_push /usr/bin/ffmpeg -re -i rtmp://127.0.0.1:1935/$app/$name -c:v copy -c:a copy -f mpegts http://localhost:8080/supersecret;
Supposedly, this is supposed to transcode my RTMP stream into an MPEG-TS format, which should be compatible with JSMpeg.
However, with the second version of the command, my FFmpeg -> JSMpeg stream keeps connecting and disconnecting, connecting and disconnecting, and so on. This behavior is observed in terminal:
Stream Connected: ::1:40208
close
Stream Connected: ::1:40212
close
Stream Connected: ::1:40216
close
Stream Connected: ::1:40220
close
Stream Connected: ::1:40224
close
...
What would cause this? I am pretty certain the issue is in my exec_push command. OBS is perfectly content, which tells me that the stream is making it to the server, and if I do a push, I can do a test push to Ustream just fine, which tells me that Nginx is at least processing the stream with some reasonable degree of success.
Disclaimer: I have no idea what I'm talking about. Everything I know about FFmpeg and JSMpeg/Node is from snippets of code that I found online.
Answer credit goes to #Mulvya.
In the second exec_push command, the -c:v copy -c:a copy should not be there. By using that, there isn't any transcoding going on-- it's just a stream passthrough.
Removing the -c:v copy -c:a copy from the command and restarting Nginx yields a successful stream.

DirectShow stream using ffmpeg point to point streaming through TCP protocol

I had set up a point-to-point stream using ffmpeg via UDP protocol and the stream worked, but there was screen tearing etc. I already tried raising the buffer size, but it did not help. This is a work network, so the UDP protocol won't work.
here is the full command:
ffmpeg -f dshow -i video="UScreenCapture" -r 30 -vcodec mpeg4 -q 12 -f mpegts udp://192.168.1.220:1234?pkt_size=188?buffer_size=65535
I've tried to make this work with TCP with no success
Here's what i've got now:
ffmpeg -f dshow -i video="UScreenCapture" -f mpegts tcp://192.168.1.194:5555
this returns an error:
real-time buffer [UScreenCapture] [Video input] too full or near too
full <323% of size: 3041280 [rtbufsize parameter]>! frame dropped!
This last message repeated xxxx times (it went up to around 1400 and I just turned it off).
I've tried to implement the -rtbufsize paremeter and raising the buffsize up to 800000000, didn't help.
I would appreciate any suggestions on how to solve this.

Force ffmpeg to ignore error when connecting failed

I'm trying to deploy a live stream delivery system with nginx and nginx-rtmp-module.
For every node in my system, I wish it could 'forward' the live stream received to downstream node. I try to implement it by following config in my nginx.conf:
exec_push ffmpeg -i rtmp://localhost/src/test -vcodec copy -strict -2 -ar 44100 -ac 1 -f flv rtmp://<downstreaming A>/src/test -f flv rtmp://<downstreaming B>/src/test
it works when everything runs well, but if the downstream node is down, this command will exit and none of the downstream nodes could receive the live stream.
How could I force ffmpeg to ignore the connetion refused, or is there any better alternative to my implementation?
You cannot ignore connection refused since RTMP uses TCP which needs a connection.
If I understood correctly you're trying to transcode a RTMP source and send it to a number of servers.
You could duplicate your command to send to each downstream node
individually but you'll be doing the transcoding twice.
An alternative is to transcode and publish the transcoded stream using
ffserver on the same machine and then push to / pull on each downstream server

Resources