こしあん
2019-06-27

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


25.6k{icon} {views}


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が必要になるので、必要なバージョンを正確にダウンロードしましょう。

以上です。



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


2 Comments

Add a Comment

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