ffmpeg filter_complex trim out-sync - ffmpeg

command line:
ffmpeg -i <INPUT> -filter-complex "<FILTER_COMPLEX>" -map "[ofa]" -map "[ofv]" -acodec aac -vcodec libx264 test.mp4
FILTER_COMPLEX content:
[0:v]split=3[sv1][sv2][sv3];
[0:a]asplit=3[sa1][sa2][sa3];
[sv1]trim=start=200:duration=5,setpts=PTS-STARTPTS[ov1];[sa1]atrim=start=200:duration=5[oa1];
[sv2]trim=start=300:duration=5,setpts=PTS-STARTPTS[ov2];[sa2]atrim=start=300:duration=5[oa2];
[sv3]trim=start=400:duration=5,setpts=PTS-STARTPTS[ov3];[sa3]atrim=start=400:duration=5[oa3];
[ov1][ov2][ov3]concat=n=3:v=1:a=0[ofv];
[oa1][oa2][oa3]concat=n=3:v=0:a=1[ofa]
As a result, the output video sounds are out of sync, and the video is redirected to 00:00:00, but the sound remains at the original time position.
Therefore, how to use ffmpeg to intercept several clips from a video, recombine them into a new video file, and keep the sound and picture synchronized.
I tried with [sa1]atrim=start=200:duration=5,setpts=PTS-STARTPTS[oa1] but an error:
Media type mismatch between the 'Parsed_atrim_4' filter output pad 0 (audio) and the 'Parsed_setpts_5' filter input pad 0 (video)
Cannot create the link atrim:0 -> setpts:0
Error initializing complex filters.
Invalid argument

Related

ffmpeg make video from audio, img and vtt subtitles

I'm trying to make a video with image audio file and vtt files, that's my command
ffmpeg -i F:\speech\media/waves/to_be_translated/python_example_test_GUyqHnh.wav -loop 1 -i F:\speech\waves/img.jpg -vf -filter_complex subtitles=F:\\speech\\media/typedVideos/combinedVideoTyped/zcjgtmrdlscqzina\\subtitles.vtt -map -shortest F:\speech\media/typedVideos/combinedVideoTyped/zcjgtmrdlscqzina\exported-video.mp4
but it gives this error:
Output #0, webvtt, to 'subtitles=F:\\speech\\media/typedVideos/combinedVideoTyped/zcjgtmrdlscqzina\\subtitles.vtt':
Output file #0 does not contain any stream
what am I doing wrong?
You have to tell ffmpeg what to do with the inputs.
There are many ways to skin a cat, here is one simplistic way.
ffmpeg -i input.jpg -f lavfi -i color=size=640x480:color=black -i 'input.wav' -filter_complex "[1][0]overlay[out];[out]subtitles='input.srt'[vid]" -map [vid] -map 2 -shortest -preset ultrafast output.mp4
We specify 3 inputs, the image, a Libavfilter input virtual device and the audio.
The virtual device generates a black video of a specified size.
The image is overlaid on top of the video, with the subtitles placed on the resulting output.
Finally we map the finished video with the audio into the final output file, an .mp4 which finishes when the shortest element going into it finishes, which will be the audio in this case, as the image and the video have no length per se.

ffmpeg watermark: scale2ref output can't be used in second overlay

