--- lang:ja-jp ###### tags: `Program` `open` --- <a id="top"></a> # ffmpegまとめ [TOC] ## remote ### はじめ まずはスペースが邪魔なので`rename`を実行。 前半の共通部分も不要な範囲は削る。 処理の段階を区別するために、prefixとしてA_も付与する。 `files.dat`に動画内で挿入するタイトルなどを記入する。 入力内容は [##insert title](#insert-title)などを参照。 ```bash= rename "s/ /_/g" *.mp4 rename "s/対戦1_//g" *.mp4 #rename "s/Zoom_ミーティング_//g" *.mp4 rename "s/^/A_/g" *.mp4 ls -1 A_*.mp4 > files.dat # code files.dat ``` ### 3x, croping : 縦長 FullHDの画面を4分割した内、次のように表示されている状況を想定。 - 左上 : 横長に表示 - 左下 : 縦長に表示 ```bash= # 3x, croping, erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} convert -size 30x200 "xc:#000000" black.png for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -i black.png -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=810:454:150:60, transpose=1, scale=-2:1028 [right]; [in2] crop=345:454:380:514, scale=-2:1028 [left]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=820:0 [not_blacked1];[not_blacked1][1:v] overlay=0:0 [not_blacked2]; [not_blacked2][1:v] overlay=820:0" -an $remake_name -y done ``` ### 3x, croping:横長 FullHDの画面を4分割した内、次のように表示されている状況を想定。 - 左上 : 横長に表示 - 左下 : 横長に表示 ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} convert -size 30x200 "xc:#000000" black.png for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=710:540:130:245, transpose=1, scale=-2:1028 [left]; [in2] crop=940:540:960:245, transpose=1, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=782:0" -an $remake_name -y done ``` ### 3x, 2x1, croping:横長 FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示 - 右 : 横長に表示(自分) ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=952:545:8:245, transpose=2, scale=-2:1028 [left]; [in2] crop=713:545:1080:245, transpose=2, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=588:0" -an $remake_name -y done # for check movies=($(ls A_*.mp4)) movie=${movies[0]} remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -t 10 -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=952:545:8:245, transpose=2, scale=-2:1028 [left]; [in2] crop=713:545:1080:245, transpose=2, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=588:0" -an $remake_name -y ``` ### 3x, 2x1, croping:横長 FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示(自分) - 右 : 横長に表示 ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=713:545:128:245, transpose=1, scale=-2:1028 [left]; [in2] crop=952:545:960:245, transpose=1, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=782:0" -an $remake_name -y done remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -t 10 -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=713:545:128:245, transpose=1, scale=-2:1028 [left]; [in2] crop=952:545:960:245, transpose=1, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=782:0" -an $remake_name -y ``` ### 3x, 2x1, croping:横長right, 縦向き FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示 - 右 : 横長に表示(自分) ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1350:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=952:545:8:245, scale=-2:540 [top]; [in2] crop=713:545:1080:245, scale=-2:540 [bottom]; [base][top] overlay=200:0:shortest=1 [tmp1]; [tmp1][bottom] overlay=320:540" -an $remake_name -y done # for check movies=($(ls A_*.mp4)) movie=${movies[0]} remake_name=$(echo $movie | sed "s/^A_/B_/g") </dev/null ffmpeg -t 2 -i $movie -filter_complex "color=black, scale=1350:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=952:545:8:245, scale=-2:540 [top]; [in2] crop=713:545:1080:245, scale=-2:540 [bottom]; [base][top] overlay=200:0:shortest=1 [tmp1]; [tmp1][bottom] overlay=320:540" -an $remake_name -y ``` ### 3x, 2x1, croping:横長left, 縦向き FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示(自分) - 右 : 横長に表示 ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") </dev/null ffmpeg -i $movie -filter_complex "color=black, scale=1350:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=713:545:128:245, scale=-2:540 [bottom]; [in2] crop=952:545:960:245, scale=-2:540 [top]; [base][top] overlay=200:0:shortest=1 [tmp1]; [tmp1][bottom] overlay=320:540" -an $remake_name -y done # for check movies=($(ls A_*.mp4)) movie=${movies[0]} remake_name=$(echo $movie | sed "s/^A_/B_/g") </dev/null ffmpeg -t 2 -i $movie -filter_complex "color=black, scale=1350:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=713:545:128:245, scale=-2:540 [bottom]; [in2] crop=952:545:960:245, scale=-2:540 [top]; [base][top] overlay=200:0:shortest=1 [tmp1]; [tmp1][bottom] overlay=320:540" -an $remake_name -y ``` ### discord: 3x, 2x1, croping:横長->横接続 FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示 - 右 : 横長に表示(自分) ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1400:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:8:270, transpose=1, scale=-2:1028 [left]; [in2] crop=948:535:963:270, transpose=1, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=782:0" -an $remake_name -y done remake_name=$(echo ${movie/mp4/png} | sed "s/^A_/B_/g") ffmpeg -i $movie -filter_complex "color=black, scale=1165:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:963:270, transpose=1, scale=-2:1028 [left]; [in2] crop=948:535:8:270, transpose=1, scale=-2:1028 [right]; [base][left] overlay=0:0:shortest=1 [tmp1]; [tmp1][right] overlay=585:0" -an $remake_name -y ffmpeg -i $movie -filter_complex "color=black, scale=910:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:7:270, scale=-2:510 [top]; [in2] crop=948:535:963:270, scale=-2:510 [bottom]; [base][top] overlay=1:2:shortest=1 [tmp1]; [tmp1][bottom] overlay=1:514" -an $remake_name -y ``` ### discord: 3x, 2x1, croping:横長->縦接続 FullHDの画面を2分割した内、次のように表示されている状況を想定。名前の黒塗りはなし。 - 左 : 横長に表示 - 右 : 横長に表示(自分) ```bash= # 3x, croping, NOT erase name movies=($(ls A_*.mp4)) movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") </dev/null ffmpeg -i $movie -filter_complex "color=black, scale=1322:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:7:270, scale=-2:535 [top]; [in2] crop=948:535:963:270, scale=-2:535 [bottom]; [base][top] overlay=237:0:shortest=1 [tmp1]; [tmp1][bottom] overlay=237:540" -an $remake_name -y done png_name=$(echo ${movie/mp4/png} | sed "s/^A_/B_/") </dev/null ffmpeg -i $movie -filter_complex "color=black, scale=910:1028 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:7:270, scale=-2:510 [top]; [in2] crop=948:535:963:270, scale=-2:510 [bottom]; [base][top] overlay=1:2:shortest=1 [tmp1]; [tmp1][bottom] overlay=1:514" -an $png_name -y png_name=$(echo ${movie/mp4/png} | sed "s/^A_/B_/") </dev/null ffmpeg -t 2 -i $movie -filter_complex "color=black, scale=1322:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:7:270, scale=-1:540 [top]; [in2] crop=948:535:963:270, scale=-1:540 [bottom]; [base][top] overlay=0:0 [tmp1]; [tmp1][bottom] overlay=0:540:shortest=1" -an $remake_name -y </dev/null ffmpeg -t 2 -i $movie -filter_complex "color=black, scale=1322:1080 [base];[0:v] setpts=PTS/3.0 [in]; [in] split [in1] [in2]; [in1] crop=948:535:7:270, scale=-2:535 [top]; [in2] crop=948:535:963:270, scale=-2:535 [bottom]; [base][top] overlay=237:0 [tmp1]; [tmp1][bottom] overlay=237:540:shortest=1" -an $remake_name -y ``` ### crop, 座標の調べ方 https://cloud-util.appspot.com/ImageMeasure を利用 -> gimp ```bash # 静止画作成 -> ffmpeg -i input.mp4 output.png # 座標で切り出して微調整 Xstart=8;Ystart=245 Xsize=955;Ysize=542 ffmpeg -i input.mp4 -vf crop=$Xsize:$Ysize:$Xstart:$Ystart output2.png ``` ### insert title タイトル挿入を行う。 ここでは`filtes.dat`の各行として次を想定している(区切りは半角スペース)。 `A_*.mp4` `自分のデッキ名` `相手のデッキ名` `対戦番号` `日付` 対戦番号は自動で取得する方が便利。 ```bash= # insert title movies=($(ls B_*.mp4)) movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^B_/C_/g") before_name=$(echo $movie | sed "s/^B_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') date_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $5}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") </dev/null ffmpeg -i $movie -c copy -t 10 -r 30 tmp1_pre.mp4 -y movie_time_out=$(($movie_time - 12)) echo "ffmpeg -ss 10 -i $movie -c copy -t $movie_time_out -r 30 tmp2.mp4 -y" | xclip xclip -o | bash </dev/null ffmpeg -i tmp1_pre.mp4 -filter_complex "format=yuv444p, drawbox=y=ih*0.7:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawbox=y=ih*0.3:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${date_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/3:enable='between(t,0,5)',drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${number_text} ${mydeck_text}VS${opdeck_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/1.27:enable='between(t,0,5)',format=pix_fmts=yuv420p" -an -movflags +faststart -crf 20 -an -r 30 tmp1.mp4 -y echo -e "file tmp1.mp4\nfile tmp2.mp4" > combine_files.dat </dev/null ffmpeg -f concat -i combine_files.dat -c:v copy -an -map 0:v $remake_name -y done ``` ```bash= movies=($(ls B_*.mp4)) movie=${movies[4]} remake_name=$(echo $movie | sed "s/^B_/C_/g") before_name=$(echo $movie | sed "s/^B_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') date_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $5}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") ffmpeg -i $movie -c copy -t 10 -r 30 tmp1_pre.mp4 -y movie_time_out=$(($movie_time - 12)) echo "ffmpeg -ss 10 -i $movie -c copy -t $movie_time_out -r 30 tmp2.mp4 -y" | xclip xclip -o | bash echo -e "file tmp1.mp4\nfile tmp2.mp4" > combine_files.dat ffmpeg -i tmp1_pre.mp4 -filter_complex "format=yuv444p, drawbox=y=ih*0.7:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawbox=y=ih*0.3:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${date_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/3:enable='between(t,0,5)',drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${number_text} ${mydeck_text}VS${opdeck_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/1.27:enable='between(t,0,5)',format=pix_fmts=yuv420p" -an -movflags +faststart -crf 20 -an -r 30 tmp1.mp4 -y ffmpeg -f concat -i combine_files.dat -c:v copy -an -map 0:v $remake_name -y ``` ```bash= # insert title movies=($(ls B_*.mp4)) movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^B_/C_/g") before_name=$(echo $movie | sed "s/^B_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') date_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $5}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") </dev/null ffmpeg -i $movie -c copy -t 10 -r 30 tmp1_pre.mp4 -y </dev/null ffmpeg -ss 10 -i $movie -c copy -r 30 tmp2.mp4 -y </dev/null ffmpeg -i tmp1_pre.mp4 -filter_complex "format=yuv444p, drawbox=y=ih*0.7:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawbox=y=ih*0.3:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,5)', drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${date_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/3:enable='between(t,0,5)',drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${number_text} ${mydeck_text}VS${opdeck_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/1.27:enable='between(t,0,5)',format=pix_fmts=yuv420p" -an -movflags +faststart -crf 20 -an -r 30 tmp1.mp4 -y echo -e "file tmp1.mp4\nfile tmp2.mp4" > combine_files.dat </dev/null ffmpeg -f concat -i combine_files.dat -c:v copy -an -map 0:v $remake_name -y done ``` ### time record ```bash= movies=($(ls C_*.mp4 -v)) movie=${movies[0]} movie_time_all=0 opdeck_text_before="" :>time_record.dat for movie in ${movies[@]}; do before_name=$(echo $movie | sed "s/^C_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") if [ ${number_text#*-} = "1" ]; then time_min=$(($movie_time_all / 60)) time_sec=$(($movie_time_all % 60)) if [ $time_sec -le 9 ]; then time_sec=0$time_sec fi echo "${time_min}:${time_sec} ${mydeck_text} Vs ${opdeck_text}" >> time_record.dat fi movie_time_all=$(($movie_time + $movie_time_all)) done dir_name=$( pwd | awk -F"/" '{print $(NF)}') ls C_*.mp4 -v | sed "s/^/file /" > combine_files.dat </dev/null ffmpeg -f concat -i combine_files.dat -c copy -an -map 0:v ${dir_name}.mp4 -y ``` ```bash= ls C_*.mp4 -v | sed "s/^C_/A_/" >> files.dat #rename "s/^B_/B2_/" B_*.mp4 movies=($(ls B2_*.mp4)) for movie in ${movies[@]}; do movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") remake_name=$(echo $movie | sed "s/^B2_/B_/") movie_time_out=$(($movie_time - 2)) echo "ffmpeg -i $movie -c copy -t $movie_time_out -r 30 ${remake_name} -y" | xclip xclip -o | bash done ``` ## ADS ### はじめ & 末尾カット 1. ADSのリプレイをWindowsのゲームキャプチャ機能で録画 2. Bandicutで分割 `rename`をかけ、末尾のBandicutの広告を削除する。 なお、sortの関係で末尾の数字に0を挿入して2桁にそろえている。 ```bash= rename "s/ /_/g" *.mp4 rename "s/Project_Ignis__EDOPro_20//g" *.mp4 rename "s/^/A_/g" *.mp4 rename 's/_(\d)of/_0$1of/' *.mp4 ls -1 A_*.mp4 > files.dat # code files.dat for dir in 09; do cd $dir movies=($(ls A_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^A_/B_/g") movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") movie_time_out=$(($movie_time - 4)) echo "ffmpeg -i $movie -c copy -t $movie_time_out ${remake_name} -y" | xclip xclip -o | bash done cd .. done ``` ### 速度変更、fps調整 タイトル挿入をしない場合、再生速度の変更、fpsの調整が必要ならここで行う。 特にfpsがずれていると、動画作成や合成の際に音ズレや動画乱れの原因になる。 **atempoは0.5~2に値が制限されているが、`"atempo=2,atempo=1.5"`のように連続して使うことで任意の値をとれる。** 例の場合、2 * 1.5=3に対応する。 ```bash= # 必要なら30fpsにencode movies=($(ls B_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^B_/BB_/g") ffmpeg -i $movie -r 30 ${remake_name} -y done # 必要ならx1.5にencode movies=($(ls B_*.mp4)) # movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^B_/BBB_/g") ffmpeg -i $movie -vf "setpts=PTS/1.5" -af "atempo=1.5" -r 30 ${remake_name} -y done ``` ### 1.5倍速 & title挿入 & 合成 動画を1本につなげたり、再生速度変更、タイトル挿入などを行う。 `filtes.dat`の各行の構造は次の通り。 `自分のデッキ名` `相手のデッキ名` `対戦番号` ```bash= for dir in 06 07; do cd $dir movies=($(ls B_*.mp4)) movie=${movies[0]} for movie in ${movies[@]}; do remake_name=$(echo $movie | sed "s/^B_/C_/g") before_name=$(echo $movie | sed "s/^B_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') title_time=6 ffmpeg -i $movie -filter_complex "format=yuv444p, drawbox=y=ih*0.7:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,${title_time})', drawbox=y=ih*0.3:w=iw:h=120:t=max:color=black@0.4:enable='between(t,0,${title_time})', drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='${mydeck_text}':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/3:enable='between(t,0,${title_time})',drawtext=fontfile='/usr/share/fonts/truetype/fonts-japanese-mincho.ttf':text='Vs ${opdeck_text} / ${number_text} in match':fontcolor=white:fontsize=90:x=(w-tw)/2:y=(h-th)/1.27:enable='between(t,0,${title_time})',format=pix_fmts=yuv420p, setpts=PTS/1.5" -movflags +faststart -crf 20 -af "atempo=1.5" -r 30 ${remake_name} -y done cd .. done for dir in 06 07; do cd $dir ls C_*.mp4 -1 | sed "s/^/file /g" > combine_files_all.dat ffmpeg -f concat -i combine_files_all.dat -c:v copy -c:a copy -map 0:v -map 0:a? ${dir}_combined.mp4 -y cd .. done ``` ### time reocrd取得 複数の動画を合成した場合、1本ずつの再生時間を取得してタイムテーブルを作成したい場合がある。 `ffprobe`の結果を`grep`で適当に取得している。 どの処理段階の動画が残っているかでスクリプトが微妙に異なる。 - `A_*.mp4` : 末尾広告あり、等倍再生 ```bash= # obtain time record text for A_.mp4 for dir in 06 07; do cd $dir movies=($(ls C_*.mp4)) movie=${movies[0]} movie_time_all=0 opdeck_text_before="" :>time_record.dat for movie in ${movies[@]}; do before_name=$(echo $movie | sed "s/^C_/A_/g") mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") if [ ${number_text#*-} = "1" ]; then time_min=$(($movie_time_all / 60)) time_sec=$(($movie_time_all % 60)) if [ $time_sec -le 9 ]; then time_sec=0$time_sec fi echo "${time_min}:${time_sec} ${opdeck_text}" >> time_record.dat fi movie_time_all=$(($movie_time + $movie_time_all)) done cd .. done ``` - `C_*.mp4` : 末尾広告カット済み、1.5等倍再生 ```bash= # obtain time record text for C_*.mp4 for dir in 06 07; do cd $dir movies=($(ls A_*.mp4)) movie=${movies[0]} movie_time_all=0 opdeck_text_before="" :>time_record.dat for movie in ${movies[@]}; do before_name=$movie mydeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $2}') opdeck_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $3}') number_text=$(cat files.dat | grep ${before_name} | awk -F" " '{print $4}') movie_time=$(ffprobe $movie -hide_banner -show_entries format=duration | grep duration | sed -r "s/^duration=(\S+)\.\S+$/\1/g") movie_time=$(($movie_time - 4)) if [ $number_text = "1" ]; then movie_time_all_tmp=$(($movie_time_all / 3 * 2)) time_min=$(($movie_time_all_tmp / 60)) time_sec=$(($movie_time_all_tmp % 60)) if [ $time_sec -le 9 ]; then time_sec=0$time_sec fi echo "${time_min}:${time_sec} ${opdeck_text}" >> time_record.dat fi movie_time_all=$(($movie_time + $movie_time_all)) done cd .. done ``` ## divide / trim multiple 画面録画しながら、あらかじめ各試合の開始時間と終了時間をメモしておく。 各行は`mm:ss,mm:ss`の形にする。 ```bash= rename "s/ /_/g" *.mp4 rename "s/Project_Ignis__EDOPro_//g" *.mp4 rename "s/^/A_/g" *.mp4 movies=$(ls A_*.mp4) echo $movies | sed "s/ /\n/g" > trim_time.dat code trim_time.dat function calcTime(){ time=(${1//:/ }) min=${time[0]} sec=${time[1]} echo $((60 * $min + $sec)) } mode=0 # 0:test, 1:main movies=$(ls A_*.mp4) time_lines_tmp=$(cat trim_time.dat) time_lines=(${time_lines_tmp//\n/ }) movie="NaN" count=0 for line in ${time_lines[@]}; do if [[ ${line} == *.mp4 ]]; then movie=${line} elif [[ $movie != "NaN" ]] && [[ $line == *:*,*:* ]]; then splited=(${line//,/ }) start_time=$(calcTime ${splited[0]}) end_time=$(calcTime ${splited[1]}) video_time=$(($end_time - $start_time)) count=$(($count + 1)) count_zfilled=$(printf %02d $count) newName=$(echo $movie | sed -e s/^A_/B_/ -e s/\.mp4/_${count_zfilled}\.mp4/) echo $start_time $end_time $movie if [ $mode == 1 ]; then ffmpeg -ss ${start_time} -i $movie -t $video_time $newName -y else ffmpeg -ss ${start_time} -i $movie -t 2 $newName -y fi fi done ffmpeg -ss ${start_time} -i $movie -t $video_time $newName -y ``` ```bash= for file in $(ls B_*.mp4); do name_base=$(echo $file | sed -r "s/_[0-9]+\.mp4$//") count=$(echo $file | sed -r "s/^.*_([0-9]+)\.mp4/\1/") count_zfilled=$(printf %02d $count) new_name="${name_base}_${count_zfilled}.mp4" mv $file $new_name -f done ls B_*.mp4 > video_memo.dat ``` ```bash= for fileName in $(find . -name "*.mp4" -printf "%f ");do ffmpeg -i $fileName -vf crop=w=690:h=1150:x=0:y=0 ../mos_$fileName; done ``` <a href="#top">TOPへ</a>