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?
Related
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.
It might be a duplicate question but didn't find any helpful answer.
I have 2 audio files and 1 mp4 video file. Want to add the 2 audio files to mp4 videoat specific time.
For example:
Video file:
input.mp4 (2 minutes video)
Audio files:
Audio File 1:
test_0:01.mp3 (15 seconds audio file) I want to insert this file at position 0:01 in the mp4 video
Audio File 2:
test_0:20.mp3(15 seconds audio file) I want to insert this file at position 0:20 in the mp4 video
I tried the following command with offset
It's only inserting test_0:01.mp3 at 0:01 position in the video file
But test_0:20.mp3 is not getting inserted at 0:020 position getting mute for this file no audio.
ffmpeg -i input.mp4 -itsoffset 01 -i test_0:01.mp3 -itsoffset 20 -i test_0:20.mp3 -c:v copy -map 0:v:0 -map 1:a -map 2:a -c:a aac -b:a 192k output.mp4
Any help will be appreciated!
Your command creates two audio tracks in the MP4 file. If you have a look in your video player you can choose between two audio tracks (usually used to choose different audio languages).
Why
This is because every -map parameter creates a new stream. In your example one video with two audio tracks.
Solution
Use the audio filter amix instead. Use also the filter adelay for the delay in the same filter chain to achieve the best result.
ffmpeg -i input.mp4 -i test_0:01.mp3 -i test_0:20.mp3 -filter_complex "[1:a]adelay=1s:all=1[a1];[2:a]adelay=20s:all=1[a2];[a1][a2]amix=inputs=2[amixout]" -map 0:v:0 -map "[amixout]" -c:v copy -c:a aac -b:a 192k output.mp4
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
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
Let say I have an MKV with a video stream, an audio stream and a subtitles stream.
I would like to burn this subtitle into my video directly from the subtitle stream.
so far, this is my command line :
ffmpeg.exe -i "MyMovie.mkv" -map 0:0 -map 0:1 -vf subtitles=sub.srt out.mkv
So far so good. But, my subtitles are inside the movie and I need to extract them before. I used this :
ffmpeg.exe -i "MyMovie.mkv" -f srt sub.srt
But this operation is too long : ~25 sec on my PC for a 2.5Go MKV. I need something faster because I need to start streaming the output to an app as soon as possible. (I did not mentioned the others command line arguments I used to achieve this streaming properly because my question is not about that.)
I know it is not possible to get the stream directly like this :
ffmpeg.exe -i "MyMovie.mkv" -map 0:0 -map 0:1 -vf subtitles=[0:s:0] out.mkv
But this is something I would love.
edit :
But I already know this kind of command line do not exist. (But if I'm wrong, please, let me know.)
Now, I would like to write this kind of filter myself, and compile ffmpeg with it.
But I have no idea where to start.
Can anyone help me to start ?
Thank you
your are looking for the "picture based" mode
ffmpeg -i input.mkv -filter_complex "[0:v][0:s]overlay[v]" -map [v] -map 0:a <output options> output.mkv
here we map the 1st(0:s) subtitle stream on the 1st video(0:v)
described with more details here