動画保存後に音声追加する方法

概要

撮影した映像に別途録音した音声を後から追加したい場合や、既存の映像に新たな音楽やナレーションを追加したい場合などに後から音声ファイルを動画ファイルに追加することができます。AIや機械学習の分野では、映像と音声の同期が必要な研究や開発においても利用されます。

出力結果

出力結果

ダウンロード(video_audio_addition_audio.mp3)

Moviepy - Building video output_with_sound.mp4. MoviePy - Writing audio in output_with_soundTEMP_MPY_wvf_snd.mp3 MoviePy - Done. Moviepy - Writing video output_with_sound.mp4 Moviepy - Done ! Moviepy - video ready output_with_sound.mp4

プログラム全体

#解説1 import cv2 from moviepy.editor import VideoFileClip, AudioFileClip #解説2 # UVCカメラを開く cap = cv2.VideoCapture(0) #解説3 # フレームレートを取得 fps = 30 # ビデオライターを作成 fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter('output_no_sound.mp4', fourcc, fps, (640, 480)) #解説4 # カメラが開いている間、フレームを読み込み、ビデオファイルに書き込む while(cap.isOpened()): ret, frame = cap.read() if ret==True: out.write(frame) cv2.imshow('frame',frame) # 'q'キーが押されたらループを抜ける if cv2.waitKey(1) & 0xFF == ord('q'): break else: break #解説5 # カメラとビデオライターを解放 cap.release() out.release() cv2.destroyAllWindows() #解説6 # moviepyを使用して音声を追加 # 音声なしのビデオファイルを読み込む video_clip = VideoFileClip('output_no_sound.mp4') # 音声ファイルを読み込む audio_clip = AudioFileClip('audio.mp3') # ここで音声ファイルを指定 # ビデオクリップに音声をセット video_clip = video_clip.set_audio(audio_clip) # 音声付きのビデオファイルとして保存 video_clip.write_videofile('output_with_sound.mp4')

解説

解説1: ライブラリのインポート

import cv2 from moviepy.editor import VideoFileClip, AudioFileClip

この部分では、プログラムで使用するライブラリをインポートしています。cv2はOpenCVのPythonライブラリで、画像処理や動画処理を行うための機能が提供されています。VideoFileClipAudioFileClipは、moviepy.editorライブラリからインポートされており、それぞれ動画ファイルと音声ファイルを扱うためのクラスです。

Pythonのmoviepy.editorモジュールをインストールするには、Pythonのパッケージ管理ツールであるpipを使用します。以下のコマンドをターミナル(Windowsの場合はコマンドプロンプトまたはPowerShell)に入力して実行します。

pip install moviepy

このコマンドはmoviepyパッケージ全体をインストールします。moviepy.editorはその中の一部です。

なお、Pythonの環境によっては、pipではなくpip3を使用する必要があるかもしれません。また、パーミッションの問題が発生する場合は、コマンドの先頭にsudoを追加する(LinuxやmacOSの場合)か、コマンドプロンプトを管理者として実行する(Windowsの場合)必要があります。

解説2: カメラの開始

cap = cv2.VideoCapture(0)

ここでは、UVCカメラを開いて、その映像を取得するためのオブジェクトを作成しています。cv2.VideoCapture(0)という関数は、引数にUVCカメラのIDを取り、そのカメラにアクセスするためのVideoCaptureオブジェクトを返しています。ここでの0は、通常はシステムに接続されているデフォルトのカメラ(通常は内蔵カメラ)を指しますが、使用しているカメラによって割り振られる番号が異なりますのでご注意ください。

補足:OpenCVにおけるデバイスID

デバイスが複数接続された場合、このIDは、いつも同じとは限りません。デバイスの起動やシステムへの接続順によって変わることがほとんどです。 TheImagingSource社が提供しているSDK(ICImagingControl)ではカメラ本体にシリアル番号が割り振られており、カメラ毎に設定が容易にできます。詳細は下記をご覧ください。 https://www.argocorp.com/software/sdk/ICImagingControl/Sample_program/Python_34/open-with-built-in-dialog.html

