はじめに
PythonでOpenCVを使って画像をMP4形式の動画に変換したところ、フォト(Windowsアプリ)では表示されるが、Telegram上では表示されないという挙動が怪しいファイルになってしまった。
結論から述べるとコーデックの形式が悪かったのだけど、少し面倒だったので解決策を残しておく。
実行環境
- Windows 10
- Python 3.10.6
- opencv-python 4.8.1.78
コード
実行したコードは以下の通り。
# 省略
_MP4V = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
def create_mp4_from_images(root_dir: str, out_path: str, exts: list[str]=['.png'], codec=_H264, fps: float=30.0, recursive: bool=False) -> None:
# フォルダから画像ファイルを抽出
image_path_list = sorted(glob_with_exts(root_dir, exts, recursive))
# 見つからない場合はエラー
if len(image_path_list) == 0:
print('no such image files')
return
# 一つ取り出して動画の縦横サイズを取得
height, width, _ = cv2.imread(image_path_list[0]).shape
writer = cv2.VideoWriter(out_path, codec, fps, (width, height))
for image_path in image_path_list:
image = cv2.imread(image_path)
writer.write(image)
writer.release()
print(f'{out_path} created')
# 省略
if __name__ == '__main__':
create_mp4_from_images('C:/Users/xxx/downloads', 'C:/Users/xxx/downloads/xxx.mp4', codec=_MP4V)
エラー内容
これで動画を出力するとフォトでは普通に表示されるが、ブラウザ版のTelegramでは以下のエラーメッセージが出て表示されない。
Unfortunately, this video can't be played on Telegram Web.
Try opening it with our desktop app instead.
原因と解決策
MP4V形式は大方のブラウザで対応していないため、H264形式で出力する必要がある。
H264形式で出力するにはcv2.VideoWriter_fourcc('m', 'p', '4', 'v')
をcv2.VideoWriter_fourcc('h', '2', '6', '4')
に変更すればOK…という訳にはいかない。変更して実行すると下記のエラーメッセージが出力されて動作しない。
Failed to load OpenH264 library: openh264-1.8.0-win64.dll
Please check environment and/or download library: https://github.com/cisco/openh264/releases
[libopenh264 @ 000001f0b4d19880] Incorrect library version loaded
[ERROR:0@0.011] global cap_ffmpeg_impl.hpp:3076 open Could not open codec libopenh264, error: Unspecified error (-22)
[ERROR:0@0.012] global cap_ffmpeg_impl.hpp:3093 open VIDEOIO/FFMPEG: Failed to initialize VideoWriter
これを解決するため、エラーメッセージに従ってopenh264ライブラリを下記の手順で配置してやる必要がある。
openh264ライブラリ配置手順
- github cisco/openh264にアクセス
- エラーメッセージに表示されているライブラリ名を確認(上記例だと
openh264-1.8.0-win64.dll
) - releases内を確認して同名のライブラリ名.bz2をダウンロード(Releaseバージョン一番下のAssetsの矢印をクリックすれば展開されてダウンロードリストが表示される)
- ダウンロードしたファイルを
7zip
等で解凍 - 解凍した*.dllファイルをPythonをインストールしたフォルダに配置(Pythonのインストール先はコマンドプロンプトで
python -c "import sys; print(sys.base_prefix)"
で確認可能)
上記手順を踏むとCisco製のOpenH264ライブラリを使っていますというメッセージ共にH264形式の動画が出力される。
OpenCV: FFMPEG: tag 0x34363268/'h264' is not supported with codec id 27 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
OpenH264 Video Codec provided by Cisco Systems, Inc.