8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Elixir Image で簡単動画再生

Last updated at Posted at 2023-02-02

はじめに

先日記事を書いた 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 を使ってください

https://rancherdesktop.io/

実行環境の注意点

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_PRECOMPILEDfalse を指定することで、 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_0.png

frame = Image.Video.image_from_video!(video, millisecond: 3_000)

Image.Kino.show(frame, max_height: 400)

frame_3000ms.png

オプションを指定しない場合は前回読んだフレームの次のフレームを読み込みます

frame = Image.Video.image_from_video!(video)

Image.Kino.show(frame, max_height: 400)

frame_next_from_3000ms.png

Image.Video.stream で動画ファイルを開くことで、各フレームを列挙型として扱えます

また、 framemillisecond で範囲を指定することができます

というわけで、以下のコードで 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)

video.gif

まとめ

かなり短いコードで簡単に動画が読み込めました

次は動画を加工してみましょう

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?