ffmpeg: combining/ordering vidstab and crop filters

北战南征 提交于 2021-01-29 07:48:16

问题


I have a workflow which essentially takes a raw video file, crops away portions of the frame that aren't relevant, then performs a two-pass deshake filter using the vidstab filter. At the moment I'm running this as three distinct commands: one to do the crop, a second to do the vidstab "detect" pass, and a third to do the vidstab "transform" pass.

My working script:

# do the crop first and strip the audio
nice -20 ffmpeg -hide_banner -ss $SEEK -i $INFILE -t $DURATION -preset veryfast -crf 12 -vf crop=0.60*in_w:in_h/9*8:0.22*in_w:0 -an -y $TEMP

# now run the vidstab detection pass
nice -20 ffmpeg -hide_banner -i $TEMP -vf vidstabdetect=stepsize=6:shakiness=10:accuracy=15:result=${INFILE}.trf -f null - 

# now the vidstab transform, with unsharp and writing the overlay text
nice -20 ffmpeg -hide_banner -i $TEMP -preset veryfast -crf 22 -vf \
" \
vidstabtransform=input=${INFILE}.trf:zoom=2:smoothing=60, 
unsharp=5:5:0.8:3:3:0.4, 
drawtext=fontfile=/Windows/Fonts/arialbd.ttf:text=$DIVE:enable='between(t,0,65)':fontcolor=black:fontsize=72:x=w*0.01:y=h*0.01,  
null"\
  -y $OUTFILE

What I can't seem to figure out is how I can combine the first two filter passes into a single chain, which (at least in theory) would be a faster encode time, and at the very least would be simpler to maintain and would eliminate a pass of the encoder. What I tried to do was the second code block, which just builds a filterchain that combines the initial crop with the vidstab detection filter.

# this is a combined filter for the crop and the vidstab detect
nice -20 ffmpeg -hide_banner -ss $SEEK -i $INFILE -t $DURATION -preset veryfast -crf 12 -vf \
" \
crop=0.60*in_w:in_h/9*8:0.22*in_w:0,
vidstabdetect=stepsize=6:shakiness=10:accuracy=15:result=${INFILE}.trf,
null " \
-an -r 30 -y $TEMP


# now run the transcoding and the vidstab transform
nice -20 ffmpeg -hide_banner -i $TEMP -preset veryfast -crf 22 -vf \
" \

vidstabtransform=input=${INFILE}.trf:zoom=2:smoothing=60, 
unsharp=5:5:0.8:3:3:0.4, 
drawtext=fontfile=/Windows/Fonts/arialbd.ttf:text=$DIVE:enable='between(t,0,65)':fontcolor=black:fontsize=72:x=w*0.01:y=h*0.01,  

null"\
  -y $OUTFILE

However, when I run this (and it runs) the final output video has most definitely NOT been effectively stabilized. The logs show that both the detect and the transform passes have been processed, it's just that the output isn't right.


回答1:


So, I managed to get this working although I have to admit I'm not 100% sure which change solved it. The code pastelet below contains the original "three pass" method as well as the newer "two-pass" method.

# begin the "three pass" method -- crop, then detect, then transform
# do the crop first and strip the audio
nice -20 ffmpeg -hide_banner -ss $SEEK -i $INFILE -t $DURATION -an -y -vf \
crop=0.60*in_w:in_h/9*8:0.22*in_w:0 $TEMP

# now run the vidstab detection pass
nice -20 ffmpeg -hide_banner -i $TEMP -vf \
vidstabdetect=stepsize=6:shakiness=10:accuracy=15:result=${TEMP}.trf -f null - 

# now run the transcoding and the vidstab transform
nice -20 ffmpeg -hide_banner -i $TEMP -y -vf \
" \
vidstabtransform=input=${TEMP}.trf:zoom=2:smoothing=60, 
unsharp=5:5:0.8:3:3:0.4, 
null " \
$OUTFILE


# begin the "two pass" method -- crop and detect together, then transform
# do the crop first and strip the audio
nice -20 ffmpeg -hide_banner -ss $SEEK -i $INFILE -t $DURATION -an -y -vf \
crop=0.60*in_w:in_h/9*8:0.22*in_w:0,vidstabdetect=stepsize=6:shakiness=10:accuracy=15:result=${TEMP2}.trf $TEMP2


# now the vidstab transform
nice -20 ffmpeg -hide_banner -i $TEMP2 -y -vf \
" \
vidstabtransform=input=${TEMP2}.trf:zoom=2:smoothing=60, 
unsharp=5:5:0.8:3:3:0.4, 
null " \
$TWOPASS

As an aside, I spent a LOT of time trying to figure out why the temporary file that came from the crop and vidstab detect pass was not identical in these two cases - in theory the same input file passed through the same two filters should be identical - but the vidstabdetect filter outputs a different pixel format:

From the three-pass (separate passes for crop & vidstabdetect)

Output #0, mp4, to 'temp-GOPR3285.MP4':
    Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuvj420p(pc), 1152x960 [SAR 1:1 DAR 6:5], q=-1--1, 47.95 fps, 48k tbn, 47.95 tbc (default)

From the combined crop/detect output:

Output #0, mp4, to 'temp2-GOPR3285.MP4':
    Stream #0:0(eng): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1152x960 [SAR 1:1 DAR 6:5], q=-1--1, 47.95 fps, 48k tbn, 47.95 tbc (default)

I haven't yet dug into what the detailed differences are between "yuvj420p" and "yuv420p" -- but that's the reason the output files aren't identical...



来源:https://stackoverflow.com/questions/38598047/ffmpeg-combining-ordering-vidstab-and-crop-filters

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!