Reputation: 131
My plan was to put a transparent red box behind a video. This box should only be present from second 1-45. But if the videos are 3 hours long, the process takes a long time although it only has to process 45 seconds.
My first attempt takes too long:
ffmpeg -i %1 -vf drawbox=0:9*ih/10:iw:ih/10:t=fill:[email protected]:enable='between(t,1,45)' "%~dp0transpred\%~n1%~x1
Then i tried splitting the video into two parts. put the box on the first video, and then put the two back together again.
ffmpeg -ss 00:00:00.0000 -i %1 -to 00:00:45.0000 -vf drawbox=0:9*ih/10:iw:ih/10:t=fill:[email protected]:enable='between(t,1,45)' "%~dp0transpred\%~n1A%~x1"
FFMpeg -ss 00:00:45.0000 -i %1 -c:v copy -c:a copy -avoid_negative_ts make_zero "%~dp0transpred\%~n1B%~x1"
But i don't even have to try to put these two together, because they are not separated exactly at the second. I have read that this is due to "timestamps" and the different video and audio streams.
Now I'm trying an approach to create a stream with the bar, and then overlay it with the finished video. I haven't quite managed that yet, and I don't know if it's faster. Shortening the video is very fast.
EDIT (Added as a replacement for the comment later)
Thanks for your help I have almost done it with a slightly different approach. Unfortunately, the second part now always has no sound. No matter if I put A and B (B no sound) or B and A (A no sound) together.
mkvmerge --split timestamps:00:00:45.100 A.MKV -o splitmkm.mkv
ffmpeg -i splitmkm-001.mkv -vf drawbox=0:9*ih/10:iw:ih/10:t=fill BAR1.MKV
ffmpeg -safe 0 -f concat -i list.txt -c copy output1.mkv
EDIT (Answer to kesh)
This was the error Again, audio codec config's must match across all your concat files
. The drawbox
changed the audio Codec from AC-3 to Vorbis.
the procedure is now:
mkvtoolnix\mkvmerge --split timestamps:00:00:05.100 %1 -o A_splitmkm.mkv
with mkvmerge i have an exact split at the time, and i don't have to learn about keyframes.ffmpeg -i A_splitmkm-001.mkv -vf drawbox=0:9*ih/10:iw:ih/10:t=fill:color=red A_BARmkm.MKV
create the Barffmpeg -i A_BARmkm.MKV -i A_splitmkm-001.mkv -map 0:v -map 1 -map -1:v -c copy A_BARwithAudio.mkv
redo the step with the changed audio from drawboxffmpeg -safe 0 -f concat -i list.txt -map 0 -c copy A_output1.mkv
mergeNow everything works. Thanks alot!
Upvotes: 1
Views: 1330
Reputation: 5513
See if this works for you:
ffmpeg -ss 00:00:00.0000 -to 00:00:45.0000 -i %1 \
-vf "color=c=red:r=1:d=1[red];color=c=0x808080:r=1:d=1,format=y8,[red]alphamerge[fore]; \
[fore][0:v]scale2ref=w=iw:h=ih/10[f][b]; \
[b][f]overlay=0:H-h:enable='between(t,1,45)'" \
"%~dp0transpred\%~n1A%~x1"
color=c=red
line: form an unsized red semi-transparent box which lasts for 1 frame over 1 second[fore][back]scale2ref
line: size the red box to the frame[b][f]overlay
line: apply the red box when neededBecause the stream foreground stream (which ends with [f]
) only lasts for 1 frame, ffmpeg will only compute the box once, and overlay
filter will reuse that frame until all the input video frames are processed.
On drawbox
. Because you need a filled box, the above is simpler implementation IMO. If you need a boundary, the issue I faced is that it is incompatible with a transparent frame. This restriction makes it unusable with the preforming approach. [edit: to make drawbox
to work with transparent frames, you need to set the option replace=1
]
On your alternate splicing approach, if you cut your video at a keyframe, you should be able to make it to work. To find the keyframes, you need to use ffprobe
. If you want to pursue this one, see my recent answer to another question.
Upvotes: 1