While ffmpeg is recording, I want it to create a smaller and lower quality video - ffmpeg

Currently I am using this...
ffmpeg -video_size 1920x1080 -framerate 1 -f x11grab -i :0.0+0,0 -f pulse -ac 2 -i default -t 00:00:10 Output.mkv
While ffmpeg is recording a video, I want it to significantly reduce both the size and quality compared to the ffmpeg command above.
In case you are curious, I am recording brief quality assurance videos to ensure a simple little web scraper I wrote in Python is scraping data properly (specifically, that it is clicking on a particular button, at a particular time, on a particular web page). My Python script triggers the command above to start recording my screen a few seconds before my Python script is supposed to click on that button.
Of course, to verify a button on a web page had been clicked on, low quality video resolution would normally suffice.

For libx264/libx265 the most important option to reduce both the size and quality is -crf. This option controls quality. A value of 51 provides the worst quality. If it's too terrible then use a lower number.
ffmpeg -video_size 1920x1080 -framerate 1 -f x11grab -i :0.0+0,0 -f pulse -channels 2 -i default -t 00:00:10 -c:v libx264 -crf 51 -c:a libopus Output.mkv
See FFmpeg Wiki: H.264.

For significantly reduce both the size and quality of Output.mkv you can use the next ffmpeg configuration:
crop: iw-(cut width in pixels):ih-(cut heigth in pixels)
scale: to set the ratio and resolution (example 1700x800)
crf: to set quality, where 0 is lossless, 23 is default, and 51 is worst possible. A lower value is a higher quality and a subjectively sane range is 18-28. Consider 18 to be visually lossless
bitrate value: -b:v value -minrate value and -maxrate max value (example -b:v 4000K -minrate 2000K -maxrate 6000K)
preset: in theory slow is best quality/size, and you can probe ultrafast
superfast
veryfast
faster
fast
medium – default preset
slow
slower
veryslow
Cut a part of video, changue the resolution, changue crf, and bitrate, first only video, then you can add audio in other work, dont mix, repeat, is very important, encoding/decoding audio and video separate, then you can mix all, but first the video like in this example
ffmpeg -i Output.mkv -map 0:v -vf crop=iw-150:ih-85,scale=ih*16/9:ih,scale=1072:732,setsar=1 -c:v libx264 -crf 17 -b:v 4000K -maxrate 6000K -bufsize 4M -movflags -faststart -preset veryfast -dn video-new.mkv

Related

Ffmpeg nvenc encoder on gpu does not compress files as much as compared to libx264

I wanted to encode a video file which was initially encoded by a libx264 encoder on a non gpu machine with ultrafast preset and crf 23 , i typically re-encode it with preset medium and get a good compression but the process is very slow , so i am considering a gpu based solution
my current command to use ffmpeg on a nvidia turing gpu
ffmpeg -y -vsync passthrough -hwaccel cuda -i a.mp4 -max_muxing_queue_size 9999 -pix_fmt yuv420p -c:v h264_nvenc -preset medium -tune ll -b:v 4M -bufsize 4M -maxrate 10M -qmin 0 b.mp4
usual command i use to do the same
ffmpeg -i a.mp4 -max_muxing_queue_size 9999 -pix_fmt yuv420p -c:v libx264 -preset medium b.mp4
enter code here
How can i make this command do a better job at reducing file size , i am okay to compromise on the quality of the video for a good reduction in size
I would highly recommend reading this H.264 Video Encoding Guide
On the surface, these variants can help you:
Decrease your bitrate
Add -cq option with suitable value 0-51 (-cq for h264_nvenc is pretty the same as -crf for libx264)
Change -tune option value to hq
Try two-pass encoding (if you know desired output file size), but here is very low benefit
If you struggle with available options for h264_nvenc you can see the whole list of them by executing following command:
ffmpeg -hide_banner -h encoder=h264_nvenc
Most of them are self descriptive or similar from libx264

How to use constrained/capped bit rate mode in FFmpeg

