今まではラズパイピコ内のフラッシュメモリに保存したファイル(バイナリ形式)を
表示してたけど今度はmicroSDに保存してそれを読み出して表示してみる
表示するアニメーション
↓ゆゆ式OPから5秒抽出した動画
動画を各フレームをバイナリ形式の画像ファイルに変換する
anacondaでmoviepyをインストールした仮想環境を作ってチャチャっとPCでやった。
どんなに早く再生できたとしても7fpsが最速なのは前に実験したから
7fpsの240*135という仮定で各フレームをバイナリ形式に変換する。
from moviepy.editor import VideoFileClip
from PIL import Image
clip = VideoFileClip("test_video.mp4")
# フレームレートを7fpsに変更
clip = clip.set_fps(7)
# フレームを順に保存
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()
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) # 下位バイト
# バイナリファイルとして保存
with open(f"frame_{i:04d}.bin", "wb") as f:
f.write(rgb565)
clip.close()
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 = 'frame_'
bin_ext = '.bin'
frame_num = 0
while True:
file_full_path = video_path + video_basename + f'{frame_num:04}' + bin_ext
try:
with open(file_full_path, "rb") as f:
buf = f.read()
tft.blit_buffer(buf, 0, 0, 240, 135)
# メモリ確保のために変数を削除
del file_full_path
del buf
except OSError:
if frame_num == 0:
print('最初のフレームが見つかりません')
else:
print('最終フレームに到達しました')
break
frame_num += 1
print('完了')
今までのテストソースとほぼ同じ
ファイルがopenできる連番まで順に表示していって、存在しない連番になったらcatchするような仕組み。
表示してみた結果
おっせ~
1.1fpsくらい?
こんなもんアニメじゃねえ、紙芝居だ。
おわりに
次回からはフレームレートを上げるための試行錯誤をしていきたいと思います。