DMM.comの、一番深くておもしろいトコロ。

新卒1年目のエンジニアが動画の品質可視化ツールを作るまで

新卒1年目のエンジニアが動画の品質可視化ツールを作るまで

  • このエントリーをはてなブックマークに追加

はじめに

20新卒として、動画配信事業部配信基盤グループへ7月に配属された中村(@zyackusan)です。 配信基盤グループでは、DMMの動画サービスにおいて動画や画像を配信する基盤の開発・運用を行っています。 具体的にやっていることは、以前の連載記事がありますのでそちらをぜひご覧ください!

inside.dmm.com

この記事では、配属されて最初に任された仕事と並行して作成したPython製のツールについて、その概要と開発に至った経緯について紹介します。

現在もチームの技術領域を把握することに専念しており、そのなかでも最初に任された仕事である「コンテンツホルダー向けの納品要件」を策定する仕事と並行して、動画の品質を可視化するダッシュボード・ツールを開発しました。 この可視化ツールを仕事の合間に最小限の労力でどのようにして開発したのか、以下に詳細にお伝えしていきます。

新卒の初仕事

配属されて最初に任された仕事は、コンテンツホルダー向けの4K動画の納品要件を策定することでした。

納品要件とは、作品を卸すコンテンツホルダーから受け取る動画のエンコード・パラメータを定義したものです。 この取り決めがあることで、動画作品の品質を維持しつつ、大きすぎないファイルサイズで受け渡せます。 動画事業ではH.264でエンコードしたmp4ファイルを受領しています。

今回の納品要件決めで調査したのは次のパラメータです。

  • ターゲットビットレート
  • 最大ビットレート
  • H.264のプロファイル(Main or High)

以前から納品要件そのものはありましたが、サービス黎明期にエビデンスがなく設定されたものや、時代の変化に伴って形骸化していた部分もあったので、それらを見直す必要がありました。 今回は様々なエンコード・パラメータで書き出した動画の品質を比較することで、その傾向を定量的に導き出すとともに、撮影時の動画と遜色ない品質を出せる組み合わせを探すことが私の仕事になりました。

動画の品質を定量的に評価する指標が数あるなか、今回はVMAFとSSIMを使いました。 それぞれ次のような特徴があります。

両指標とも、エンコード前後の動画を比較することで品質を評価しています。 そして、これらの指標を評価するのに用いるのがエンコードツールのFFmpegです。 libvmafをリンクしたFFmpegのビルドを用いることで、フレームごとにVMAFとSSIMを評価した結果がxml形式のファイルで出力されます。 今回は、次のようなコマンドを実行しました。

ffmpeg -i $1 \
       -i $2 \
       -filter_complex "\
       scale=3840:2160:flags=bicubic, \
       libvmaf=vmaf_4k_v0.6.1.pkl:model_path=./vmaf/model/vmaf_4k_v0.6.1.pkl:ssim=1:psnr=1:log_path=$OUT_LOG" \
       -an \
       -f null -

出力されたxmlファイルは、次の図に示すとおり、フレームごとにVMAFやSSIMの評価値が記録されています。 好みの言語とライブラリを使って、このファイルを様々な手法で解析することにより定量的な評価が可能になります。 私は、最初の頃Pythonとpandas・Jupyter Notebookなどを使って、平均や分散・フレームごとのスコアなどを解析していました。

f:id:dmminside:20210128112246p:plain

しかし、要件を決めるにあたって、新卒ならでは、動画に疎い人間ならではのキャッチアップしていくうえでの問題が生じます。 配属された当初、私は動画に関わる技術の基本的な部分を知りませんでした。 例えば、コーデック・FFmpeg・動画の品質を決める要素など、動画サービスを実現するうえでの基本的な部分がそれにあたります。 この程度の専門性では、当然1人で判断して結論を出すことができないので、最終的なパラメータの決定では、先輩社員と相談のうえで決めることにしました。

