見出し画像

EPGStationでQSVエンコード 2024夏

過去に何度も挫折した EPGStationでQSVエンコードですが、ようやっと時間がある程度解決してくれました。嬉しかったので手順を忘れないうちにメモります。このご時世にHaswellとか…なんて言わないでください。化石を使い倒すのもSDGってもんです。

前提条件:

  • ハードウェア: VA-APIに対応した内蔵グラフィックスを搭載したIntel Haswell以降 CPU。

  • オペレーティングシステム: Debian 12 (Bookworm)をインストールし、更新済みであること。

  • EPGStation / Mirakurun: docker-mirakurun-epgstationを正常にインストールし、動作確認が取れていること。

まずはコンテナ外で普通にVAAPIが動くことを確認しましょう

モジュールのインストール:

FFmpeg: VA-APIサポート付きの最新のFFmpegバージョンをインストールします。ソースからコンパイルするか、ビルド済みのパッケージを使用できます。

$ sudo apt install ffmpeg


Intelメディアドライバ:
Intelメディアドライバをインストールします。

$ sudo apt install libva-dev intel-media-va-driver intel-media-va-driver-non-free

これにより、Haswell CPUに適したi965ドライバがインストールされます。いらんものも入れてるかもしれませんが、どれが必須でどれがそうでないかあんまり確認してないです。


追加ツール (オプションですが推奨):

$ sudo apt install vainfo intel-gpu-tools
  • vainfo: VA-APIのインストールと機能を確認します。root / sudoでの実行が必要。

  • intel-gpu-tools: intel_gpu_topでエンコード中のGPU使用率を監視します。これもroot / sudoでの実行が必要。

トラブルシューティングと解決策:

ドライバの問題:

  • Intelグラフィックスドライバが最新であり、VA-APIをサポートしていることを確認してください。IntelのWebサイトで更新プログラムを確認できます。

  • 問題が発生した場合は、sudo apt install --reinstall intel-media-va-driver intel-media-va-driver-non-freeを使用してメディアドライバを再インストールしてみてください。

自動フィルター挿入:

  • FFmpegが問題を引き起こすフィルターを自動的に追加している場合は、-vfオプションを使用してコマンドでフィルターを手動で指定します。

スケーリング:

  • ビデオのサイズを変更する必要がある場合は、scale_vaapiフィルターを使用し、Intel GPUがVA-APIベースのスケーリングをサポートしていることを確認してください。

権限の問題:

  • VA-APIデバイスへのアクセスで問題が発生した場合は、権限を変更してください:

私の環境で動作したFFmpegコマンド:

$ ffmpeg -hwaccel vaapi ¥
         -vaapi_device /dev/dri/renderD128 ¥
         -i input.mp2ts ¥
         -map 0:v:0 -map 0:a:0 ¥
         -vf 'format=nv12,hwupload' ¥
         -c:a copy -c:v h264_vaapi 
         -profile:v 77 -level 40 -qp 23 outfinal.mp4

オプションの説明:

  • ハードウェアアクセラレーション: ビデオ処理にVA-APIを有効にします。

  • VA-APIデバイス: VA-APIに使用するデバイスを指定します (通常は/dev/dri/renderD128)。

  • 入力とストリームの選択: 入力ファイル (i) を指定し、最初のビデオ (map 0:v:0) とオーディオ (map 0:a:0) ストリームを選択します。

  • ビデオフィルター:

    • format=nv12: ハードウェアエンコード用にビデオをNV12形式に変換します。

    • hwupload: ビデオフレームをGPUにアップロードします。

  • エンコード:

    • c:a copy: オーディオストリームを再エンコードせずにコピーします。

    • c:v h264_vaapi: VA-APIを使用してビデオをH.264でエンコードします。

    • profile:v 77 -level 40: 互換性のために一般的なH.264プロファイルとレベルを設定します。

    • qp 23: 画質の量子化パラメータを設定します (好みに合わせて調整してください)。

  • 出力: 出力ファイル名 (outfinal.mp4) を指定します。

次はコンテナ内で試してみましょう

コンテナの外でうまく行くことが確認できたら、動作したffmpegのコマンドを控えておきましょう。
次に、EPGStationのコンテナ内のffmpegで動作しないと意味ないので、docker-composeの中に入って検証します。

コンテナから必要なハードを参照できるようにする

まずは、以下の記事にある通り、docker-mirakurun-epgstationの中のdocker-compose.ymlを修正します。要するに以下をepgstationセクションに追記ないしコメントアウトします。

devices:
   - /dev/dri:/dev/dri

その後コンテナ再起動。

$ sudo docker-compose down
$ sudo docker-compose up -d

コンテナ内でffmpegのHWエンコード動作確認

この次は、以下記事の中を参照しつつコンテナ内に入ります。
https://qiita.com/tsuboyataiki/items/90dbe94553d3dea39b19

$ cd <docker-mirakurun-epgstationのディレクトリ>
$ sudo docker-compose exec epgstation bash

その状態で、コンテナ外と同様にffmpegを走らせて、問題なく動作するか確認します。  

$ ffmpeg -hwaccels

これ動かしてみて、Hardware acceleration methodsにvaapiが出てこなかったら、リビルドが多分必要です。私は必要なかったのでわかりませんが。

最後にEPGStationのGUIから呼び出せるようにする

コンテナ内でのHWエンコードが首尾よくうまく行ったら、EPGStationのエンコードオプションを追加します。

epgstation/config/の中に、env_vaapi.shをつくります。中身は以下:

#!/bin/bash

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -i "$INPUT" -map 0:v:0 -map 0:a:0 -vf 'format=nv12,hwupload' -c:a copy -c:v h264_vaapi -profile:v 100 -level 40 -qp 23 "$OUTPUT"


できたら、以下のようにepgstation/config/config.ymlを修正します。

encode:
    - name: H.264
      cmd: '%NODE% %ROOT%/config/enc.js'
      suffix: .mp4
      rate: 4.0
    - name: H264/VAAPI
      cmd: /bin/bash %ROOT%/config/enc_vaapi.sh
      suffix: .mp4

- name: H264/VAAPI 以降が追記箇所。

ここまで済んだら、コンテナ再起動してブラウザリロードして、GUIからエンコード起動してみましょう。 intel_gpu_topでGPUがゴリゴリ使われており、htopでCPUがあまり使われてない(うちの環境・設定だと3割くらい)ことを確認して歓喜しましょう。

おまけ: エンコ後にNASにコピりたい

まずコピり先をマウントしましょう。/mnt/nasとでもしといてください。

次に、docker-mirakurun-epgstation/docker-compose.ymlを以下のように変更。

epgstation:
  build:
    〜以下略〜
  volumes:
    〜いろいろ書いてある〜
    - /mnt/nas:/app/nas

これでNASをコンテナ内から参照できるようになったので、エンコ後の処理を書きます。
docker-mirakurun-epgstation/epgstation/config にpostEncode.shとか適当な名前のテキストファイルを作成します。

#!/bin/bash

cp -f ${OUTPUTPATH} /app/nas

できたら、次にdocker-mirakurun-epgstation/epgstation/config/config.ymlに以下を追記します。どこでもいいらしいけど、意味合い的にencodeセクションの次、urlschemeの前くらいが良さそう。

encodingFinishCommand: '/bin/bash /app/config/postEncode.sh'

で、コンテナを再起動しておしまい。
参照:https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md#encodingfinishcommand

この記事が気に入ったらサポートをしてみませんか?