Streaming RTMP to JANUS-Gateway only showing bitrate but no video - ffmpeg

I'm currently using the streaming plugin as follows
Fancy artchitecture here
OBS--------RTMP--------->NGINX-Server------FFMPEG(input RTMP output RTP)--------->JANUS---------webrtc-------->Client
When using the ffmpeg command (bellow), on the Janus streaming interface, we only see the bitrate that corresponds to that of the ffmpeg output in the console but we don't see any video.
ffmpeg -i rtmp://localhost/live/test -an -c:v copy -flags global_header -bsf dump_extra -f rtp rtp://localhost:8004
(using "-c:v copy" so that no encoding is used and hence reducing the
latency)
The video shows fine if I use "-c:v libx264", the only issue is that it is CPU intensive and adds latency.
Previously I had tried using RTSP as input for FFMPEG and in this case the video show fine with almost no latency even though I use "-c:v copy".
So I don't realy get why for RTSP the copy works fine, but for RTMP I have to use the libx264 codec. If anyone has an idea about this I am all ears :)

I had similar issue and my problem was that the stream / video that I used has large GOP size.
For WebRTC, latency is sub-second, so the input source should have short interval I frames. Better to remove B frames since they referring backward and forward as well.
Here are commands that you could use for small GOP size (4) and remove B frames.
Using RTMP streaming src:
ffmpeg rtmp://<your_src> -c:v libx264 -g 4 -bf 0 -f rtp -an rtp://<your_dst>
Using a mp4 file:
ffmpeg -re -i test.mp4 -c:v libx264 -g 4 -bf 0 -f rtp -an rtp://<your_dst>
-c:v copy does not reduce latency. It merely tells ffmpeg not to transcode.

Related

Force ffmpeg to quit when input resolution changes

I'm using ffmpeg to restream a live feed. Unfortunately occasionally the input resolution changes but ffmpeg continues running. The nginx rtmp server I'm using doesn't cope well with this, and continues the stream with audio, but the video is mostly black or green with some artifacts.
Ideally what I want to happen is for ffmpeg to stop on an input resolution change, as I have a script that detects ffmpeg stopping and will restart it again.
I'm using -c:v copy in my ffmpeg command as unfortunately my machine is not powerful enough to re-encode the live video on the fly to a constant resolution (not without a significant quality reduction at least)
ffmpeg -i "http://mpegts-live-stream" -c:v copy -c:a aac -ac 2 -f flv "rtmp://nginxserver/live/streamname"
So, ffmpeg can't detect input parameter change during streamcopy but we can work around that by adding a minimal decoding load to the process.
ffmpeg -xerror -skip_frame:v nokey -flags:v +drop_changed -i "http://mpegts-live-stream" -c:v copy -c:a aac -ac 2 -f flv "rtmp://nginxserver/live/streamname" -an -f null -
-xerror : exits upon error
-skip_frame:v nokey : only decodes keyframes of video stream
-flags:v +drop_changed : drops frame and signals error when parameters (like resolution) change
-an -f null - : maps a video output stream which needs a decoded stream, needed else no decoding will occur.

Is it possible to stream MJPEG content over MPEG-DASH?

I am trying to re-stream an MJPEG stream over dash using ffmpeg.
I have an ESP32 camera module that outputs an MJPEG livestream at 192.168.2.128:81/stream (Arduino code here).
I can open this stream directly in the browser and see the video in realtime, but the camera will only allow for a single client at a time while I am in need of a multi client solution.
What doesn't work
A solution I am currently trying to implement is to use a seperate server (Raspberry Pi) running apache and ffmpeg to re-stream the MJPEG content using DASH:
ffmpeg -re -i http://192.168.2.128:81/stream -strict -2 -an -c:v copy -b:v 2000k -f dash -window_size 4 -extra_window_size 0 -min_seg_duration 2000000 -remove_at_exit 1 /var/www/html/out.mpd
I get no errors when executing this command on the server.
I then use this ffmpeg-dash.html to display the video in the browser.
This code unfortunately fails, in Firefox the console reports the error:
[72][Stream] No streams to play.
followed by:
Cannot play media. No decoders for requested formats: video/mp4;codecs="mp4v.6c";width="640";height="480"
What does work
What is puzzling me is that the above code works fine if I replace the MJPEG livestream url with a sample .mkv file, so if I use
ffmpeg -re -i /var/www/html/video.mkv -strict -2 -an -c:v copy -b:v 2000k -f dash -window_size 4 -extra_window_size 0 -min_seg_duration 2000000 -remove_at_exit 1 /var/www/html/out.mpd
I can view the livestreamed sample video (video.mkv) without problems using the previously mentioned ffmpeg-dash.html file.
Furthermore, it seems that ffmpeg can read the MJPEG livestream without problems, since
ffmpeg -t 10 -i http://192.168.2.128:81/stream -filter:v fps=15 -c:v flv test.flv
returns a 10 second clip of the livestream succesfully.
So to me it seems that the problem lies in how I combine the two. What am I missing? Is it even possible to stream MJPEG content over MPEG-DASH?
(I am new to this, sorry in advance for my ignorance)

FFMPEG reduce fps for live h264 stream with direct copy

I found different articles on changing the fps with ffmpeg but none of them is matching for my exact purposes.
There is an ffmpeg command like below:
ffmpeg -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4
This will remux my camerastream to fragmented mp4 perfectly.
Is there a way to force ffmpeg to lower the FPS to save bandwidth?
I.e. camera streams 30fps, it needs 1Mbps for fmp4 (sample numbers!):
I'd like to know if it's possible to lower the FPS and get an output stream for which 500kbps (50% of original is enough) without re-encoding.
ffmpeg -r 1 -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -f mp4
and
ffmpeg -i RTSPCAMERAPRODUCEH264 -c:v copy -an -movflags +frag_keyframe+empty_moov -r 1 -f mp4
do not seem to work.
A temporally coded video stream (like one with H264 codec) cannot arbitrarily drop intermediate packets, so this is not possible. Only whole or trailing part of GOPs may be dropped.

FFMPEG screen capture outputting very poor and inconsistent framerate as webm with no audio

I've been testing different parameters to capture my desktop video and audio (desktop audio, not mic) and I find that no matter what settings I have, the resulting webm file's framerate is around 5fps and is horribly inconsistent. It starts at around 20fps and slowly drops over time until about 4-5fps. I'm not really sure what I'm doing wrong, but here is the basic command I'm using:
ffmpeg -y -video_size 1920x1080 -f gdigrab -framerate 60 -i desktop -c:v libvpx-vp9 -acodec libvorbis -c:a libopus -b:v 2M -threads 4 output.webm
I've tried anywhere between 30-60 fps and tested different bitrates but nothing seems to affect the output framerate.
Also, I know that acodec and c:a are for audio but I'm not sure how to specify the audio device to use.
So my issues are horrible framerate for webm and how to include desktop audio in the recording.
You can use arecord and pipe it through stdout and ffmpeg can read it from stdin.
aplay piping to arecord using a file instead of stdin and stdout
Replacing the aplay command with your ffmpeg. Dont forget to add '-i -' in ffmpeg.
A doubt: why are you defining audio encoder two times?
It's impossible to say why the video frame rate is low from the question. It can be an issue with encoder. Or issue in reading input. Remove the video encoding option. See if the issue persists. If it's working fine, try some other encoders.
Use -c:v libx264 instead of -c:v libvpx-vp9. libvpx-vp9's realtime encoding quality is really bad, even regular libvpx (i.e. VP8) is much better. If you insist on using libvpx, use options like -deadline realtime and -cpu-used -4

How add scale in my ffmpeg command

i want convert video from any format to mp4. so i am using command:
ffmpeg -i ttt.mp4 -vcodec copy -acodec copy test.mp4
this is working perftectly but now i also add scale in this -s 320:240.
There also many other command for convert LIKE :
ffmpeg -i inputfile.avi -s 320x240 outputfile.avi
but after convert by this command video not play in html5 player
BUT this is not working so tell me in my command how i add scale;
So please provide me solution for this .
Thanks in advance.
You have several problems:
In your command, you have -vcodec copy you cannot scale video without reencoding.
In the command you randomly found on the Internet, they are using AVI, which is not HTML5-compatible.
What you should do is:
ffmpeg -i INPUT -s 320x240 -acodec copy OUT.mp4
Adding to Timothy_G:
Video copy will ignore the video filter chain of ffmpeg, so no scaling is available (man ffmpeg is a great source of information that you will not find on Google). Notice that once you start decoding-filtering-encoding (i.e., no copy) the process will be much slower (x100 time slower or even more). The libx264 is recommended if you want compatibility with all browsers.
$ ffmpeg -i INPUT -s 320x240 -threads 4 -c:a copy -c:v libx264 OUT.mp4
vp9 will provide nearly 50% extra bandwidth saving, but only for supported browsers (Firefox/Chrome), and the encoding will much slower compared to libx264 (that itself is much slower that v:c copy):
$ ffmpeg -i INPUT -s 320x240 -c:a copy -c:v vp9 OUT.webm
Notice that there is a set of formats (containers) accepted by browsers (most admit mp4, some also webm, ...) and for each format there is a set of audio/video codecs accepted. For example you can use mp3 or aac with an mp4 file (container), but not with webm files.
http://en.wikipedia.org/wiki/HTML5_video#Supported_video_formats

Resources