解説3: ビデオライターの作成

fps = 30 fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter('output_no_sound.mp4', fourcc, fps, (640, 480))

この部分では、動画ファイルを作成するためのビデオライターを設定しています。fpsはフレームレートを、fourccは動画ファイルのコーデックを指定しています。cv2.VideoWriter`はビデオライターのインスタンスを作成します。引数には出力ファイル名、コーデック、フレームレート、フレームサイズを指定します。

fps = 30:fpsでは1秒あたり30フレームの動画を作成することを意味しています。 fourcc = cv2.VideoWriter_fourcc(*'mp4v'):fourccはビデオコーデックを指定するためのものです。ここでは'mp4v'を指定しています。'mp4v'はMPEG-4ビデオコーデックを表します。fourccは、ビデオデータの圧縮形式を指定するために使用されます。

out = cv2.VideoWriter('output_no_sound.mp4', fourcc, fps, (640, 480)):VideoWriterオブジェクトを作成します。第一引数には出力ファイル名(ここでは'output_no_sound.mp4')、第二引数にはfourcc(ビデオコーデック)、第三引数にはfps(フレームレート)、第四引数にはフレームのサイズ(ここでは幅640ピクセル、高さ480ピクセル)を指定します。この例では、'output_no_sound.mp4'という名前のMPEG-4ビデオファイルを作成し、そのフレームレートを30fps、フレームのサイズを640x480に設定しています。このように、VideoWriterを使用することで、カメラから取得した映像を指定したビデオコーデックとフレームレートで動画ファイルとして保存することができます。

解説4: フレームの読み込みと保存

while(cap.isOpened()): ret, frame = cap.read() if ret==True: out.write(frame) cv2.imshow('frame',frame) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break

カメラが正常に開いている間に、while文のループ処理をしています。ループ処理の中で、cap.read()を使ってカメラからフレームを取得します。その際に正常に画像を取得できていれば、out.write(frame)を使ってcv2.VideoWriterオブジェクトを使って、output_no_sound.mp4のビデオファイルに書き込む処理を行っています。また、cv2.imshow('frame',frame)は取得したフレームを画面に表示します。 cv2.waitKey(1) & 0xFF == ord('q')は、'q'キーが押されたらループ処理から抜け出します。

解説5: リソースの解放

cap.release() out.release() cv2.destroyAllWindows()

ここでは、使用したリソースを解放しています。cap.release()でカメラを解放し、out.release()でビデオライターを解放します。cv2.destroyAllWindows()で開いたウィンドウを全て閉じます。

解説6: 音声の追加

video_clip = VideoFileClip('output_no_sound.mp4') audio_clip = AudioFileClip('audio.mp3') video_clip = video_clip.set_audio(audio_clip) video_clip.write_videofile('output_with_sound.mp4')

ここでは、moviepyを使用して解説4で作成した動画ファイルに音声を追加しています。 まず、音声なしの動画ファイルと音声ファイルを読み込みます。次に、set_audioメソッドを使用して動画ファイルに音声をセットします。最後に、write_videofileメソッドを使用して音声付きの動画ファイルとして保存します。

補足:

VideoFileClipとAudioFileClipの長さが異なる場合、set_audioメソッドは以下のように動作します。

音声(audio.mp3)の長さが動画ファイル(output_no_sound.mp4)の長さより短い場合 音声はその長さまで再生され、その後は無音になります。つまり、動画の残りの部分は無音になります。
音声(audio.mp3)の長さが動画ファイル(output_no_sound.mp4)の長さより長い場合 ビデオクリップの長さに合わせて音声クリップは切り詰められます。つまり、動画ファイルが終了すると音声も同時に終了し、音声クリップの残りの部分は無視されます。

したがって、動画ファイルと音声の長さが一致しない場合でも、set_audioメソッドは問題なく動作しますが、動画ファイルと音声の長さが一致しないと、動画の一部が無音になったり、音声が途中で切れたりする可能性があるため、できるだけ動画ファイルと音声の長さは一致させることをおすすめします。