get consistent 60fps while recording X screen with ffmpeg - ffmpeg

I wrote the following script to record an X screen for a specified amount of time, to make sure that it's lossless I've separated it into two steps
record for the specified amount in a codec that requires almost no compression (so there's no overhead that might cause frames to be dropped)
re-encode the original video into HEVC to make the filesize significantly smaller
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -vsync 1 -f x11grab -probesize 128M -s 1920x1080 -r 60 -i :0.0 -qscale 0 -vcodec huffyuv -t 00:01:13 "$video.avi" # record the screen losslessly
ffmpeg -hwaccel cuvid -vsync 1 -i "$video.avi" -map 0:0 -c:v:0 hevc_nvenc -crf 23 -preset medium "$video-clean.mp4"
This works just like I expect it to some of the time, but very often it drops a lot of frames (I've seen as many as 10000 frames dropped on occasion)
The gpu is a 1080 TI that's being used just for rendering an X server with a chrome window and recording it, according to nvidia-smi the usage never goes to higher than 50% even in the most extreme cases.
I don't know what else to try, I thought about using a ramdisk to write the file to as it might be an IO problem, but ffmpeg refuses to write to tmpfs (for some reason I can't explain)

Solved it, recording to a tmpfs turned out to be the solution for me, however because I was using the snap version of ffmpeg I couldn't directly write to ram (because of permission issues), so I just compiled ffmpeg myself (needed support for cuda, and since this script runs on an ubuntu-based machine and the apt version of ffmpeg doesn't have access to cuda for some specific encoders I just compiled ffmpeg myself)

Related

FFmpeg randomly stopping during encoding. No error given

I recently upgraded to Windows 11, just in case that matters, and I went to encode a series of images into a video with FFmpeg like I usually would. For some reason seemingly randomly it just stops. No error is given, the frame that it stops on is random, the amount of time it's encoding for is random, and starting from a different frame doesn't change anything.
Here is the code I'm using:
ffmpeg -r 59.94 -f image2 -start_number 0 -i "%06d.png" -vcodec libx265 -crf 18 -preset medium -tune grain -pix_fmt yuv420p10le "Encode/S2005E14.mp4"
The version of ffmpeg I'm using is the newest git-full version from https://www.gyan.dev/ffmpeg/builds/
The CPU being used to encode it is a Ryzen 3900x.
Log: https://pastebin.com/EnyWs7cL
The problem was caused by an unstable overclock. After reducing the overclock everything worked normally.

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

FFMPEG PERFORMING VERY SLOW

I'm trying to setup a media processing server. I've done a lot of research for FFMPEG and wrote a command. The command is as follows.
ffmpeg -y -i "bbb_sunflower_2160p_60fps_normal.mp4" -c:v libx264 \
-threads 7 -profile:v main -preset ultrafast -vf scale=1920:-1 \
"process/video/1080p.mp4" -c:v libx264 -threads 7 -profile:v main \
-preset ultrafast -vf scale=1280:-1 "process/video/720p.mp4" -c:v \
libx264 -threads 7 -profile:v main -preset ultrafast -vf \
scale=854:-1 "process/video/480p.mp4" -vf fps=5/60 \
process/image/thumb_%d.jpg
This command works and runs perfectly, but it is dirt slow. My server, which is dedicated to just running ffmpeg has the following specs:
12 core intel Xeon X5650 (Hyperthreading enabled)
64 GB ECC DDR3 RAM
250 GB SSD Drive
But when I use this command, the server CPU load hangs around 250-300%, which I would like it to hang around 2,000% while processing the video. Currently when processing the video, the server is rendering around 17 frames per second. This would take a very long time to process a 10 minute video that's 60fps.
It's the scaler. The scaler in ffmpeg is single threaded, it is a bottleneck on a system with that many threads. Try running a different process for each output.
If you are running windows, try again with defender (and any other virus checker) disabled. It can make a huge difference.
Let us know the outcome please...
This worked for me on a windows 10 machine (which then processed up to ten times faster ) and is therefore a possible answer to the above problem. Clarification (of any sort) is not requested, but it would be good to know if it helped.
This is a very complicated commandline with little to no useful information. For example, you're not providing FFmpeg stdout/stderr (which contains lots of useful information). Possible causes:
video encoding is simply too slow (try 1 encode instead of 3, w/o screenshots)
maybe your bottleneck is audio (test with -an)
something else?
I'd encourage you to test simpler versions and provide stdout/stderr.