I used FFmpeg with this command to convert a video:
ffmpeg -i input -c:v libx264 -x264-params opencl=true -preset veryslow -crf 19 -maxrate 7000k -profile:v high -level 4.0 -bf 2 -coder 1 -pix_fmt yuv420p -c:a copy output.mkv
Note that I set -maxrate 7000k to set the maximum bit rate for the video. Still, the end result video has a maximum bit rate of 38.0 Mb/s.
Here are the results before (to the left) and after (to the right), if that helps.
Am I using maxrate properly? Should not the video be capped at 7000 kb/s?
maxrate is enforced via the bufsize option. No bufsize, no enforcement. See https://stackoverflow.com/a/33612662
The smaller the bufsize relative to maxrate, closer the actual peak bitrate to maxrate, but expect transient quality dips (if maxrate is too low for desired quality).
Start with
-maxrate 7000k -bufsize 7000k

FFMPEG, any video to 16:9

Help me find a command or script that will convert any video to 16:9, h264 and ~2500kbps. I have a server where people upload videos of different quality, size and length. It can be either 640x480 or 1216x2160. Ultimately, I need to get any resolution to 16:9 (with black borders, if needs) and bitrate without visible loss of quality, which will be acceptable for online broadcasting.
I have this command, but it does not check the resolution of the video. And if the video was 560x448 1000kbps and 700mb, then after conversion it will be 1280x720 3000kbps and 1.5gb, that's not right.
ffmpeg -i 5.avi -vcodec libx264 -crf 23 -preset veryfast -vf scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,setsar=1 -tune zerolatency highoutput.mp4
Please try the following as a starting point:
ffmpeg -i "5.avi" -vcodec libx264 -crf 23 -vf "scale=w=trunc(ih*dar/2)*2:h=trunc(ih/2)*2, setsar=1/1, scale=w=1920:h=1080:force_original_aspect_ratio=1, pad=w=1920:h=1080:x=(ow-iw)/2:y=(oh-ih)/2:color=#000000" "output.mp4"
Please tweak the crf value depending on the picture quality.
Use
-vf scale=iw*sar:ih,setsar=1,pad='max(iw+mod(iw,2),2*trunc(ih*16/9/2))':'max(ih+mod(ih,2),2*trunc(iw*9/16/2))':-1:-1

FFMPEG: Youtube streaming quality and speed issues

I am trying to make a reliable stream from my Icecast/Shoutcast servers to Youtube live. The command that I use is:
ffmpeg -v verbose -framerate 30 -loop 1 -i /var/image.jpg -re -i http://127.0.0.1:4700/radio -c:v libx264 -preset ultrafast -b:v 2250k -maxrate 6000k -bufsize 6000k -c:a copy -ab 128k -s 1920x1080 -framerate 30 -g 60 -keyint_min 60 -f flv rtmp://a.rtmp.youtube.com/live2/xxx
As you can see I am using recommended bitrate for Youtube, insert keyframes every 2 seconds and streaming at 30 frames per second.
The stream is working but after running for some time two thing are happening:
FFMPEG speed falls from 1x to something like 0.998x
Youtube starts complaining that video stream speed is slow, markes the quality as bad and sometimes video starts buffering.
Why is this happening? CPU load is normal, connectivity is ok (the stream is running on a 1Gg/s dedicated server).
Since in my example above I am streaming a single image as a logo of the stream I also tried to generate a short 30 seconds video with that image and broadcast that video instead of an image, but that did not help as well.
The command I used for conversion:
ffmpeg -framerate 30 -loop 1 -i /var/image.jpg -c:v libx264 -preset ultrafast -tune stillimage -b:v 2250k -minrate 2250k -maxrate 6000k -bufsize 6000k -framerate 30 -g 60 -keyint_min 60 -t 30 out4.mp4
And broadcast with
ffmpeg -stream_loop -1 -i out4.mp4 -re -i http://127.0.0.1:4700/radio -c:v copy -c:a copy -framerate 30 -g 60 -keyint_min 60 -f flv rtmp://a.rtmp.youtube.com/live2/xxx
ffmpeg version is 4.1.1
Are you sure that your original stream is really keeping up with the wall-clock?
Depending on how it's encoded there are possibilities that it gets heavily skewed. This ultimately leads to buffer under (or overruns if it's too fast) and the player complaining/skipping.
Can you try and dump several hours worth of stream to a file and then stream that with FFmpeg? If that works, then it's a strong indication that your original stream timing (sample rate) is off.
Getting the sample rate right is why professional/expensive sound cards use high precision Quartz-Crystal controlled oscillators. Purely virtual processing (e.g. files get encoded into a stream) can easily get skewed, especially inside virtual machines. Also, cheap USB sound cards are often among the worst offenders in terms of frequency accuracy and stability.
FFmpeg might have an option to deal with too slow input. Keywords could be 'padding' or 'missing samples'.
Youtube's error saying "...buffer....." is not a buffer issue on your PC, but simply data you are sending to youtube is too small.
1)note that [-preset ultrafast] and [-preset fast] does not make big difference.
2) change your ffmpeg comannd for broadcast one. like, [-b:v 2250k] to [-b:v 15000k],and set fps to 12→[-r 12] option.
I's gonna be.
ffmpeg -stream_loop -1 -i out4.mp4 -re -i http://127.0.0.1:4700/radio -preset fast -r 12 -framerate 30 -g 60 -video_track_timescale 1000 -b:v 15000k -f flv rtmp://a.rtmp.youtube.com/live2/xxx
I hope this will be good for you !!(^v^)Y