そのため、次の図の流れのように、集計・分析・相談のサイクルを繰り返すことで最終的に納品要件を決めることになったのですが、コミュニケーション面で1つの問題が生じました。 2020年、新型コロナの流行により、チームはリモートワークに移行していたので、たいていのコミュニケーションはSlackかzoomを用いるようになっていました。 先輩社員との相談でも、zoomで繋いでグラフが書き出されたJupyter Notebookを画面共有しながら行っていました。 私が作ったグラフと自分なりの判断を先輩社員に説明し、それを受けてアドバイスを受けたり、別のグラフを求められたりしました。 ただ、それらの助言をグラフに落とし込むのには少々時間がかかり、グラフを作り直すたびにzoomを繋ぎ直すことによって仕事の効率は下がってしまいました。 つまり、使っていた集計・分析のツールによって、このサイクルを高速に回すことができなかったのです。 そこで、この技術的な問題を解決する策として、グラフのパラメータをその場でインタラクティブに操作できる動画の品質評価ツールを実装しようということになりました。 また、今後も品質の分析で同様のことをするかもしれないので、使い捨てのコードではなく、ある程度ツールとしての体裁を整えることにしました。

f:id:dmminside:20210128112307p:plain

どんなデータが欲しい?

方針としてはこんな感じです。

  • 各変数の変化によって、どのように指標値が推移していくか(変数の値が異なる動画を比較したり、傾向を見つけたりする)
  • フレームごとに指標値がどのように推移しているか(動画の動きによっては指標値の値が急激に低下する時間があるので、そういった推移を見たい)
  • 比較対象になった動画の情報についてざっと一覧表示

フレームごとに品質を確認することで、動画内での動きに応じて品質の変化を確認することにしました。 動画内の動きに応じて品質が瞬間的に低下することがあります。 エンコード・パラメータによって下がり具合に違いがあるので、より安定して品質を維持できるパラメータの組み合わせを探す際に有効になります。 平均や分散・最低値などに数値を取り出すことで、より定量的な判断が期待できます。

コミュニケーションを取る際には、グラフを用いた直感的な手段があると良いでしょう。 そこで、フレームごとのスコアを比較できるように次のような機能も求められます。

  • フレームごとに表示されるVMAFやSSIMの値
  • 二つのエンコード・パラメータでのスコアの差分
  • 1フレーム前との差分

お手軽に可視化ツールを作りたい

今回は、ツールを作ること自体が仕事の目的ではないので、検証作業と並行してできるぐらいの労力で可視化ツールを作らなければなりません。 わざわざフロントエンドを構築するよりは、それまで書いていた有り合わせのPythonコードを流用して、Jupyter Notebookをそのままダッシュボードにするほうが楽なので、それを実現できる方法を探すことにしました。

そして見つけたがVoilàとipywidgetsです。

  • Voilà Jupyter Notebookをダッシュボードにしてくれるツール ビューをタイルにして自由に配置したりもできますが、今回のツールでは一枚板にしたので固定です。 https://github.com/voila-dashboards/voila
  • ipywidgets Jupyter NotebookやIPython向けにHTMLベースのウィジェットを提供してくれます。 ボタンやスライダーのみならず、タブバーやファイルアップロードのウィジェットなどもあります。 https://github.com/jupyter-widgets/ipywidgets

この二つを使えば、ダッシュボード・ツールはある程度作れそうです。 Voilàを使わずともJupyter Notebookだけでツールっぽく振る舞うこともできますが、Voilàを使うことでコードパネルを隠すことができるので、よりツールらしい体裁にできます。 ipywidgetsはフロントエンドの知識なしで簡単にGUIのビューを表示させることができますが、反面、レイアウトに対する自由度は低いです。 せいぜい、ウィジェットの縦と横の長さを変えたり、ウィジェットの縦横の並びを変えたりする程度のことしかできません。 ただ、今回のツールはチーム内で使えれば良いので、この手軽さとレイアウトの自由度のバランスはちょうど良いと感じました。

