コマンド1発でYouTubeのダイジェスト生成

第18回のしれごとがてらで「デザイナーはシェルスクリプトでもっと生産的に!」という話をしました.そこでお話しした「YouTube動画を1分に短くまとめるシェルスクリプト」をここに公開します.

しれごとがてら 第18回 本編

ダイジェストの例

まずはダイジェストの例を見てみてください.具体的には下に書くような条件で動画をギュッと自動で編集したものになります.とは言え,読むよりも見たほうが理解は早いと思います.

しれごとがてら 第18回 ダイジェスト
  • 動画をちょうど1分に短縮 (早送り)
  • 動画の元の音声はミュート.代わりに好きなBGMを追加可能
  • 冒頭の3秒間はYouTubeで設定されたサムネイルを表示
  • 終わりの3秒はフェードアウト (暗転 + 消音)

この編集を一括・自動でやってくれるスクリプトの紹介です!

スクリプト

#!/bin/bash
# 引数は [YouTube動画のURL] と [出力ファイル名]
# youtube-dl と ffmpeg と curl が前提
# カレントディレクトリに bgm.mp3 を置くこと

##################################################
# prefix and suffix of the thumbnail URL
prefix="http://img.youtube.com/vi/"
suffix="/maxresdefault.jpg"

# Parameters setting
id=`echo ${1} | grep -oP "(?<==)(.+)"` # target id
url=$prefix$id$suffix # thumbnail url
vid_sec=60 # output video duration in sec
fadetime="3" # fade out duration in sec

# file names ... used in command line
bgm="bgm.mp3" # bgm file path
thumb="${2}.jpg"
video="${2}.mp4"
mute="${2}_mute.mp4"
short="${2}_short.mp4"
sound="${2}_sound.mp4"
thumb_scaled="${2}_scaled.jpg"
outname="./digests/${2}.mp4" #output video path and filename

# make directory if not exist
mkdir -p digests

##################################################
# download the thumnail image
curl -o ${thumb} ${url}

# download video
youtube-dl -o ${video} -f mp4 ${1}

##################################################
# get video duration
duration=`ffmpeg -i ${video} 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'`

# remove audio
ffmpeg -y -i ${video} -c copy -an ${mute}

# change duration into ${vid_sec}
# ${mute} -> ${short}
ffmpeg -y -i ${mute} -filter:v "setpts=${vid_sec}*PTS/${duration}" ${short}

# change thumbnail size as same as video resolution
# get x size of "${short}"
width=`ffprobe -v error -select_streams v:0 -show_entries stream=width -of default=nw=1:nk=1 ${short}`
ffmpeg -y -i ${thumb} -vf scale=${width}:-1 ${thumb_scaled}

# add thumbnail at beginning and bgm
# ${short} -> ${sound}
ffmpeg -y -i ${short} -i ${thumb_scaled} -filter_complex "[0:v][1:v]overlay=0:0:enable=between(t,0,3)" -i ${bgm} -shortest ${sound}

##################################################
# get frame rate
fr=`ffmpeg -i ${sound} 2>&1 | sed -n "s/.*, (.*) fp.*/1/p"`

fadestarttime=`expr ${vid_sec} - ${fadetime}`
fadingtime=${fadetime}

fadestartframe=`echo "scale=5; ${fadestarttime} * ${fr}" | bc`
fadingframe=`echo "scale=5; ${fadetime} * ${fr}" | bc`

# fade out at end
# And encode for Twitter
ffmpeg -y -i ${sound} -vf "fade=out:${fadestartframe}:${fadingframe}" -af "afade=out:st=${fadestarttime}:d=${fadingtime}" -vcodec libx264 -pix_fmt yuv420p -strict -2 -acodec aac ${outname}

##################################################
# remove all intermediate files
rm ${mute} ${short} ${thumb_scaled} ${sound} ${thumb} ${video}

exit 0

使い方

  1. このスクリプトをyt-digest.sh などの名前で任意の場所に保存
  2. 同じ階層に bgm.mp3 を設置
  3. ./yt-igest.sh [YouTube Video URL] [output name] を実行
  4. ./digests/[output name].mp4 というファイルが生成されます

./yt-digest.sh https://www.youtube.com/watch?v=naneHUHwvxI tutorial-101

注意

  1. youtube-dlcurlffmpeg が必要です.使用の前にインストールしておいてください.
  2. スクリプトに2つの引数を与えてください.[YouTube Video URL][output name] です.
  3. [ouput name] には,拡張子を除いた名前を入れてください.出力ファイルは [output name].mp4 になります.

免責

私はグラフィックデザイナーであり,プログラマーではありません!この実装は最適とは程遠いと思いますので,実装の非効率があればご指摘いただけますとありがたいです!

“コマンド1発でYouTubeのダイジェスト生成” への2件の返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください