how to use concat demuxer twice in the same ffmpeg command - ffmpeg

For a complex ffmpeg filter I need the same input twice. For the sake of simplicity I will use a sample where I just overlay a video with itself. (In my real problem the filter is more complex):
ffmpeg -i vid -i vid -filter_complex '[0:v][1:v]overlay' -c:v libx265 -an result.mkv
This works, the result is the reencoded original video.
Sadly, my input is not a video file but a concat demuxer. This is my naive aproach:
ffmpeg -f concat -i vid_list -f concat -i vid_list -filter_complex '[0:v][1:v]overlay' -c:v libx265 -an result.mkv
And it fails. I get tons of error messages about missing frames and the resulting video is completely wrong.
How can I use concat demuxer twice as input within the same ffmpeg command?
NB: loading the concat only once and then using the split filter doesn't work for me. In combination with my complex filter it consumes all RAM.

Based on the assertion from llogan above, that my idea should work, I found a solution that I don't 100% understand but it seems to work....
The input videos do not all have the same framerate. I didn'T expect this to be important, since I am using the very same list of videos twice, so whatever the framerate is or what the concat demuxer does to it, it should be the same to both. Still, explicitly setting the input frame rate seems to solve my problem.
So this fails:
ffmpeg -f concat -safe 0 -i vidlist -f concat -safe 0 -i vidlist ...
but this works:
ffmpeg -f concat -r 15 -safe 0 -i vidlist -f concat -r 15 -safe 0 -i vidlist ...
As said I don't understand exactly why...
Thanks to all

Related

add current video time with ffmpeg

I can add frame number to video with ffmpeg as below:
ffmpeg -y -i input.mp4 -an -vf drawtext=fontsize=36:fontcolor=yellow:text='%{frame_num}':x=20:y=20 -f mp4 output.mp4
How can I modify it to show HH:MM:SS instead of current frame number?
As #kesh pointed out pts:hms instead of frame_num does the job but your specific command line, will lead you astray, as you have omitted a set of encapsulating quotes.
Whilst omitting them, works with frame_num, it will not work with pts:hms
Use:
ffmpeg -y -i input.mp4 -an -vf "drawtext=fontsize=36:fontcolor=yellow:text='%{pts\:hms}':x=20:y=20" -f mp4 output.mp4
Here the entire drawtext filter is wrapped in quotation marks.
Edit:
To achieve pure HH:MM:SS format use gmtime rather than hms i.e.
ffmpeg -y -i input.mp4 -an -vf "drawtext=fontsize=36:fontcolor=yellow:text=' %{pts\:gmtime\:0\:%T}':x=20:y=20" -f mp4 output.mp4

merge audio and video with ffmpeg doesnt work correctly

I have ubuntu 20.04 and in past days I did this job(merge video and audio) well in terminal and with ffmpeg:
ffmpeg -i input.mp4 -i input2.mp3 -c copy output.mp4
so fast I have recived output.mp4, but now I tried this one and get output without any sound!
I try another ways to merge this ones(also with ffmpeg) but there are no diffrent...
ffmpeg -f concat -safe 0 -i <(for f in ./input*.mp4; do echo "file '$PWD/$f'"; done) -c copy output.mp4
Note -f concat will select a demuxer. This alters the way -i nput files are read.
So instead video-files 'concat expects a txt-file listing the files to concatenate.
However we somehow omit the creation of that text file and use process substitution to generate and pass that list on the fly to demux.
For more details go here:
https://trac.ffmpeg.org/wiki/Concatenate#demuxer
If you want to merge several video files, you can use these command.
merge two video files.
ffmpeg -f concat -i 1.mp4 -1 2.mp4 -codec copy out.mp4
merge multiple video files.
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mpt -vcodec copy -acodec copy out.mp4

ffmpeg - Concat multiple video files, add audio, set length to videos combined length

I have up until now done this in 2 steps.
Concat video files to outputNoAudio.mp4
Add audio to outputNoAudio.mp4 trimming with -shortest
Now I'm trying to do this in one step using this line
ffmpeg -f concat -safe 0 -i 'vidlist.txt' -i 'music.m4a' -c copy -movflags faststart -y 'test.mp4'
If I use -shortest I end up with an output the length of the shortest video in vidlist.txt. What I'm trying to achieve is the length of all videos combined.
As #Mulvya pointed out. The command works with -shortest. I had the times of my test videos wrong when I started testing. Leaving the answer here for for others trying to do the same.
ffmpeg -f concat -safe 0 -i 'vidlist.txt' -i 'music.m4a' -c copy -movflags faststart -shortest -y 'test.mp4'

Is it possible to create a ”timeline” using FFMPEG?

I know it’s possible to get a part of a file using the command:
ffmpeg -ss 00:02:00.000 -i input.mp4" -t 00:00:05.000 out.mp4
But is it possible to combine multiple videos with text and other effects?
I want to create a output from the following
File1.mp4:
Read from 00:02:00.000 to 00:02:05.000
File2.mp4
Read from 00:00:00.000 to 00:01:30.000
Insert overlay image “logo.png” for 20 seconds
File3.mp4
Insert the whole file
Insert text from 00:00:10.000 to 00:00:30.000
It can be done with FFmpeg, but it isn't really an 'editor' so the command will get long, unwieldy and prone to execution errors the more the number of input clips and effects you apply.
That said, one way to do this is using the concat filter.
ffmpeg -i file1.mp4 -i file2.mp4 -i file3.mp4 -loop 1 -t 20 -i logo.png \
-filter_complex "[0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
[1:v]trim=duration=90,setpts=PTS-STARTPTS[vt2];
[vt2][3:v]overlay=eof_action=pass[v2];
[2:v]drawtext=enable='between(t,10,30)':fontfile=font.ttf:text='Hello World'[v3];
[0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1];
[1:a]trim=duration=90,setpts=PTS-STARTPTS[a2];
[v1][a1][v2][a2][v3][2:a]concat=n=3:v=1:a=1[v][a]" -map "[v]" -map "[a]" output.mp4
I haven't specified any encoding parameters like codec or bitrate..etc. Assuming you're familiar with those. Also, haven't specified arguments for overlay or drawtext like position..etc. Consult the documentation for a guide to those.

How to Loop Input video x number of time using FFMPEG?

I want to loop same video 4 times and output as video using ffmpeg.
SO I create code like this in ffmpeg.
ffmpeg -loop 4 -i input.mp4 -c copy output.mp4
but when i run it it give the error like this.
Option Loop Not Found.
how to do this withour error. Please Help Me
In recent versions, it's
ffmpeg -stream_loop 4 -i input.mp4 -c copy output.mp4
Due to a bug, the above does not work with MP4s. But if you wrap to a MKV, it works for me.
ffmpeg -i input.mp4 -c copy output.mkv
then,
ffmpeg -stream_loop 4 -i output.mkv -c copy output.mp4
I've found an equivalent work-around with input concatenation for outdated/bugged versions -stream_loop:
ffmpeg -f concat -safe 0 -i "video-source.txt" -f concat -safe 0 -i "audio-source.txt" -c copy -map 0:0 -map 1:0 -fflags +genpts -t 10:00:00.0 /path/to/output.ext
This will loop video and audio independently of each other and force-stop the output at 10 hour mark.
Both text files consist of
file '/path/to/file.ext'
but you must make sure to repeat this line enough times to keep the output satisfied.
For example, if your total video time is less than total audio time then video output will stop earlier than intended and the audio will keep playing until either -t 10H is reached or audio ends prematurely.

Resources