x264: Encoded videos need lots of CPU to play

My computer (Intel Core 2 Duo T9300, 2.5GHz) can usually play any Full HD file, and Blu-Rays perfectly.
However, when I encode a Full HD file myself, the CPU is struggling and frames are dropped.
Here's my command line:
ffmpeg.exe -r 24 -f concat -i list_of_png_files.txt -i w:\audio.wav -acodec copy -c:v libx264 -preset medium -b:v 10000k -shortest output.avi
I tried adding -maxrate 13000k after "-preset medium". However, x264 doesn't seem to honor this - the framerate still reaches 20MBit at parts.
How can I encode videos in such a way as to reduce CPU usage during decoding?
There is an x264 tuning option for exactly this purpose. I believe -tune fastdecode is what you are looking for. But this will disable some compression features, so the video may not look as good without increasing the bitrate.

ffmpeg setting for HD and normal quality

Hello i need to have two versions of the same file stored on my server, medium and HD quality, the thing is that don't really know ffmpeg that well so im just trying this is code at random, i'm using the code belo but I end up with a much larger file, however it works,it plays.
ffmpeg -i inputfile.wmv -vcodec libx264 -ar 44100 -b 200 -ab 56 -crf 22 -s 360x288 -vpre medium -f flv tmp.flv
Just need the two commands to create the 2 different files
You need to give more information about what bitrate, quality or target file size you are aiming for and the size and quality of your source material preferably including codecs used and relevant parameters.
You should read the manual or ffmpeg -h or both. There are several problems with your command line:
You are using constant rate factor, crf = 22, while still trying to limit the bitrate using -b 200.
Bitrate is specified in bits/s (unless you are using a very old ffmpeg), and 200 bps is not usable for anything, add k to get kilobits/s.
You have not specified an audio codec, but you have specified an audio bitrate, ffmpeg will try to guess the audio codec for you but I don't know what codec is the default for .flv-files.
I'm assuming that the command line you posted is supposed to be for the 'medium' quality file.
Some suggestions that you can try:
Try this first: specify audio codec, e.g. -acodec libmp3lame, or if the audio is already in a good format you can just copy it without modification using -acodec copy
Try a different rate factor, e.g. -crf 30, higher numbers mean uglier picture quality, but also smaller file size.
Try a different encoder preset, e.g. -vpre slow, in general, the slower presets enable features that require more CPU cycles when encoding but results in a better picture quality, see x264 --fullhelp or this page to see what each preset contains.
Do a 2-pass encode, link.
If you don't want to read all the documentation for ffmpeg and the codec parameters that you need I suggest you look at this cheat sheet, although the command line switches have changed over the different versions of ffmpeg so the examples might not work.
An example command line:
ffmpeg -i inputfile.wmv -vcodec libx264 -crf 25 -s 360x288 -vpre veryslow -acodec libmp3lame -ar 44100 -ab 56k -f flv tmp.flv
The parameter -s [size] is the size of the output video, in pixels, for the HD file you probably want something around 1280x720, if your material is 5:4 ratio (as 360x288 is) you'll want to try 1280x1024, 960x768 or 900x720. Don't set a size larger than the source material as that will simply upscale the video and you will (probably) end up with a larger file without any noticeable improvement in quality. The -ab parameter is the audio bitrate, you'll probably want to increase this parameter on the HD version as well.

Resources