FFMPEG duplicating the first frame - ffmpeg

I want to use FFMPEG (the latest version) to cut a 24 fps matroska file. So I am using -ss and -t, but I noticed with VLC that the very first frame is ALWAYS duplicated one time, no matter the file or the duration I choose. While it is not a really serious issue, but I wanted to know if there was a way to prevent that.
Here is the command I am using:
ffmpeg -ss 00:01:26.086 -i file.mkv -t 00:00:02.000 -c:v libx264 -crf 18 output.mp4

add -vsync vfr in your cmd may be helpful
ffmpeg -ss 00:01:26.086 -i file.mkv -vsync vfr -t 00:00:02.000 -c:v libx264 -crf 18 output.mp4

Related

Duration filter is ignored using FFMPEG Laravel

This commands works perfectly:
ffmpeg -loop 1 -i flyer.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -vf scale=1080:720 out.mp4
Trying to do the same with Laravel FFMPEG
FFMpeg::fromDisk('images')
->open('flyer.jpg')
->export()
->addFilter('-loop', 1)
->addFilter('-c:v', 'libx264')
->addFilter('-t', '15')
->addFilter('-pix_fmt', 'yuv420p')
->addFilter('-vf', 'scale=1080:720')
->save('timelapse.mp4');
Seems that all filters are correctly applied but "-t 15" is not.
The problem is that in order to work, the -loop parameter should be specified before the -i parameter.
This works:
ffmpeg -loop 1 -i flyer.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -threads 12 -vf [in]scale=1080:720 out.mp4
This doesn't work:
ffmpeg -i flyer.jpg -loop 1 -c:v libx264 -t 15 -pix_fmt yuv420p -threads 12 -vf [in]scale=1080:720 out.mp4
So I should I proceed with FFMPEG Laravel?
This topic was brought up in github:
https://github.com/protonemedia/laravel-ffmpeg/issues/349
But no answers.
Thanks.
You need to set input options not filters (or output options). Not knowing anything about PHP/Laravel, I suspect you need to use either openWithInputOptions() to open the input file or setInputOptions() to set -loop 1 input option.

How to add a hard code of subs to this filter_complex

ffmpeg -ss 00:11:47.970 -t 3.090 -i "file.mkv" -ss 00:11:46.470 -t 1.500 -i "file" -ss 00:11:51.060 -t 0.960 -i "file.mkv" -an -c:v libvpx -crf 31 -b:v 10000k -y -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa];[outv]scale='min(960,iw)':-1[outv];[outv]subtitles='file.srt'[outv]" -map [outv] file_out.webm -map [outa] file.mp3
I have a filter where take three different points in a file concat them together and scale them down this part works
Im looking to see how to add to the filter_complex a sub burn in step rendering the subs from the exact timings usings a file that I specify when I use the above code it doesn't work
The subtitles filter is receiving a concatenated stream. It does not contain the timestamps from the original segments. So the subtitles filter starts from the beginning. I'm assuming this is the problem when you said, "it doesn't work".
The simple method to solve this is to make temporary files then concatenate them.
Output segments
ffmpeg -ss 00:11:47.970 -t 3.090 -copyts -i "file.mkv" -filter_complex "scale='min(960,iw)':-1,subtitles='file.srt',setpts=PTS-STARTPTS;asetpts=PTS-STARTPTS" -crf 31 -b:v 10000k temp1.webm
ffmpeg -ss 00:11:46.470 -t 1.500 -copyts -i "file.mkv" -filter_complex "scale='min(960,iw)':-1,subtitles='file.srt',setpts=PTS-STARTPTS;asetpts=PTS-STARTPTS" -crf 31 -b:v 10000k temp2.webm
ffmpeg -ss 00:11:51.060 -t 0.960 -copyts -i "file.mkv" -filter_complex "scale='min(960,iw)':-1,subtitles='file.srt',setpts=PTS-STARTPTS;asetpts=PTS-STARTPTS" -crf 31 -b:v 10000k temp3.webm
The timestamps are reset when fast seek is used (-ss before -i). -copytswill preserve the timestamps so the subtitles filter knows where to start the subtitles.
Make input.txt:
file 'temp1.webm'
file 'temp2.webm'
file 'temp3.webm'
Concatenate with the concat demuxer:
ffmpeg -f concat -i input.txt -c copy output.webm
-c copy enables stream copy mode so it avoids re-encoding to concatenate.

ffmpeg: How to speed up (and keep only) a specified portion of an input video

