I'm using an ffmpeg script (in Windows) that extracts all the keyframes from a video and pastes them into a folder. I've made sure that my drive speed, CPU, and RAM are not causing a bottleneck.
The quality of the video is actually not important at all in this case. I need to encode the video that the script extracts frames from so that it has the fastest possible decoding speed. File size and quality are not important, only read speed. The video does not have audio. What would work best for me?
If it matters, here's the script I'm working with:
ffmpeg -i input.mp4 -vf "select=eq(pict_type\,I)" -vsync 1 %%3d.bmp
Sorry if sound like I don't know what I'm talking about, this is not a topic I am super familiar with. I appreciate your help!
The below will be much faster for a codec like H.264
ffmpeg -discard nokey -i input.mp4 -vsync 0 %%3d.bmp
Your present approach decodes all frames and then the select filter gets to do gating, but the above command discards everything but keyframes at the demuxer level. It only works with MP4/MOV like containers.
Related
I am wondering when I convert a .mp4 to .mkv using the following command if the quality changes.
ffmpeg -i in.mp4 out.mkv
The input file, in.mp4 has a file size of 297 megabytes, while the out.mkv file has a size of 249 megabytes, ~15% lower. Upon manual inspection, the resolution, video, and audio streams are the same before/after (as I would have expected given my (limited) knowledge of ffmpeg).
Is the 15% size decrease by simply converting to mkv actually not affect the quality of the video? If so this seems like a very reasonable way of freeing up some space on my computer.
The quality gets worse
This is due to generation loss because you are re-encoding the video and audio to lossy formats. But you may not notice the difference.
The output file size will vary depending on the input format, if it was encoded well or badly, your output format, and the settings you use.
MP4 to MKV without quality loss
You can just re-mux and avoid re-encoding by using stream copy mode:
ffmpeg -i input.mp4 -c copy output.mkv
You can think of it like a copy and paste. The video and audio is untouched and just put into a new container.
I frequently deal with .mp4 footage files which are game recordings from my computer. Because I'm dealing with a laggy game I end up with footage that has both duplicate frames and a variable frame rate. I want to cut out lagspikes from my video, lagspikes that can have the form of variable frame rates and/or duplicate frames. The end goal is to have video with a constant frame rate and no more lagspikes.
I'm well aware that this will destroy or at least damage the audio, but keeping the audio intact is not necessary for my application.
I have come across the mpdecimate filter for FFmpeg. As far as I have seen this is able to remove duplicate frames, however it does this in a way that does not make the output file a shorter video, but it introduces more variable frame rate.
Is it possible to reach my goal with FFmpeg? And if so, how?
Thanks in advance for help!
ffmpeg -i input.mp4 -vf mpdecimate,setpts=N/FRAME_RATE/TB out.mp4
as Gyan showed in a comment on my original question, this is the solution. Works like a charm, thanks a lot!
(FRAME_RATE can be replaced with a number if you wish to have a set framerate)
First, I have looked at the older questions asking the same, but the responses do not work.
Adding -r 30 or 60 to the input file does not impact the output, nor does setting it for the output, which remains unchanged.
I am handling a very large number of files from 1 to 22 gigs recorded (with audio) in 30fps that need to be re-posted as 60pfs, with the corresponding speed increase.
I toyed with ffmpeg a bit and came up with this..
-filter_complex "[0:v]setpts=0.50*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" -vcodec:v libx264
It works fine, but to have to wait out a complete re-encoding of the video and audio to produce the same video with the fps changed seems like an insane waste of time.
Am I missing something simple? Is there not a way to -c copy with a new fps playback rate on the resulting file?
(if it still has to recode the audio to maintain sync that's fine, audio is quick enough it doesn't much matter)
I'm trying to play some videos (webm mostly) on some very-low performance hardware. The hardware can barely handle FullHD output.
Since the devices in question are online via 3G modem only, there is some weight on the video size as well. However right now, the playing performance is definitely the more important part.
So, here's the question: Are there any options for avconv to improve playback performance? Or should I simply use another codec instead?
Right now, the command used is something like the following:
avconv \
-i $input_file \
-y \
-vf scale=$scale \
-an \
$output_file
You would want to use ffmpeg instead of avconv (ffmpeg is more active and reliable - my opinion):
Compile ffmpeg with libvpx support (WebM): guide
I would suggest you use CBR encoding
Set --profile to 3: guide, read about some more options if you want
Generally you would want to lower frame resolution and frame per second as much as acceptable for your project requirement and throw the appropriate bitrate for it.
There is an approach that you can try, that is to shrink the video twice in hight while leaving the width alone:
$ avconv -i 01.webm -vf 'scale=w=iw:h=ih/2' -c:v libtheora -c:a copy 01.ogv
for me has produced a file 84% the size of
$ avconv -i 01.webm -c:v libtheora -c:a copy 01.ogv
This way is much better than scalink in width, because it does not damage the text that may appear on the screen quite as much (human brain can for whatever reason deal with vertical distortion easier than with horizontal one).
You can also apply the denoise filter hqdn3d, which will make the filesize smaller, but will not damage the quality of the video.
The load on the processor of the playing machine can sometimes be more difficult to predict when one goes from video to video; but there is a difference in codecs. I've not compared them much, so can't offer real assistance.
Hey, I want to split a video which is one second long (25fps)into 25 seperate video files. I know I can split it up into jpegs but I need to retain the audio. So when I recompile audio is still there.
This is what I tried to grab the first frame only (with audio):
ffmpeg -i 1.mov -vcodec mjpeg -qscale 1 -an -ss 00:00:00:00 -t 00:00:00:1 frame1.mov
But it doesn't seem to work. Am I wrong in assuming ffmpeg supports time stamps in this format? hh:mm:ss:f?
Thanks
You are wrong in assuming ffmpeg supports timestamps in that format, but that's not the only problem
ffmpeg does not support the time format you're using. Options are either the time in seconds, or hh:mm:ss[.xxx] (two colons and a dot instead of three colons).
Your example code specifically strips the audio. That's what -an does.
Splitting by time when you actually want frames is not a great idea. Though since the audio frames are unlikely to match 1:1 with the video frames, it might be the best option.
Most importantly, most video and audio codecs are lossy and thus do not take well to being broken up into lots of pieces and then put back together. To do this without horribly mangling the quality, you need to first convert both video and audio into raw formats, manipulate those, and then re-transcode to compressed formats once you've done whatever you want to do with the pieces. You'll still lose some quality, but not as much as otherwise.