先日、ffmpegにsilencedetectなる機能があることを知った。これは動画や音声メディアファイルの無音や小さな音しか鳴ってない場所を調べて表示してくれるという優れもの。
ffmpegはメディアファイルを切り抜くことも可能なので、うまいことやると無音部分を好きなように、そして品質を落とさずに切り抜けるようになるはずだ。ちなみにsilenceremoveという、まさに無音を切り抜く機能もあるのだが、こちらを使うとファイルが再エンコードされてしまうらしいので注意が必要。

人間が思いつくことは似たり寄ったりなので「silencedetect」で検索すると、動画や音声ファイルから無音を切り取るスクリプトを書いて日本語で公開している人が何人かいた。(例1, 例2, 例3)
うーん、これらのスクリプトは無音を全部削除するっぽいけど、私が希望するのはファイルの冒頭と末尾、つまりイントロとアウトロの無音を削除してくれるだけでいい。というのも、私はYouTubeの動画から音声のみを抽出してラジオ替わりに聞くことがある。特に画面がほぼ変わらない動画とか、しゃべってる顔を映してるだけの動画とかは音声のみの方が色々と都合がよい。しかし、その様なYoutTube動画で困るのが、Liveのアーカイブ動画。冒頭が数分無音だったり、小さな音でフィラー音声が挿入されていることが多い。これらを削除してくれるだけでいいんだけど…。探せば誰かそういうのを作ってそうだけど、ここは勉強もかねて自分で書いてみた。動作するには実行ポリシーを設定したpowershell 5以上(Windows 11なら標準でOKのはずだ)とffmpegがPathにあることが必要。Pathを設定してなければ改変してハードコードすれば動く。どうせCC0なのでご自由にどうぞ。

silence_cut.ps1

最近、Windows 11にアップグレードしたのを機に、PowerShellスクリプトを見よう見まねで書くようになったのでその練習もかねてある。一行ごとにドキュメントを見るような状態なので「お察し」だけど。

私はこのスクリプトを前述のようにYouTube動画で使っている。具体的にはyoutube-dlと組み合わせてこんな感じに。

youtube-dl --extract-audio --exec 'powershell -File /path/to/silence_cut.ps1 {}' https://www.youtube.com/watch?v=video_id

標準で-30dB未満のファイルの開始2秒以内のイントロと末尾2秒以内に終わったアウトロの無音をバサッと削除している。フェードイン、フェードアウトするような動画の場合、若干の違和感があるかもしれないが、私は主にトーク動画の音声を対象としてるので今のところいい感じに動いている。