In my input video is a 48 second range that I wish to speed up. I wish to save only that sped up portion to a new video.
Solution:
ffmpeg -y -ss 00:00:03 -t 00:00:48 -i input.mp4 -an -crf 20 -pix_fmt yuv420p -vf "scale=1080:-1, setpts=PTS/10.0" "output.mp4"

Clip long video segment quickly

Let's say I have a video called Concert.mp4. I want to extract a performance from it quickly with minimal reencoding. I want to do the equivalent of this, but faster:
ffmpeg -i "Concert.mp4" -ss 00:11:45 -to 00:18:15 -preset veryfast -y artist.mp4
This takes 17 seconds, which is way too long for our needs.
Now, it turns out that 11:45 and 18:15 don't fall on iframes, so if you try this you will get a 3 second delay at the beginning before the video shows:
ffmpeg -i "Concert.mp4" -ss 00:11:45 -to 00:18:15 -c copy -y artist.mp4
Running this command, we can see where we need to cut:
ffprobe -read_intervals "11:00%19:00" -v error -skip_frame nokey -show_entries frame=pkt_pts_time -select_streams v -of csv=p=0 "Concert.mp4" > frames.txt
So what we need to do is encode the first 3.708 seconds, copy the middle, and then encode the last 5.912 seconds.
I can get the 3 segments to all look perfect (by themselves) like this:
ffmpeg -ss 698.698 -i "Concert.mp4" -ss 6.302 -t 3.708 -c:v libx264 -c:a copy -c:s copy -y clipbegin.mp4
ffmpeg -ss 708.708 -to 1089.088 -i "Concert.mp4" -c copy -y clipmiddle.mp4
ffmpeg -ss 1089.088 -i "Concert.mp4" -t 5.912 -c:v libx264 -c:a copy -c:s copy -y clipend.mp4
ffmpeg -f concat -i segments.txt -c copy -y artist.mp4
segments.txt of course contains the following:
file 'clipbegin.mkv'
file 'clipmiddle.mkv'
file 'clipend.mkv'
I saw this solution presented here, but no amount of tweaking gets it to work for me:
https://superuser.com/a/1039134/73272
As far as I can tell, this method doesn't work at all. It crashes VLC pretty hard no matter what I try.
The combined video keeps glitching after the 3 seconds, probably because the PTS times are different or something (using some options, I have seen warning messages to this effect). Is there anything I can add to the commands above to get this to work? The only requirement is that the middle command must not re-encode the video, but must do a fast copy.
Thanks in advance.
OK, so the answer was just that the latest VLC seems to be buggy. What I did above plays just fine with a very slight pause at the cut point in ffplay, mplayer and PotPlayer.
Following #Gyan's advice, I set the profile and level to match the original (using -profile:v main -level:v 4) and even the slight pause went away.
ffmpeg -ss 698.698 -i "Concert.mp4" -ss 6.302 -t 3.708 -c:v libx264 -c:a copy -c:s copy -profile:v main -level:v 4 -y clipbegin.mp4
ffmpeg -ss 708.708 -to 1089.088 -i "Concert.mp4" -c copy -y clipmiddle.mp4
ffmpeg -ss 1089.088 -i "Concert.mp4" -t 5.912 -c:v libx264 -c:a copy -c:s copy -profile:v main -level:v 4 -y clipend.mp4
ffmpeg -f concat -i segments.txt -c copy -y artist.mp4

FFMPEG "-to" option won't stop encoding at the implied time

I'm using ffmpeg to cut and covert a part of a long video but when using the "-to" option ffmpeg keeps encoding till the end of the video and wont stop.
Here's my command:
ffmpeg -ss 00:22:59 -i input.mkv -to 00:23:15.5 -c:v libx264 -c:a aac output.mp4
if i change to "-t" and enter my desired duration, problem goes away. but since i have a very long video and many tasks i need to use "-to" which is easier for me.
Thanks in advance.
Basically, -ss when used as an input option, seeks to the given time and resets timestamps, so that the first selected frame has timestamp 0. So, in your command, t and to will have the same effect.
You have to either use
ffmpeg -ss 00:22:59 -copyts -i input.mkv -to 00:23:15.5 -c:v libx264 -c:a aac output.mp4
(not recommended)
or
ffmpeg -ss 00:22:59 -to 00:23:15.5 -i input.mkv -c:v libx264 -c:a aac output.mp4
(needs ffmpeg build > Nov 19 2017)
or
ffmpeg -i input.mkv -ss 00:22:59 -to 00:23:15.5 -c:v libx264 -c:a aac output.mp4
(slowest of the three)

Resources