こしあん
2019-06-27

OpenCVで作成した動画がブラウザで正常に表示できない場合の解決法

Pocket
LINEで送る


OpenCVで作成した動画をサイトで表示する場合、ローカルで再生できていても、ブラウザ上では突然プレビューがでなり、ハマることがあります。原因の特定が難しい現象ですが、動画を作成する際にH.264形式でエンコードするとうまくいきました。その方法を解説します。

MPV4は手軽だが…

OpenCVで動画を作成する例で検索すると、おそらくこっちのほうが多く出てくると思うのですが、fourccにMP4Vを指定するパターンです。

directory以下のPNGファイルを1つのMP4ファイルにまとめてみましょう。

import cv2
import glob

# よくある例
def create_mp4(directory):
    # コーデックの指定
    fourcc = cv2.VideoWriter_fourcc("m", "p", "4", "v")
    # 引数はファイル名、コーデック、FPS、解像度(横、縦)
    video = cv2.VideoWriter(directory+".mp4", fourcc, 5.0, (640, 480))

    files = sorted(glob.glob(directory + "/*.png"))
    for f in files:
        img = cv2.imread(f)
        video.write(img)

これはローカルPCではうまく行きます。そしてメディアプレーヤーで再生してもちゃんと表示されます。しかし、作成した動画をブラウザで表示しようとすると急に沼にハマります

WordPressだとエラー

「Media error: Format(s) not supported or source(s) not found」というエラーが出てしまいます。

このエラーで検索すると、いくつかそれっぽい理由が出てきました。

  • ファイルサイズが上限にかかっていて正常にアップロードできない(php.iniに問題あるケース)
  • WordPressのバグだという主張

一点目は自分のサーバーだと128MBまでアップロードでき、ファイルサイズは10MB程度だったので引っかかることはありませんでした。サーバーのファイルマネージャーから当該のアップロード済ファイルをダウンロードして、ローカルPCのメディアプレーヤーで開くと正常に表示できました。したがって、アップロード自体に失敗しているということは考えられません。アップロード自体は成功しています。

二点目は例えばこちらのフォーラムにありますが、WordPressのバグだという説が浮上しています。しかし、明確な解決法は特に示されていませんでした。

一方で、MP4のURLを直打ちするとChromeでのプレビューは以下のようになりました。

プレビューができていない??

つまり、正常にアップロードできているのに再生ができないということになります。

ローカルファイルをChromeやFirefoxで開いてもエラー

なら作成したMP4のローカルファイルをChromeで開くとどうかというと、上の図と同じ状態になりました。

ブラウザを変えてみるとどうかというと、Firefoxでは次のようになりました。

Chromeと同様に再生できません。つまり、作成した動画ファイル自体に問題があるということになります。

原因はコーデック

諸悪の根源はコーデックでした。こちらのStackOverFlowの記事が参考になりました。

この記事によると、「MP4Vはほとんどのブラウザでサポートされていないから、代わりにH264を使いなさい」とのこと。H264への切り替えは簡単で、fourccの設定を、

fourcc = cv2.VideoWriter_fourcc("H", "2", "6", "4")

とするだけ。じゃあそのままこれで実行すれば終わりかというともう一歩あります。

OpenH264が必要

H.264でエンコードするにはOpenH264というライブラリが別途必要になります。主にライセンスの関係です。試しにOpenH264なしでエンコードしようとすると、

Failed to load OpenH264 library: openh264-1.8.0-win64.dll
        Please check environment and/or download library: https://github.com/cisco/openh264/releases

「OpenH264を取ってこい」と怒られてしまいます。

本来H.264を使うにはMPEG-LAにライセンス料を支払う必要があります。しかし、OepnH264という、Ciscoがオープンソースとして公開しているビルドされたライブラリを使う限りにおいては、このライセンス料をCiscoが肩代わりしてくれるという契約があるのです。OpenCVでOpenH264を必要としているのもこれが理由です。

また、過去のニュース:2011年を読んでいるとChromeがH.264のサポートを切る予定との報道もありましたが、現在はこのOpenH264を通じてChromeもFirefoxもH.264の再生は可能になっています。

しかし、これはあくまでビルド済みのバイナリを使う上では使用料いらないよということであって、オープンソースのコードを自分でビルドする場合はこの契約から外れるそうです(つまりライセンス料払う必要がある)。詳しくはこちら

早い話がOpenH264のリリースビルドを取ってくれば良いということなのでサクッとダウンロードします。

  1. https://github.com/cisco/openh264/releasesこのページにアクセス
  2. ただし、バージョンは正確に一致する必要がある。1.8.0を要求していて(この例)、2.0.0をダウンロードすると「バージョンが違うぞ」って怒られる。
  3. Windowsの場合は、OpenCVのバージョンにもよるが「openh264-1.8.0-win64.dll.bz2」をダウンロードすればOK
  4. ダウンロードしたアーカイブを解凍(WinRARでできる)
  5. dllファイルをPythonのカレントディレクトリにコピー

dllのコピーを忘れないようにしましょう。コードを実行するとH.264のMP4が出来上がります。

試しにローカルのMP4ファイルをFirefoxやChromeで開くと無事表示することができました。

アップロードし、WordPressでもちゃんとプレビューできるようになりました。やったぜ。

まとめ

OpenCVで保存した動画をブラウザ上で表示(サイト表示を含む)したいときは、H.264形式で保存するとよい。その際OpenH264が必要になるので、必要なバージョンを正確にダウンロードしましょう。

以上です。

Related Posts

PyTorchでSliced Wasserstein Distance (SWD)を実装した... PyTorchでSliced Wasserstein Distance (SWD)を実装してみました。オリジナルの実装はNumpyですが、これはPyTorchで実装しているので、GPU上で計算することができます。本来はGANの生成画像を評価するためのものですが、画像の分布不一致を見るためにも使うこ...
PyTorchで複数出力があるモデルの出力の型について... 出力が複数あるモデルの訓練というのは少し複雑なモデルだとよく出てきます。PyTorchでは複数出力のモデルの、出力の型はどうなっているでしょうか。それを見ていきます。中間層の値を取りたい場合も使えます。 サンプルコード import torch from torch import nn cl...
Kerasのジェネレーターでサンプルが列挙される順番について... Kerasの(カスタム)ジェネレーターでサンプルがどの順番で呼び出されるか、1ループ終わったあとにどういう処理がなされるのか調べてみました。ジェネレーターを自分で定義するとモデルの表現の幅は広がるものの、バグが起きやすくなるので「本当に順番が保証されるのか」や「ハマりどころ」を確認します。 0~...
Pillowでグレースケール化するときに3チャンネルで出力するテクニック... カラー画像をグレースケール化すると1チャンネルの出力になりますが、カラー画像と同時に扱うと整合性からグレースケールでも3チャンネルで欲しいことがあります。Numpyのブロードキャストを使わずに簡単に3チャンネルで出力する方法を書きます。 グレースケール化してカラー化すればOK これでOK i...
PyTorchでConvolutionフィルターをやる(エッジ検出やアンシャープマスク)... PyTorchでPILのConvolutionフィルター(エッジ検出やアンシャープマスク)をやりたくなったので、どう実装するか考えてみました。 やりたいこと PIL/PillowのConvolutionフィルター(ImageFilterなど)の処理をPyTorchの畳み込み演算で再現したい ...
Pocket
LINEで送る
Delicious にシェア

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です