忙しい人用
VideoFileClip().write_videofileのlogger引数にproglog.ProgressBarLoggerを継承したクラスを渡して上手いことやる
きっかけ
こんなものを作っていざ実行ファイル化したいとなったときに僕は思いました
「moviepyの動画書き出しの進捗、コンソールに出されるけどどうしよう」
と
最初は面倒くさそうと思って普通にコンソールも表示させてました
しかし、やはり動画の書き出しだけCUIに進捗出すのはどうなのかと思い、偉大なるGoogle様に質問させていただきました
実装してみる
Google様から得られた情報をもとに、「動画に音声をつけ、かつその進捗をGUIとして表示する」という処理を実装してみるとこうなります(今回はGUIにwxPythonを使ってます)
import wx
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.VideoClip import proglog # moviepyの依存ライブラリにありますよ〜ってことを示すためにわざとmoviepyからインポートしてます
class WriteVideoProgress(proglog.ProgressBarLogger):
def __init__(self, progress, *args, **kwargs):
super().__init__(*args, **kwargs)
self.progress = progress
self.reading_audio = False
def callback(self, *_, **__):
pass
def bars_callback(self, bar, attr, value, old_value=None):
total = self.bars[bar]["total"]
p = int(value / total * 100)
if old_value is None:
self.reading_audio = not self.reading_audio
self.msg = "音声の読み込み中... {}/{}" if self.reading_audio else "動画の書き出し中... {}/{}"
self.progress.Update(99 if 100 <= p else p, newmsg=self.msg.format(value, total))
dlg = wx.ProgressDialog(title="動画書き出し", message="音声の読み込み中...", style=wx.PD_APP_MODAL | wx.PD_ESTIMATED_TIME | wx.PD_REMAINING_TIME)
dlg.Show()
video = VideoFileClip(video_path)
audio = AudioFileClip(audio_path)
video.set_audio(audio)
video.write_videofile(to_path, verbose=False, logger=WriteVideoProgress(dlg))
dlg.Update(100, newmsg="処理が完了しました")
もちろんこれ単体では動きません(wx.Appを生成してなかったり変数定義してないので)
参考程度によろしくお願いします
あとこれ小ネタなんですけど、動画に音声をつける処理に関してはbars_callbackのold_value引数は最初(つまり音声読み込みが始まったとき)と動画の書き出しが始まったときにNoneをとります
これを利用するとダイアログメッセージをいい感じに変えることができます