今回は
1つのバイナリファイルに全フレーム分のデータを連結して
ファイルのopenの回数を減らす作戦
全フレーム分のバイナリデータを1つファイルに出力する
from moviepy.editor import VideoFileClip
from PIL import Image
# 動画ファイル読み込み
clip = VideoFileClip("test_video.mp4")
# フレームレートを7fpsに変更
clip = clip.set_fps(7)
with open("all_frames.bin", "wb") as f:
for i, frame in enumerate(clip.iter_frames(fps=7)):
img = Image.fromarray(frame)
# サイズを240x135に変換
img = img.resize((240, 135))
# RGB888 → RGB565 に変換
img = img.convert("RGB")
rgb = img.tobytes() # RGB888のバイト列
rgb565 = bytearray()
for j in range(0, len(rgb), 3):
r = rgb[j]
g = rgb[j+1]
b = rgb[j+2]
# RGB565に変換(5bit R、6bit G、5bit B)
pixel = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
rgb565.append((pixel >> 8) & 0xFF) # 上位バイト
rgb565.append(pixel & 0xFF) # 下位バイト
f.write(rgb565)
clip.close()
出力されたall_frames.binはいつも通り、
ラズパイに繋いだmicroSD内のディレクトリ/sd/testvideo/にコピー
表示するソース
import tft_config
import time
import os
import sdcard
# SDcard 初期化
sd = sdcard.SDCard(machine.SPI(0), machine.Pin(28))
os.mount(sd, '/sd')
# LCD 初期化
tft = tft_config.config()
video_path = '/sd/testvideo/'
video_basename = 'all_frames'
bin_ext = '.bin'
frame_size = 240 * 135 * 2
file_full_path = video_path + video_basename + bin_ext
frame_num = 0
try:
f = open(file_full_path, "rb")
while True:
buf = f.read(frame_size)
if not buf or len(buf) < frame_size:
print('最後まで再生しました')
break
tft.blit_buffer(buf, 0, 0, 240, 135)
frame_num += 1
del buf
f.close()
except OSError:
if frame_num == 0:
print('最初のフレームが見つかりません')
else:
print('最終フレームに到達しました')
print('完了')
結果
5.2fpsくらい?マシになってきた
おわりに
次回、解像度下げます。