LoginSignup
15
15

More than 3 years have passed since last update.

動画編集(ジャンプカット)を自動化してみた!

Posted at

参考にさせていただいた記事

この記事を参考にさせていただきました。
https://qiita.com/merarli/items/1b7819adbae7fad3c9b4

やったこと

YouTube動画の編集手法の一つである「ジャンプカット」の自動化に取り組みました。
Jupyter Notebookで作ってみました。OSはMacです。
FFmpegで無音時間を検出し、動画を切り出します。
こんな感じでできます。⇒ https://youtu.be/i2fFIWyXGXo

コード

import subprocess
import os
def mk_movieList(movie_folder):
    files = os.listdir(movie_folder)
    files = [x for x in files if x[-4:] == '.mp4']  ### x[-4]'後ろ4文字目以降'
    files = [x for x in files if x[0] != '.']
    return files

def mk_starts_ends(wk_dir, movie):
    os.chdir(wk_dir)
    output = subprocess.run(["ffmpeg", "-i", movie, "-af", "silencedetect=noise=-33dB:d=0.6", "-f", "null", "-"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(output)
    s = str(output)
    lines = s.split('\\n')
    time_list =[]
    for line in lines:
        if "silencedetect" in line:
            words = line.split(" ")
            for i in range(len(words)):
                if "silence_start" in words[i]:
                    time_list.append(float(words[i+1]))
                if "silence_end" in words[i]:
                    time_list.append(float(words[i+1]))
    print(time_list)
    starts_ends = list(zip(*[iter(time_list)]*2))
    return starts_ends

def mk_jumpcut(wk_dir, movie, starts_ends):
    os.chdir(wk_dir)
    for i in range(len(starts_ends)-1):
        movie_name = movie.split(".") 
        splitfile = "./JumpCut/" + movie_name[0] + "_" + str(i) + ".mp4"
        print(splitfile)
        output = subprocess.run(["ffmpeg", "-i", movie, "-ss", str(starts_ends[i][1]), "-t", str(starts_ends[i+1][0]-starts_ends[i][1]), splitfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
movie_folder = "ここに素材動画が入っているフォルダの場所を記載してください。"

os.chdir(movie_folder)
wk_dir = os.path.abspath(".")
try:
    os.mkdir("JumpCut")
except:
    pass

movie_list = mk_movieList(movie_folder)

for movie in movie_list:
    print(movie)
    starts_ends = mk_starts_ends(wk_dir, movie)
    print(starts_ends)
    mk_jumpcut(wk_dir, movie, starts_ends)

こんな感じになります。

スクリーンショット 2019-08-20 20.35.53.png
コード上の「movie_folder」で指定したフォルダの中に、更にJumpCutというフォルダができて...
スクリーンショット 2019-08-20 20.35.03.png
こんな感じに動画が分割されます。これをまとめて、動画編集ソフトにブチ込んで再生すると
ジャンプカット動画が完成してます!!!!

重要なところ

 output = subprocess.run(["ffmpeg", "-i", movie, "-af", "silencedetect=noise=-33dB:d=0.6", "-f", "null", "-"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

 この行が無音時間を検出するコマンドをsubprocessで回しています。
 「silencedetect=noise=-33dB:d=0.6」で無音状態の判定基準を決めています。
-33dBの音量が0.6秒続くと無音であると判定されるみたいです。
 ここのパラメータは、動画ごとに調整が結構必要ですね。
 ここで、返っていた結果をテキスト処理して、[無音開始時間,無音終了時間]のリストを作り、それをmk_jumpcutに渡して、動画を切り出しています。

一番良い感じの使い道

無音状態の判定基準を緩くして、長回しの動画で音声がある部分を切り取りたいときとか、
粗編集的に使うのが便利そうです。
完成版のジャンプカットを完全に自動化するには、パラメータの調整が必要になってきます。

15
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15