I was able to add a watermark to 2 position(top left & bottom right) of a video with scaling image height to tenth of the video height in one command
ffmpeg -hide_banner -i /path/to/input.mp4 -i /path/to/watermark.jpg -filter_complex "[1:v][0:v]scale2ref=oh*mdar:ih/10[logo-out][video-out];[video-out][logo-out]overlay=10:10[flag];[1:v][flag]scale2ref=oh*mdar:ih/10[logo-out2][video-out2];[video-out2][logo-out2]overlay=W-w-10:H-h-10" -c:a copy /path/to/output.mp4
But the above command is too redundant, so I remove the second scale2ref
ffmpeg -hide_banner -i /path/to/input.mp4 -i /path/to/watermark.jpg -filter_complex "[1:v][0:v]scale2ref=oh*mdar:ih/10[logo-out][video-out];[video-out][logo-out]overlay=10:10[flag];[flag][logo-out]overlay=W-w-10:H-h-10" -c:a copy /path/to/output.mp4
But sadly, error occurs
[mov,mp4,m4a,3gp,3g2,mj2 # 0x7fb195013c00] Invalid stream specifier: logo-out.
Last message repeated 1 times
Stream specifier 'logo-out' in filtergraph description [1:v][0:v]scale2ref=oh*mdar:ih/10[logo-out][video-out];[video-out][logo-out]overlay=10:10[flag];[flag][logo-out]overlay=W-w-10:H-h-10 matches no streams
I know error occurs because of the first overlay didn't set an image output specifier, but it seems we can't do this? I only know overlay can set a video stream specifier.
How can I use the [logo-out] specifier which output from scale2ref in the second overlay?
An output generated inside a filtergraph can only be consumed once. To reuse it, split it first.
ffmpeg -hide_banner -i /path/to/input.mp4 -i /path/to/watermark.jpg -filter_complex "[1:v][0:v]scale2ref=oh*mdar:ih/10[logo-out][video-out];[logo-out]split=2[logo-left][logo-right];[video-out][logo-left]overlay=10:10[flag];[flag][logo-right]overlay=W-w-10:H-h-10" -c:a copy /path/to/output.mp4

Remove all non key frames from video without re-encoding

I have a HEVC mkv video from which I need to remove all but key frames without re-encoding whole thing.
I found out that I can extra key frames using this
ffmpeg -i full.mkv -c:v copy -vf "select=eq(pict_type\,PICT_TYPE_I)" key.mkv
but I get:
Filtergraph 'select=eq(pict_type\,PICT_TYPE_I)' was defined for video output stream 0:0 but codec copy was selected.
Filtering and streamcopy cannot be used together.
What do I do?
You'll have to use the bitstream filter filter_units for this:
ffmpeg -i test.mkv -c copy -map v -bsf:v "filter_units=pass_types=16-23|32-34" key.mkv
This will only pass through random access pictures from the HEVC stream. This should cover most of them but HEVC has more keyframes types than H.264 so I'll update the types above if there are some I've missed.

FFMPEG overlay video over image using movie filter resulting video with no sound

I want to overlay srinked video on the top of single image.
I use movie filter to do that. like this
ffmpeg.exe -loop 1 -i Coronavirus00000000.jpg -vf "movie=C\\:/\Users/\Toshiba/\Pictures/\test vcp/\shopi pro.mp4,scale=1180:-1[inner];[in][inner]overlay=70:70:shortest=1[out]" -y out.mp4
It's work. but the problem, the audio from video is removed. The final video out.mp4 has no sound, even though the original video has.
I have read answer on this threat FFMPEG overlaying video with image removes audio
That recommend to Change into ...[padded]overlay=0:0" -y ... Or add -map 0:a
But I don't understand how to implement that answer into movie filter
Please notice inputs/sources you have:
an input image ("Coronavirus00000000.jpg")
a movie source which by default selects a video stream
so you don't have any audio input stream selected/opened. To do so I'd recommend open every file as a standard ffmpeg input (-i <file>) and then configure a complex filtering graph that utilizes them.
In your example that would be:
ffmpeg -loop 1 -i Coronavirus00000000.jpg -i C\\:/\Users/\Toshiba/\Pictures/\test vcp/\shopi pro.mp4 -filter_complex "[1:v]scale=1180:-1[inner];[0:v][inner]overlay=70:70:shortest=1[out]" -map '[out]' -map 1:a -y out.mp4
where:
-i Coronavirus00000000.jpg opens your image file as input #0
-i C\\:/\Users/\Toshiba/\Pictures/\test vcp/\shopi pro.mp4 opens your video file with video and audio streams as input #1
[1:v]scale=1180:-1[inner] scales the input's #1 video stream
[0:v][inner]overlay=70:70:shortest=1[out] overlays the scaled video onto input's #0 video stream
-map '[out]' selects overlayed video stream (tagged as [out]) for output video stream
-map 1:a selects input's #1 audio stream for output audio stream

Extract first frame of multi video streams video

I am curious about how to use FFmpeg in order to extract the first frame of the first video stream from a multi-video stream file.
What I have so far is:
ffmpeg -i {mediaFile} -ss 0 -map 0:v -vframes 1 -f image2 firstFrame.jpeg.
I am not sure about the -map part. How can be certain that I work on the first video stream? Is there a way to first filter streams by codec type, then select the first and then extract the frame?
Thanks.
ffmpeg -i {mediaFile} -map 0:v:0 -frames:v 1 firstFrame.jpeg
Add an input stream index to your -map as shown in the example above. 0:v:0 is input #0:video:stream #0. Note that ffmpeg starts counting from 0. If you wanted video stream #3, it would be 0:v:2.
I removed the superfluous options from your command.
Also see
-map option documentation
How can I extract a good quality JPEG image from a video with ffmpeg?

Resources