encoding jpeg as h264 video

I am using the following command to encode an AVI to an H264 video for use in an HTML5 video tag:
ffmpeg -y -i "test.avi" -vcodec libx264 -vpre slow -vpre baseline -g 30 "out.mp4"
And this works just fine. But I also want to create a placeholder video (long story) from a single still image, so I do this:
ffmpeg -y -i "test.jpg" -vcodec libx264 -vpre slow -vpre baseline -g 30 "out.mp4"
And this doesn't work. What gives?
EDIT: After trying LordNeckbeards answer, here is my full output: http://pastebin.com/axhKpkLx
Example for a 10 second output:
ffmpeg -loop 1 -framerate 24 -i input.jpg -c:v libx264 -preset slow -tune stillimage -crf 24 -vf format=yuv420p -t 10 -movflags +faststart output.mp4
Same thing but with audio. The output duration will match the input audio duration:
ffmpeg -loop 1 -framerate 24 -i input.jpg -i audio.mp3 -c:v libx264 -preset slow -tune stillimage -crf 24 -vf format=yuv420p -c:a aac -shortest -movflags +faststart output.mp4
-loop 1 loops the image input.
-framerate sets the frame rate of the image input. Default is 25. Some players have issues with low frame rates so a value over 6 or so is recommended.
-i input.jpg the input.
-c:v libx264 the H.264 video encoder.
-preset x264 encoding preset. Use the slowest one you can.
-tune x264 tuning for various adjustments to fit specific situations.
-crf for quality. A lower value results in higher quality. Use the highest value that still provides an acceptable quality to you. Default is 23.
-vf format=yuv420p outputs the pixel format as yuv420p. This ensures the output uses a widely acceptable chroma sub-sampling scheme. Recommended for libx264 when encoding from images.
-c:a aac the AAC audio encoder. If your input is already AAC or M4A then use -c:a copy instead to stream copy instead of re-encode.
-t 10 (in the first example) makes a 10 second output. Needed because the image is looping indefinitely.
-shortest (in the second example) makes the output the same duration as the shortest input. In this case it is the audio since the image is looping indefinitely.
-movflags +faststart relocates the moov atom to the beginning of the file after encoding is finished. Allows playback to begin faster in progressive download playing; otherwise the whole video must be downloaded before playing.
-profile:v main (optional) some devices can't handle High profile.
See FFmpeg Wiki: H.264 for more info.

Resources