SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

今日からできる! 動画配信基盤システム構築

【Webブラウザでストリーミング動画配信:前編】MP4プログレッシブダウンロードによるストリーミング再生を実現しよう

今日からできる! 動画配信基盤システム構築 第4回

GOP長を調整して素早くシークができるようにする

 さて、上記で作ったファイルを再度簡易HTTPサーバーで再生してみましょう。

<!DOCTYPE html>
<html>
  <head>
    <title>Test streaming player</title>
  </head>
  <body>
    <video src="output_1080p.mp4" controls></video>
  </body>
</html>

 どうでしょう?快適に再生できたでしょうか?ローカルサーバーからの参照なので当然快適に再生できることでしょう。

 せっかくなので、実際のユーザー環境に近づけてみます。各種Webブラウザには開発者ツールに通信速度をシミュレートする設定があるため、そちらを有効にして、ユーザーの回線環境を再現してみます。

 例として以下にGoogle Chromeでその設定を行う方法を紹介します。

 まず、開発者ツールを下記コマンドで起動します。

  • macOS:command⌘ + option⌥ + I
  • Windows:Ctrl + Shift + I

 次に「Network」タブを選択し、WiFiマークをクリックします。すると画面下方に「Network Conditions」タブが表示されるため、そこの「Network throttling」の設定を変更してみましょう。

 例では「10Mbps」で通信を行う設定を追加して、利用しています。

 この状態で何度かシークを実行してみましょう。1秒~2秒ほどシークに時間が掛かることがあると思います。

 この原因は先程のコマンドで指定した、「-g 120」と「-sc_threshold 0」によって、強制的にGOP(Group Of Pictures)の長さが120フレーム(=4秒)に設定されていたためです。

 動画の圧縮に用いられている要素技術の一つとして、フレーム間の差分に注目し、フレーム間で変化していない部分をなるべく同じデータで表現するという方法があります。GOPはそれらをまとめる単位のことだと思って差し支えありません。

 例えば、GOP長が4秒であった場合、4秒ごとに「キーフレーム」と呼ばれる「そのフレームデータのみでデコードが可能なフレーム」が挿入されており、それ以外のフレームは前後(通常は前)のフレームを参照しなければデコードできないフレームとなっています。すなわちシークした場合は最大4秒前のフレームからデータを参照しないとデコードができないことになります。

 今回の例では6Mbpsでエンコードしていたため、4秒だと24Mbとなります。回線速度を10Mbpsに指定していたため、最大2.4秒程度バッファリングが発生することになります。

 なお、キーフレームはなるべくシーンの変わり目に挿入するほうが良いとされています。その方が差分を計算する上で有利となり、圧縮率向上が狙えるからです。libx264には強力なシーンチェンジ検出機能が搭載されており、デフォルトでシーンチェンジの位置にキーフレームが挿入されるような設定になっています。「-sc_threshold」はシーンチェンジ検出の設定を行うオプションであり、上記例では「0」を指定することでそれらを無効にしていました。

 では今度はGOP長が1秒程度の動画を作ってみましょう。「-g 30」とすることで1秒ごとにキーフレームが入るようにしており、なおかつ「-sc_threshold 0」を削除することでシーンチェンジも加味した形で良い塩梅に挿入されるようになります。

$ ffmpeg -i bbb_sunflower_1080p_60fps_normal.mp4  -c:v libx264 -preset veryslow -r 30 -g 30 -s 1920x1080 -b:v 6000k -maxrate 8500k -bufsize 8500k -level 42 -pix_fmt yuv420p -aspect 16:9 -sar 1:1 -c:a aac -b:a 128k -ac 2 -movflags +faststart output_1080p_gop30.mp4

 HTMLファイルを下記のように編集し、それぞれの動画を見比べてみましょう。

<!DOCTYPE html>
<html>
  <head>
    <title>Test streaming player</title>
  </head>
  <body>
    <video src="output_1080p.mp4" controls></video>
    <video src="output_1080p_gop30.mp4" controls></video>
  </body>
</html>

 明らかに後者の方が快適にシークができると思います。

 このようにGOP長を短くする事でシークの体験を向上させることができます。

 ではストリーミング配信においてはGOP長はなるべく短いほうが良いのでしょうか?残念ながらそういった単純な判断は難しいパラメーターとなっています。

 一般的にGOP長は長ければ長いほど圧縮効率が高くなる可能性があるとされています。そのため、ストリーミング配信におけるGOP長の長さは、圧縮効率とシーク体験のトレードオフとなっているといえます。

 シークが多く発生するようなコンテンツのストリーミング配信では、0.5~2秒程度のGOP長が望ましいことでしょう。逆にシークすることがあまり考えられないコンテンツにおいては、シーンチェンジをベースとした10秒前後のGOP長でも問題なくサービス提供できる可能性があります。

 このあたりはサービスの性質やコンテンツの性質も加味した上で判断する必要があります。

 なお、これは経験則ではありますが、短すぎるGOP長(10フレーム未満な値)はストリーミング再生においては再生を不安定にする可能性があります。逆にGOP長が長くなればなるほど、デコード時のバッファサイズを要するため、クライアントのスペックを加味すると長すぎるのも良くないと言えます。

 そのため、0.5~10秒程度のGOP長が望ましいと思われます。

次のページ
コラム:キーフレームの挿入位置を実際に確認してみる

この記事は参考になりましたか?

今日からできる! 動画配信基盤システム構築連載記事一覧

もっと読む

この記事の著者

矢野 完人(合同会社DMM.com)(ヤノ マサヒト)

 2016年にDMM.comへ新卒入社。CTO室に配属され、新規事業立案や動的画像リサイズエンジンのR&D等に従事。2017年に動画サービスを司る部署(現:動画配信開発部)に異動し、配信基盤グループにて設計・開発・運用・マネジメントなどさまざまな業務を行う。現在はメディア基盤開発部 部長とし...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/21095 2025/03/28 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー