【Python】moviepyで動画のトリミングとビットレート指定のエンコード
【状況】大きな動画から必要な部分を切り抜いて再エンコードしたい.さらに,元のビットレートだと高すぎるので調整してエンコードしたい.
【対処】切り抜きはmoviepyで簡単にできるものの,moviepy 1.0.3ではビットレートを取得できなかった(できなくなっていた?)のでOpenCVを使ってみた,のメモ(githubで議論はあったけどよく分からず).
moviepyを導入
切り抜きが簡単にできるmoviepyをインストール.執筆時点のバージョンは1.0.3.
pip install moviepy
OpenCVでビットレート取得
一番手間がかからなかったのがOpenCVを使った方法(なんかモヤモヤするけど.ffmpegを使う方法もある).
from moviepy.editor import VideoFileClip
from moviepy.video.fx.all import crop
import cv2
# 元の動画のビットレートを取得(OpenCV利用)
def get_bitrate(file_path): # ファイルパスを引数とする
cap = cv2.VideoCapture(file_path)
bitrate = cap.get(cv2.CAP_PROP_BITRATE) # 動画のビットレートを取得(単位:k)
cap.release()
return bitrate
# 元の動画ファイルから切り抜いて,指定したビットレートでエンコードする
def crop_and_encode(input_file, x1, y1, x2, y2, output_file, new_bitrate):
video = VideoFileClip(input_file)
# x2, y2を1ずつ増やさないと意図通りの切り抜きがされない(moviepy1.0.3)
clip = video.fx(crop, x1=x1, y1=y1, x2=x2+1, y2=y2+1)
# ビットレートを指定して切り抜きをエンコード
clip.write_videofile(output_file, codec='libx264', bitrate=f"{bitrate}k")
if __name__ == "__main__":
input_file = "input.mp4" # 入力動画ファイル名
output_file = "output.mp4" # 出力動画ファイル名
x1, y1 = 100, 100 # 画像の左上座標
x2, y2 = 819, 579 # 画像の右下座標
org_bitrate = get_bitrate(video_path)
new_bitrate = org_bitrate * 0.5 # 切り抜いた動画のビットレートを元の画像の半分にした
# 領域の幅と高さが16の倍数になっていることが望ましい(補正処理は省略)
crop_and_encode(input_file, x1, y1, x2, y2, output_file, new_bitrate)
これでできたからよし♪
※更新(2024.04.03)
クロップのパラメータ指定方法が「 x1 = x1, y1 = y1, x2 = x2, y2 = y2」のように座標値のまま与えたときに,縦横1ずつ少なく生成されていることが判
明.仕方ないので呼び出しの際に1ずつ増やしています.moviepy1.0.3時点.