Chienomi

高解像度VP9動画群をFHD H.265に変換

Live With Linux::technique

VP9の試練

私が扱っている限り、圧倒的な重さを誇っているのがMMD動画である。 YouTubeは特にVP9を使うため再生はより一層重い。

MMD動画は同じ4kであってもものすごく重い傾向があるのだが、既に8kまで存在しており、非常に再生困難である。 様々な理由が絡んでいそうだが、現行手持ちのビデオカード(Nitro+ RX5700XT)ではVP9 8k MMDの再生は厳しい。

8kは置いておくとして、4k VP9の再生はCPUではかなり厳しい。Ryzen7 3700X, Ryzen7 5600Uともに4k VP9 MMDのCPU再生はどうしてもdropしてしまう。 基本的にVP9はハードウェアデコーディングを必要とするものと理解したほうが良いだろう。

だが、問題はP720はRX570を搭載しており、このビデオカードがVP9をサポートしないということだ。 VP9デコーディングは広く、IntelのCPU、及び比較的最近のNvidia(Pascal以降)とAMD(Vega RX以降)がサポートする。 しかし、P720はCPUにXeonを採用し、RX570ビデオカードを搭載しているためにVP9デコードの方法がない。 もちろん、Quadro P400に戻せばVP9デコードが取り戻せるわけだが、ビデオ性能が足りてないからRX570を乗せているわけで、選択の余地がない。

主に4k 60fpsのMMDがストックされている動画ディレクトリがあるが、大半はまともに再生できない。 新しいPCを早く入れたいと思っていたのだが、予定が立たないし、このままでは見づらいままなので、一時的に変換した動画も持つことにした。

変換スクリプト

#!/bin/zsh

DEST="$1"
shift

if [[ -z $DEST ]]
then
  print "NO DEST"
  exit 1
fi

for sourcefile in */*
do
  destfile="$DEST/${sourcefile:r}.mkv"
  print "DESTINATION:: $destfile"
  [[ -e $destfile ]] && continue
  [[ ! -e ${destfile:h} ]] && mkdir -vp ${destfile:h}
  probe=$(ffprobe $sourcefile 2>&1)
  if print -r $probe | grep -q -i vp9
  then
    print "VP9 DETECTED ($sourcefile)"
    typeset videogeo=$(print -r $probe | grep -i vp9 | grep -o '[0-9][0-9]*x[0-9][0-9]*')
    print "VIDEO GEO $videogeo"
    typeset original_x=${videogeo%%x*}
    typeset original_y=${videogeo##*x}
    print "ORIGINAL GEO $original_x / $original_y"
    if (( original_x <= 1920 || original_y <= 1080 ))
    then
      print "UNDER FHD, COPYTING."
      cp -n -v $sourcefile ${destfile:h}/
    fi
    (( ratio_x = $original_x / 1920.0 ))
    (( ratio_y = $original_y / 1080.0 ))
    print "RATIO $ratio_x / $ratio_y"
    if (( ratio_x < ratio_y ))
    then
      print "1920x*"
      ffmpeg -i $sourcefile -c:v libx265 -crf 23 -vf scale=1920:-1 -c:a copy $destfile
    else
      print "*x1080"
      ffmpeg -i $sourcefile -c:v libx265 -crf 23 -vf scale=-1:1080 -c:a copy $destfile
    fi
  else
    print "NOT VP9, COPYING ($sourcefile)"
    cp -n -v $sourcefile ${destfile:h}/
  fi
done

ポイント

P720に接続されているディスプレイ自体がFHDであるため、ターゲット解像度はFHDとした。 また、フォーマットはH.265を選択した。容量が小さく、ノイズが気になりやすいMMD動画でもH.264と比べれば乱れにくく、RX570でもハードウェアデコーディングが有効である。

まず、ターゲットファイルが既に存在する場合はスキップする。 エンコードが行われる前提であれば処理冒頭でスキップするが、コピーに入った場合はコピー時にスキップされる。

コピーされる条件は

  • VP9でない
  • X<=1920 または Y<=1080 である

のどちらか。 なお、ここでは動画はVP9でないのならH.264またはH.265だろうという前提に立っている。

これに該当しない場合、エンコードを行う。アスペクト比を維持するが、この場合Xを基準にするかYを基準にするかを選ばないといけない。 今回のポリシーでは、X<=1920かつY<=1080であるように変換することとした。grepと変数展開を組み合わせているが、シェルスクリプトになれない人には少し難しいだろう。 一連の処理が参考になれば幸いである。