はじめに
先日記事を書いた Image モジュールを使って、 Livebook 上で動画を再生します
Image モジュールの動画関連処理は内部的に evision を使っています
実行環境
- Elixir: 1.14.2 OTP 24
- Livebook: 0.8.1
以下のリポジトリーの Docker コンテナ上で起動しています
Docker が使える環境であれば簡単に実行できます
https://docs.docker.com/engine/install/
Docker Desktop を無償利用できない場合は Rancher Desktop を使ってください
実行環境の注意点
Image (Vix) を使うためには libvpc が必要です
また、 evision の動画関連処理を実行するためには、 FFmpeg をインストールしてからビルドする必要があります
Ubuntu の場合は以下のモジュールを apt-get install
してください
- unzip
- ffmpeg
- libavcodec-dev
- libavformat-dev
- libavutil-dev
- libswscale-dev
事前準備
適当な動画を以下のパスに用意したものとします
- /tmp/sample.mp4 (なんでも良い)
セットアップ
必要なモジュールをインストールします
Mix.install(
[
{:image, "~> 0.23"},
{:evision, "~> 0.1"},
{:req, "~> 0.3"},
{:kino, "~> 0.8"}
],
system_env: [
{"EVISION_PREFER_PRECOMPILED", "false"}
]
)
環境変数 EVISION_PREFER_PRECOMPILED
に false
を指定することで、 evision をソースからコンパイルするよう指定しています
evision のコンパイルには非常に時間がかかるため、30分程度待ちます
動画の読込
Image.Video.open
で動画ファイルを開きます
video = Image.Video.open!("/tmp/sample.mp4")
Image.Video.image_from_video
で動画内の1フレームを静止画として取得できます
オプションとしてフレーム番号とミリ秒単位での時間を指定できます
frame = Image.Video.image_from_video!(video, frame: 0)
Image.Kino.show(frame, max_height: 400)
frame = Image.Video.image_from_video!(video, millisecond: 3_000)
Image.Kino.show(frame, max_height: 400)
オプションを指定しない場合は前回読んだフレームの次のフレームを読み込みます
frame = Image.Video.image_from_video!(video)
Image.Kino.show(frame, max_height: 400)
Image.Video.stream
で動画ファイルを開くことで、各フレームを列挙型として扱えます
また、 frame
や millisecond
で範囲を指定することができます
というわけで、以下のコードで Livebook 上で動画が再生できます
"/tmp/sample.mp4"
|> Image.Video.stream!(frame: 0..-1)
|> Kino.animate(0, fn frame, counter ->
if frame do
frame
|> Image.Kino.show(max_height: 400)
|> then(&{:cont, &1, counter + 1})
else
:halt
end
end)
まとめ
かなり短いコードで簡単に動画が読み込めました
次は動画を加工してみましょう