convert raw video .y4m to mpg video with certain GOP - ffmpeg

I want to compress a raw video .y4m to mpg, and I want then to extract the frames from the mpg video, I need the GOP of the compression to be :IBBPBBPBBPBBPBBIBBP....15:2
I used this command:
ffmpeg -i video.ym4 -vcodec libx264 -sameq -y -r 30 output.avi 2>list.txt
ffmpeg -i output.avi -vcodec libx264 -y -sameq -vf showinfo -y -f image2 image%3d.jpeg -r 30 2>list1.txt
The output contains only 2 I frames, 100 P and 198 B frames, it is not 15:2 GOP, what to do?
I need one I-frame every 15 frames, and the pattern to b IBBPBBP..
Sorry, Im new to ffmpeg, please help me, this is the input to my project, it is the important step to me.

Try (according to http://ffmpeg.org/ffmpeg.html#Video-Encoders)
ffmpeg -i video.ym4 -vcodec libx264 -g 15 -y -r 30 output.avi
I think option -sameq (means "same quantizers") is not needed in your case.

Related

mp4 video written with ffmpeg has different first frame based on total number of frames

I'm trying to read and write videos using ffmpeg, and I got an interesting phenomenon where the first frame is not the same in videos I create that are made from the same frames, only with different lengths.
The commands I'm running to reproduce the problem:
ffmpeg -i <some_video>.mp4 -frames:v 20 -q:v 3 resource_images/00%04d.png
ffmpeg -hide_banner -loglevel error -framerate 30 -y -i resource_images/00%04d.png -c:v libx264 -pix_fmt yuv420p -frames:v 20 long_video.mp4 -y
ffmpeg -hide_banner -loglevel error -framerate 30 -y -i resource_images/00%04d.png -c:v libx264 -pix_fmt yuv420p -frames:v 10 short_video.mp4 -y
ffmpeg -i long_video.mp4 -vf "select=eq(n,0)" -q:v 3 long_frame0.png -y
ffmpeg -i short_video.mp4 -vf "select=eq(n,0)" -q:v 3 short_frame0.png -y
The images long_frame0.png and short_frame0.png are different (I loaded them using Python and compared them, there are many differences).
I find it very peculiar, since I create very short videos, it's those videos first frames, and they are keyframes of those videos (I checked it using ffprobe)
What is the cause of this issue and how do I overcome it to create a consistent first frame for a video, regardless of the video length?

FFMPEG changing output framerate issues

I want to take the input, blend N frames, decimate the other frames and use those for the output with the fps of my choice.
I used this line:
ffmpeg -y -i input.mp4 -vf tmix=frames=15:weights="1",select='not(mod(n\,15))' -vsync vfr frames/output-%05d.tif
That generated images, which I combined into the video. So far, so good.
But I'd like to skip the image output and go straight to video, so I tried this:
ffmpeg -y -i input.mp4 -vf tmix=frames=15:weights="1",select='not(mod(n\,15))' -vsync vfr -r 30 -c:v prores_ks -profile:v 3 -vendor apl0 -bits_per_mb 8000 -pix_fmt yuv422p10le output.mov
That produces 1.62 fps video, instead of 30 fps.
I'm at a loss on how to get it to output 30fps without the intermediate step of outputting images.
Thanks
I think the simplest way to achieve this is to feed the input at the 15-times the desired rate and drop all intermediate frames with -r 30:
ffmpeg -y -r 450 -i input.mp4 \
-vf tmix=frames=15:weights="1" \
-r 30 sandbox/out.mp4
However, a tmix solution is somewhat inefficient for your use case because it's mixing for all frames, including those dropped. If you don't mind a longer expression, you can try:
ffmpeg -i in.mp4 \
-vf
setpts=\'floor(N/15)/(30*TB)\',select=\'mod(n,15)+1\':n=15[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14];\
[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14]mix=inputs=15:weights=1 \
-r 30 sandbox/out.mp4
[edit] setpts expression should be floor(N/15)/(30*TB) not mod(n,15)+1 for 15 successive frames to have the same pts.

FFMPEG cannot encode video with high speed change

Hi I am trying to speed up and trim clips with FFMPEG version 4.2.2. Is there a limit to how fast you can speed up a clip? If I try to speed up a clip over a certain then the output file cannot be opened.
I have tried two methods without any luck: 1. using the setPTS filter and 2. inputing the file at a faster frame rate.
1.
ffmpeg -i GH012088.MP4 -y -ss 18 -t 0.48 -an -filter:v "setpts=0.096*PTS" -r 25 output.MP4
2.
ffmpeg -r 312.1875 -i GH012088.MP4 -y -ss 18 -t 0.48 -r 25 -an output.MP4
I am trying to create a clip from the input that starts at 1 second in the original clip, plays at 10.4166 x speed and lasts for 0.48 seconds
What am I doing wrong?
Thanks
Use
ffmpeg -ss 1 -i GH012088.MP4 -y -t 0.48 -an -filter:v "setpts=0.096*PTS" -r 25 output.MP4
The seek has to be on the input side, before frames are retimed. The -t has to be on output side, after frames are retimed.
Does the movie have sound?
If yes, than we have to sync speed up audio and video by combine filter:
ffmpeg -i video.avi -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" -f avi video1.avi

Fade out in ffmpeg when creating a video from a still image is wonky?

I'm creating a video that:
uses a still image as a source
has a text overlay
fades in and out
has a silent stereo audio track.
So far, I have this, and it (almost) works correctly:
ffmpeg -f lavfi -i "aevalsrc=0|0" -loop 1 -i turtle-2.jpg -c:v libx264 -t 5 -r 30 -s 1920x1080 -aspect 16:9 -pix_fmt yuv420p -filter:v drawtext="fontsize=130:fontfile=comic.ttf:text='hello world':x=(w-text_w)*.25:y=(h-text_h)*.75",fade=in:0:60,fade=out:90:60 -acodec aac turtle11.mp4
The only problem is that the fade out doesn't seem to be going to black, even tho this is a 150 frame video and I believe I am following the ffmpeg documentation correctly.
The resulting video is here:
http://video.blivenyc.com/vid-from-image/turtle11.mp4
Any thoughts?
Well, I'm not sure why but this works, even tho it appears to be equivalent:
ffmpeg -f lavfi -i "aevalsrc=0|0" -loop 1 -i turtle-2.jpg -c:v libx264 -t 5 -r 30 -s 1920x1080 -aspect 16:9 -pix_fmt yuv420p -filter:v drawtext="fontsize=130:fontfile=comic.ttf:text='hello world':x=(w-text_w)*.25:y=(h-text_h)*.75",fade=t=in:st=0:d=1,fade=t=out:st=4:d=1 -acodec aac turtle12.mp4
Basically, frame-based syntax:
fade=in:0:60,fade=out:90:60
gets substitued with time-based:
fade=t=in:st=0:d=1,fade=t=out:st=4:d=1
And somehow it works. Not sure why this is.
The video stream on which the fade filter operates is not 150 frames long. Input and output framerates are different here. The use of -r to set output rate happens after all filtering is done. At that stage, ffmpeg will drop or duplicate frames to obtain the output rate.
The input rate for an image or image sequence is 25, unless expressly set otherwise. In your command, since there is no override, it's 25. So fade out of 60 frames starting at frame 90, will end at frame 125 (5 seconds x 25). ffmpeg will duplicate 5 frames of each input second to get it to 30.
To get the desired result, use
ffmpeg -f lavfi -i "aevalsrc=0|0" -loop 1 -framerate 30 -i turtle-2.jpg -c:v libx264 -t 5 -s 1920x1080 -aspect 16:9 -pix_fmt yuv420p -filter:v drawtext="fontsize=130:fontfile=comic.ttf:text='hello world':x=(w-text_w)*.25:y=(h-text_h)*.75",fade=in:0:60,fade=out:90:60 -acodec aac turtle11.mp4

How to get better quality converting MP4 to WMV with ffmpeg?

I am converting MP4 files to WMV with these two rescaling commands:
ffmpeg -i test.mp4 -y -vf scale=-1:360 test1.wmv
ffmpeg -i test.mp4 -y -vf scale=-1:720 test2.wmv
I've also tried:
ffmpeg -g 1 -b 16000k -i test1.mp4 test1.wmv
However, the .wmv files that are produced are "blocky and grainy" as you can see here in a small section of a video screenshot:
These are the sizes:
test.mp4 - 106 MB
test1.wmv - 6 MB
test2.wmv - 16 MB
How can I increase the quality/size of the resulting .wmv files (the size of the .wmv files is of no concern)?
Consider the following command instead (some outdated commands in the final answer section):
ffmpeg -i test.mp4 -c:v wmv2 -b:v 1024k -c:a wmav2 -b:a 192k test1.wmv
REFERENCES
https://askubuntu.com/questions/352920/fastest-way-to-convert-videos-batch-or-single
You can simply use the -sameq parameter ("use same quantizer as source") which produces a much larger sized video file (227 MB) but with excellent quality.
ffmpeg -sameq -i test.mp4 -y -vf scale=-1:360 test1.wmv
In newer versions of ffmpeg flag '-sameq' has been removed. To achieve similar results one should use 'qscale' flag with 0 value:
ffmpeg -sameq -i test.mp4 -qscale 0 -vf scale=-1:360 test1.wmv
Working answer in 2020, producing an output video without blockiness:
ffmpeg -i input.mp4 -q:v 1 -q:a 1 output.wmv
One thing I discovered after many frustrating attempts of enhancing the final quality was that if you don't specify a bitrate, it'll use a quite low average. Try -b 1000k for a starting point, and experiment increasing or decreasing it until you reach the desired result. Your file will be quite bigger or smaller, accordingly.
I used this and it turned out quite well
ffmpeg -i "file1.mp4" -q:v 0 -c:v wmv2 -b:v 1024k -c:a wmav2 -b:a 192k test2.wmv

Resources