本記事では、下図左のようにスマホで録画した場合、画面サイズが縦長になるのを下図右のようにアスペクト比を横長へ変更して、日本語文字列を挿入したりと加工しています。

下記リンク先が完成版で、音声も有りです。
www.youtube.com
■本記事で特筆するのは下記3つです。
1. 必要な箇所を開始,終了時間を指定することで抽出して、fpsも変更できてファイルを軽くできる。mp4ファイルで出力。
2. アスペクト比を保ったまま、解像度を指定サイズへ変更し、テキストも入れる。しかし、ここでは音はなし。mp4ファイルで出力。
3. 音声(音楽)を1の動画から抽出して、mp3ファイルで出力。それを2の動画へ結合してmp4ファイルで出力して完成する。
■本プログラム実行の流れ
◇①ライブラリのインストール
pip install opencv-python でOpenCVをインストールして、import cv2で使用
pip install moviepy でMoviePyをインストール
もし、pillow(PIL)がなれけば、conda もしは pipでインストールする。Apnacondaを入れていれば入ってるはず。
◇②使用ファイル
下図のようにファイルを二つ準備する。ひとつは、本記事に後述するコードを適当な名前「***.py」で保存する。そして、スマホ等で録画した動画を準備する。
下図の場合、python edit_mp4.py とすれば実行する。

◇③実行後
下図のようにファイルを4つ出力する。
完成版mp4は「zzz_out3_w_audio.mp4」です。その他は途中過程の中間ファイルを出力しています。例えば、mp3は音声のみ抽出したファイルです。

▼本プログラム
特記事項は、コードの下の方にある下記で入力因子の値を指定できます。
if __name__ == '__main__':
### 設定項目
input_video = "WGJB6714.mp4"
cut_time = (0, 137) # (start, end) second
out_audio = 'zzz_audio.mp3'
out_video1 = 'zzz_out1_simple.mp4'
out_video2 = 'zzz_out2_wo_audio.mp4'
out_video3 = 'zzz_out3_w_audio.mp4'
out_size = (1280, 720) # (width, height) = (1920, 1080)
fps = 30
import cv2
from PIL import Image, ImageFont, ImageDraw
import numpy as np
import moviepy.editor as mp
def simplification(input_file, out_file, cut_time, fps):
start, end = cut_time
video = mp.VideoFileClip(input_file).subclip(start, end)
video.write_videofile(out_file, fps=fps)
def image_add_message(img, message):
font_path = 'C:\Windows\Fonts\meiryo.ttc'
font_size = 54
font = ImageFont.truetype(font_path, font_size)
img = Image.fromarray(img)
draw = ImageDraw.Draw(img)
draw.text((50, 50), message, font=font, fill=(255, 255, 255, 0))
img = np.array(img)
return img
def edit_mp4(input_file, out_file, out_size, fps):
out_width, out_height = out_size
video = cv2.VideoCapture(input_file)
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
size = (width, height)
num_of_frame = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(video.get(cv2.CAP_PROP_FPS))
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
writer = cv2.VideoWriter(out_file, fourcc, fps, out_size)
scale = out_height / height
flag = num_of_frame // len(global_list)
j=0
k=0
for i in range(num_of_frame):
if i % 30 == 0:
print(str(i) + "/" + str(num_of_frame))
ret, frame = video.read()
new_frame = np.zeros((out_height, out_width, 3), np.uint8)
if out_width == width:
new_frame[0:out_height, 0:out_width] = frame
else:
frame = cv2.resize(frame, dsize=None, fx=scale, fy=scale)
frame_height, frame_width = frame.shape[:2]
offset = int((out_width - frame_width)*2/3)
new_frame[0:out_height, offset:(frame_width+offset)] = frame
'''
print("i -> " + str(i) + "/" + str(num_of_frame))
print("k/len(global_list) -> " + str(k) + "/" + str(len(global_list)))
print(global_list[k])
'''
new_frame = image_add_message(new_frame, global_list[k])
writer.write(new_frame)
j += 1
if flag < j:
j = 0
k += 1
writer.release()
video.release()
print(str(size) + " -> " + str(out_width) + "," + str(out_height))
print("num_of_frame -> " + str(num_of_frame))
print("fps -> " + str(fps))
def extract_audio(input_video1, input_video2, out_file, out_audio):
clip_in = mp.VideoFileClip(input_video1).subclip()
clip_in.audio.write_audiofile(out_audio)
clip_out = mp.VideoFileClip(input_video2).subclip()
clip_out.write_videofile(out_file, audio=out_audio)
global_list = ['ドラクエモンスターズ\nスーパーライト\n略して、DQMSL',
'配信開始は2014年\n今更、\nどんな感じなのかやってみた',
'スマホはiPhoneXR\n操作はヌルヌル動く',
'まだレベルが低いため\nほぼ単なる\n打撲攻撃だけ',
'ある程度進むめば\n面白しろそうと思った',
'ただ、ふと思う',
'こやつらは\n戦って\n仲間になる',
'なぜケンカする\n必要があるのか?\n',
'最初から、\n話しすれば済みそう(笑)',
'ところで、この元は\niPhoneの「画面収録」による\n3分の録画でした。',
'スマホゲームを録画すると\n アスペクト比が縦長になります。',
'編集は、\n普通のソフトを使わず\nPythonで次の4つを加工した。',
'1. fpsを60→30削減\n2. 尺を3分→2分程に短縮',
'3. 解像度を横長に変更\n4. 文章をこうして入れた',
'終わり',
]
if __name__ == '__main__':
input_video = "WGJB6714.mp4"
cut_time = (0, 137)
out_audio = 'zzz_audio.mp3'
out_video1 = 'zzz_out1_simple.mp4'
out_video2 = 'zzz_out2_wo_audio.mp4'
out_video3 = 'zzz_out3_w_audio.mp4'
out_size = (1280, 720)
fps = 30
simplification(input_video, out_video1, cut_time, fps)
input_video = out_video1
edit_mp4(input_video, out_video2, out_size, fps)
input_video1 = out_video1
input_video2 = out_video2
extract_audio(input_video1, input_video2, out_video3, out_audio)
##### 以下、参考にさせて頂いたHP
▼日本語挿入に関して、下記リンクの関数がそのまま使える形であったのでコピペさせて頂きました。https://watlab-blog.com/2019/08/25/image-text/
以上
<広告>
リンク