概要
streamlitによるWebアプリ開発時に,Webアプリ内でエンコードした動画が再生されない問題が発生.当該問題に対して考えられる原因の一つと,その解決策を提示する.
背景
実装したかったこと
- 画像処理を行った画像群から動画を作成
- 作成した動画をブラウザに表示
実装方法
動画エンコード
- 事前の処理で画像群のリストを作成
- opencv-pythonのVideoWriter()を使用
h, w, c = images[0].shape
fourcc = cv2.VideoWriter_foucc(*'mp4v')
video = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
for image in images:
video.write(image)
video.release()
ブラウザ表示
- streamlitのst.video()を使用
st.video(output_path)
問題
- ブラウザで開くと動画が再生されない
- エラーは出力されない
原因
- 動画に音声が入っていないこと
対策
- 動画に音声を合成する
- moviepyとsoundfileを使用
ライブラリのインストール
pip install moviepy soundfile
実装
# ライブラリのインポート
from moviepy.editor import ImageSequenceClip
from moviepy.audio.AudioClip import AudioArrayClip
import soundfile as sf
# 音が鳴らない音声データを作成
duration = n_frames / fps
silent_audio = np.zeros((int(duration * 22050), 2)
audio_clip = AudioArrayClip(silent_audio, fps=22050)
# 動画のエンコード
# opencvとmoviepyではRGBの順番が異なるので対応させる(BGR->RGB)
images = [cv2.cvtColor(image, cv2.COLOR_BGR2RGB) for image in images]
clip = ImageSequenceClip(images, fps=fps)
video_clip = clip.set_audio(audio_clip)
video_clip.write_videofile(output_path, codec='libx264', audio_codec='libvorbis', fps=fps)
st.video(output_path)
補足
- VSCodeで動画が開かない問題も音声を合成することによって解決