動画からの音声抽出と動画への音声結合

testpy.hatenablog.com

上記の記事で、動画を左右反転させて、新たな動画を生成した。 生成した動画には音声がないため、元の動画から音声を抽出して、結合してみた。

コード

# coding: utf-8
import sys
import cv2
import moviepy.editor as mp

class Test:
    def __init__(self):
        # Set video names.
        self.input_video = sys.argv[1]
        self.output_video = sys.argv[2]


    def main(self):
        self.set_audio()


    def set_audio(self):
        # Extract audio from input video.
        clip_input = mp.VideoFileClip(self.input_video).subclip()
        clip_input.audio.write_audiofile('audio.mp3')

        # Add audio to output video.
        clip_output = mp.VideoFileClip(self.output_video).subclip()
        clip_output.write_videofile(self.output_video.replace('.avi', '.mp4'), audio='audio.mp3')


if __name__ == "__main__":
    Test().main()

set_audio()が本体。前半2行で音声の抽出と保存、後半の2行で音声の結合を行っている。 結合する際、動画の拡張子がmp4じゃないとコーデックエラーが出る。 でも、mp4の方が容量が少ないので、それでいいかなと。

使い方

上記のコードをtest.pyで保存して、第一引数に入力動画名、第二引数に出力動画名(aviファイル)を指定する。

> python test.py input.MOV ouput.avi
[MoviePy] Writing audio in audio.mp3
100%|###################################################################################################################| 623/623 [00:00<00:00, 733.71it/s]
[MoviePy] Done.
[MoviePy] >>>> Building video output.mp4
[MoviePy] Writing video ouput.mp4
100%|####################################################################################################################| 846/846 [00:25<00:00, 33.65it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: output.mp4

>

動画の生成と音声の結合を同時に実行

前回行った動画の生成と、今回行った音声の結合を同時に行ってみた。 音声を結合した動画がmp4なので、生成する動画もmp4(コーデックはMP4S)にしたのだが、警告が出て、どうも上手く音声付きの動画が生成されない。 この辺は後ほど対応したい。

OpenCV: FFMPEG: tag 0x5334504d/'MP4S' is not supported with codec id 13 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x00000020/' ???'

同時に実行したコードを載せておく。 使い方は上に示したのと同じ。

# coding: utf-8
import sys
import cv2
import moviepy.editor as mp

class Test:
    def __init__(self):
        # Set video names.
        self.input_video = sys.argv[1]
        self.output_video = sys.argv[2]


    def main(self):
        self.make_video()
        self.set_audio()


    def make_video(self):
        # Get input video information.
        cap = cv2.VideoCapture(self.input_video)
        fps = int(cap.get(cv2.CAP_PROP_FPS))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        # Set output video infomation.
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        #fourcc = cv2.VideoWriter_fourcc(*'MP4S')
        vw = cv2.VideoWriter(self.output_video, fourcc, fps, (width, height))  # Set the above information.

        # Make the output video.
        print('Making a video...')
        while(True):
            ret, img = cap.read()
            if ret == True:
                img_flip = cv2.flip(img, 1)  # Flip horizontal
                vw.write(img_flip)  # Add frame
            else:
                break

        # Post processing.
        cap.release()
        cv2.destroyAllWindows()


    def set_audio(self):
        # Extract audio from input video.
        clip_input = mp.VideoFileClip(self.input_video).subclip()
        clip_input.audio.write_audiofile('audio.mp3')

        # Add audio to output video.
        clip_output = mp.VideoFileClip(self.output_video).subclip()
        clip_output.write_videofile(self.output_video.replace('.avi', '.mp4'), audio='audio.mp3')



if __name__ == "__main__":
    Test().main()

参考文献