インタラクティブなグラフを提供するライブラリにはPlotlyを用いました。

  • Plotly Jupyter Notebookでも動かせるインタラクティブな可視化ライブラリ 無料版と有料版がありますが、無料版で全く問題ないです。 https://github.com/plotly/plotly.py

完成したもの

完成した可視化ツールはスクリーンショットのような外観になりました。

f:id:dmminside:20210128112612p:plain
ログファイルの入力画面
f:id:dmminside:20210128112630p:plain
統計情報の画面
f:id:dmminside:20210128112658p:plain
ログを比較する画面
f:id:dmminside:20210128112718p:plain
ログの一覧画面

大まかに使い方を説明するとこんな感じです。

  • VMAFとSSIMを評価した結果のxmlファイルをアップロードする
  • それぞれのエンコード・パラメータとファイルの対応を手動で設定する
  • タブを移動することで、全体の傾向や各エンコード・パラメータの比較、表形式による動画の品質情報を確認する

Plotlyのスクリーンショット機能で、グラフの画像を保存することも可能です。

また、グラフを下の動画のようにズームインして、急激にVMAFの値が低下したフレーム番号を確認できます。 そのため、対応する検証対象の動画を並行して確認しながら、水の流れるシーンや動きの激しいシーンでのエンコードの劣化具合を確かめるといった作業もコードを書き換えることなく行うことができます。 f:id:dmminside:20210128112528p:plain

注意しなければならなかったのは、Jupyter Notebook上で今回のようなツールを作ろうとすると簡単にスパゲッティ・コード化することです。 GUIを提供するipywidgetsも、ウィジェットのインスタンスにイベントハンドラを関数として渡すだけで、枠組みとしてはとても質素です。 自身でMVCなどのアーキテクチャを意識して整備しておかないと、後々負債になるでしょう。

使ってみてどうだった?

可視化ツールを作ってからの作業効率が大幅に改善されました。 先輩社員とzoomを繋ぎながら、その場でいろいろなグラフを作ることができるようになったので、仕事のサイクルを高速に回すことができるようになりました。 例えば、フレームごとの指標値を見ながら、瞬間的に低下しているフレーム番号へズームインして、複数あるエンコード・パラメータのうち、どれが品質を劣化させにくいかをその場で比較して回ったことなどが挙げられます。 他にも、ターゲットビットレートを順次上げれば指標値も上がっていたのが、一定のビットレートになるとVMAFもSSIMも上がりにくくなることが可視化ツールによる分析から見えてきました。 そのため、ファイルサイズなども考慮して、このぐらいのビットレートで十分だよね、などといった判断をコードの改変なしにできました。 結果的に、数回の相談で結論を出すことができました。 当初は、納品要件策定の期限を1ヶ月半ほどに設定していましたが、1ヶ月もかからずに仕事を終えることができたので、追加でSDやHD画質の納品要件を決める作業を始め、これも2週間足らずで終わらせることができました。 これらは、技術的な改善による生産性向上の表れだと言えるでしょう。

学生時代からJupyter Notebookはよく使っていましたが、Voilàなどのツールを使うことで今回のような可視化ツールを作ることができるのは新しい発見でした。 チーム内向けに簡単なUIの載ったツールを提供するシーンでは、今回のようにJupyter Notebook周辺の技術を使うほうが良いのかもしれません。

終わりに

今回の記事では、仕事の合間に開発したツールの概要と経緯について紹介しました。

新卒として働くにあたって、未知の領域であった動画サービスに係る技術をキャッチアップしていく必要がありました。 そのような状態だった私にとって、今回の納品要件決めは最初の仕事として最適な内容だったと感じます。 また、業務の一環として作ったツールをチームの上司や先輩方に評価していただき、こうして記事をまとめることができたのは幸いなことです。 何よりも、チームとして新卒を育てていくという環境が充実していると感じます。

あともう少しすれば「新卒」という肩書きが外れるわけですが、それまでにチームの一員として事業部の一員として会社を支える一人前の存在になれるようにがんばっていきます。