動画

ユーザーは動画を好みます。面白く、ためになるからです。携帯端末では、動画の方が情報を理解しやすい場合があります。しかし動画は帯域幅を必要とするため、すべてのプラットフォームで常に同じように視聴できるとは限りません。動画の読み込みで待たされたり、[再生] を押して何も起こらなかったりすると、ユーザーは不快に感じます。動画をサイトに追加して、どのデバイスでも最高のユーザー エクスペリエンスを実現する方法をご確認ください。

動画を追加する

動画をサイトに追加して、どのデバイスでも最高のユーザー エクスペリエンスを実現する方法について説明します。

TL;DR

  • 動画要素を使用して、サイトで動画の読み込み、デコード、再生を行う。
  • 多様なモバイル プラットフォームに対応できるように複数の形式で動画を生成する。
  • 動画がコンテナからはみ出さないように動画のサイズを正しく設定する。
  • 動画要素の子としてトラック要素を追加し、利用しやすさの問題に対応する。

動画要素を追加する

サイトで動画の読み込み、デコード、再生を行うための動画要素を追加します。

<video src="chrome.webm" type="video/webm">
    <p>お使いのブラウザは、動画要素をサポートしていません。</p>
</video>

複数のファイル形式を指定する

すべてのブラウザが同じ動画形式をサポートしているとは限りません。 要素では、ユーザーのブラウザがいずれかの形式をサポートしていない場合の代替として、複数の形式を指定することができます。 次に例を示します。

<video controls>
  <source src="chrome.webm" type="video/webm">
  <source src="chrome.mp4" type="video/mp4">
  <p>This browser does not support the video element.</p>
</video>

ブラウザは <source> タグを解析する際に、オプションの type 属性を使用して、どのファイルをダウンロードして再生するかを判断します。ブラウザが WebM をサポートしている場合は chrome.webm を再生し、サポートしていない場合は MPEG-4 動画を再生できます。 ウェブで動画と音声を使用する方法については、A Digital Media Primer for Geeks(英語)をご覧ください。

このアプローチは、特に携帯端末でさまざまな HTML やサーバー側スクリプトを配信する場合に、次のようなメリットがあります。

  • デベロッパーが優先順位に基づいて形式を指定できます。
  • ネイティブ クライアント側で切り替えることで、コンテンツを取得する際にリクエストが 1 つだけ生成されるため待ち時間が短縮されます。
  • サーバー側でユーザー エージェントの検出機能とサポート データベースを使用するよりも、ブラウザで形式を選択する方がより簡単かつ迅速で、信頼性が高くなる場合があります。
  • ファイルごとにソースのタイプを指定するとネットワークのパフォーマンスが向上します。ブラウザが動画の一部をダウンロードして形式を識別しなくても、動画のソースを選択できるためです。

ここに挙げたポイントはすべて、帯域幅と待ち時間が重視され、ユーザーの忍耐に限界があるモバイル コンテキストでは特に重要です。 type 属性を指定しないと、複数のソースの中にサポートされていないタイプが存在する場合に、パフォーマンスに影響する可能性があります。

モバイル ブラウザ デベロッパー ツールを使用して、type 属性がある場合type 属性がない場合でネットワークのアクティビティを比較してください。 また、ブラウザ デベロッパー ツールでレスポンス ハンドラを確認し、サーバーが適切な MIME タイプを報告することを確認してください。そうしないと、動画のソースタイプのチェックが機能しません。

開始時刻と終了時刻を指定する

帯域幅を節約し、レスポンシブなサイトを構築しましょう。それには、Media Fragments API を使用して、動画要素に開始時間と終了時間を追加します。

メディア フラグメントを追加するには、メディアの URL に #t=[start_time][,end_time] を追加するだけです。たとえば、5~10 秒の間だけ動画を再生するには、次のように指定します。

<source src="video/chrome.webm#t=5,10" type="video/webm">

また、Media Fragments API を使用すると、DVD のキューポイントのように同じ動画の複数のビューを配信することができ、複数のファイルをエンコードして配信する必要はありません。

ブラウザ デベロッパー ツールを使用して、レスポンス ヘッダーの Accept-Ranges: bytes を確認します。

Chrome デベロッパー ツールのスクリーンショット: Accept-Ranges: bytes

ポスター画像を含める

動画要素に poster 属性を追加しておくと、要素が読み込まれたときにユーザーがその内容をすぐに把握できるため、動画をダウンロードして再生する必要がなくなります。

<video poster="poster.jpg" ...>
  ...
</video>

ポスターは、動画の src が破損していたり、指定した動画形式がすべてサポートされていない場合の代替手段にもなります。ポスター画像の唯一のデメリットは、追加のファイル リクエストによって帯域幅を消費し、レンダリングが必要になることです。詳しくは、画像の最適化をご覧ください。

次に、ポスター画像がある場合とない場合を並べて比較してみましょう。動画ではないことを証明するため、グレースケールのポスター画像を使用しています。

縦向きの Android Chrome のスクリーンショット、ポスターなし 縦向きの Android Chrome のスクリーンショット、ポスターあり

レガシー プラットフォーム用の代替手段を提供する

すべてのプラットフォームですべての動画形式がサポートされているわけではありません。主要なプラットフォームでサポートされている動画形式を確認し、各プラットフォームで動画を再生できるようにしましょう。主要なプラットフォームでサポートされている動画形式を確認し、各プラットフォームで動画を再生できるようにしましょう。

サポートされている形式を確認する

サポートされている動画形式を検出するには、canPlayType() を使用します。このメソッドは、mime-type とオプションのコーデックで構成された文字列引数を受け取り、次のいずれかの値を返します。

戻り値 説明
(空の文字列) コンテナまたはコーデック、あるいはその両方がサポートされていません。
maybe コンテナおよびコーデックはサポートされている可能性がありますが、ブラウザで 動画の一部をダウンロードして確認する必要があります。
probably この形式はサポートされています。

Chrome で実行する場合の canPlayType() の引数と戻り値の例は次のとおりです。

タイプ レスポンス
video/xyz (空の文字列)
video/xyz; codecs="avc1.42E01E, mp4a.40.2" (空の文字列)
video/xyz; codecs="nonsense, noise" (空の文字列)
video/mp4; codecs="avc1.42E01E, mp4a.40.2" probably
video/webm maybe
video/webm; codecs="vp8, vorbis" probably

複数の形式で動画を生成する

同じ動画を異なる形式で保存できるツールは数多くあります。

使用されている形式を確認する

ブラウザで実際に選択されている動画形式を確認したい場合があります。

JavaScript では、動画の currentSrc プロパティを使用して、使用されているソースを取得できます。

実際の動作を確認するには、こちらのデモをご覧ください。Chrome と Firefox は chrome.webm を選択し(ブラウザがサポートしているソースのリストで先頭に指定されているため)、Safari は「chrome.mp4」を選択しています。

動画のサイズを正しく設定する

ユーザーに楽しんでいただくためには、サイズの設定が重要です。

動画のサイズを確認する

エンコードされた動画の実際のフレームサイズは、動画要素のサイズによって異なる場合があります(画像を実際のサイズでは表示できない場合があるため)。

エンコードされた動画のサイズを確認するには、動画要素の videoWidth と videoHeight プロパティを使用します。width と height は、動画要素のサイズを返します。この値は、CSS またはインラインの width と height 属性を使用してサイズが設定されている場合があります。

動画がコンテナからはみ出さないようにする

動画要素がビューポートよりも大きすぎると、コンテナからはみ出し、コンテンツを表示できなかったり、 コントロールを使用できない場合があります。

縦向きの Android Chrome のスクリーンショット。スタイルが未設定の動画要素がビューポートからはみ出している 横向きの Android Chrome のスクリーンショット。スタイルが未設定の動画要素がビューポートからはみ出している

JavaScript または CSS を使用して動画のサイズを制御できます。FitVids などの JavaScript ライブラリとプラグインによって、YouTube やその他のソースから取得した Flash 動画でも、適切なサイズとアスペクト比を維持することができます。

CSS メディア クエリを使用して、ビューポートのサイズに応じた要素のサイズを指定できます。max-width: 100% と指定することをおすすめします。

フレーム内のメディア コンテンツ(YouTube 動画など)には、レスポンシブな手法をお試しください(John Surdakowski 氏が提唱している手法など)。

CSS:

.video-container {
    position: relative;
    padding-bottom: 56.25%;
    padding-top: 0;
    height: 0;
    overflow: hidden;
}

.video-container iframe,
.video-container object,
.video-container embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

HTML:

<div class="video-container">
  <iframe src="//www.youtube.com/embed/l-BA9Ee2XuM"
          frameborder="0" width="560" height="315">
  </iframe>
</div>

レスポンシブなサンプルレスポンシブではないサンプルを比較してみましょう。

動画プレーヤーをカスタマイズする

動画の表示はプラットフォームによって異なります。モバイル ソリューションではデバイスの向きを考慮する必要があります。Fullscreen API を使用すると、動画コンテンツのフルスクリーン表示を制御できます。

動画の表示はプラットフォームによって異なります。モバイル ソリューションではデバイスの向きを考慮する必要があります。Fullscreen API を使用すると、動画コンテンツのフルスクリーン表示を制御できます。

さまざまなデバイスでのデバイスの向きの影響

デバイスの向きは、デスクトップ モニターやノートパソコンでは問題になりませんが、携帯端末やタブレット用のウェブページのデザインを検討する際には非常に重要です。

iPhone の Safari は、縦向きと横向きでの切り替えが非常にスムーズです。

縦向きの iPhone の Safari で再生している動画のスクリーンショット 横向きの iPhone の Safari で再生している動画のスクリーンショット

iPad や Android の Chrome では、デバイスの向きが問題になることがあります。 たとえば、横向きの iPad での動画の再生をカスタマイズしないと、次のように表示されます。

横向きの iPad Retina の Safari で再生している動画のスクリーンショット

CSS で width: 100% または max-width: 100% と設定すると、デバイスの向きによるレイアウトの問題の多くは解決できます。また、フルスクリーンの代替手段も検討した方がよい場合があります。

インラインまたはフルスクリーン表示

動画の表示はプラットフォームによって異なります。iPhone の Safari では、動画要素をウェブページ内で表示しますが、再生するときはフルスクリーン モードになります。

縦向きの iPhone に表示された動画要素のスクリーンショット

Android では、フルスクリーン アイコンをクリックすることでフルスクリーン モードをリクエストできますが、デフォルトではインラインで動画を再生します。

縦向きの Android の Chrome で再生している動画のスクリーンショット

iPad の Safari では動画をインラインで再生します。

横向きの iPad Retina の Safari で再生している動画のスクリーンショット

コンテンツのフルスクリーン表示の制御

フルスクリーンでの動画の再生を強制できないプラットフォームでは、Fullscreen API が幅広くサポートされています。この API を使用すると、コンテンツまたはページのフルスクリーン表示を制御できます。

video:のように要素をフルスクリーン表示する方法は、次のとおりです。

elem.requestFullScreen();

ドキュメント全体をフルスクリーン表示する方法は、次のとおりです。

document.body.requestFullScreen();

フルスクリーン状態の変更をリッスンすることもできます。

video.addEventListener("fullscreenchange", handler);

要素が現在フルスクリーン モードかどうかを確認することもできます。

console.log("In full screen mode: ", video.displayingFullscreen);

また、CSS で :fullscreen 疑似クラスを使用して、フルスクリーン モードでの要素の表示方法を変更することもできます。

Fullscreen API をサポートしているデバイスでは、動画のプレースホルダとしてサムネイル画像を使用することを検討してください。

実際の動作を確認するには、こちらのデモをご覧ください。

利用しやすさに関する問題

利用しやすさは機能ではありません。目や耳が不自由な方は、キャプションや説明なしでは動画を楽しむことができません。ユーザーに不便な思いをさせることを思えば、動画にキャプションや説明を追加するのはたいした手間ではありません。すべてのユーザーが最低限の情報を利用できるようにしましょう。

キャプションを含めて利用しやすさを改善する

携帯端末でメディアを利用しやすくするには、トラック要素を使用してキャプションまたは説明を表示します。

トラック要素を使用すると、次のようにキャプションが表示されます。

Android の Chrome でトラック要素を使用して表示されているキャプションを示すスクリーンショット

トラック要素を追加する

動画にキャプションを追加するのは非常に簡単です。動画要素の子としてトラック要素を追加するだけです。

<video controls>
    <source src="chrome.webm" type="video/webm" />
    <source src="chrome.mp4" type="video/mp4" />
  <track src="chrome-subtitles-en.vtt" label="English captions"
         kind="captions" srclang="en" default>
  <p>This browser does not support the video element.</p>
</video>

トラック要素の src 属性では、トラック ファイルの場所を指定します。

トラック ファイルでキャプションを定義する

トラック ファイルは WebVTT 形式で、時間を指定した「キュー」で構成されます。

WEBVTT

00:00.000 --> 00:04.000
木の枝の上に座った男性がノートパソコンを使っています。

00:05.000 --> 00:08.000
枝が折れて男性は落下してしまいます。

...

クイック リファレンス

動画要素のプロパティの概要を説明します。

動画要素の属性

動画要素の属性の詳細な一覧とその定義については、動画要素の仕様をご覧ください。

属性 使用可能状況 説明
src すべてのブラウザ 動画のアドレス(URL)
poster すべてのブラウザ ブラウザが動画要素を表示するときに、動画コンテンツをダウンロードせずにすぐに表示できる画像ファイルのアドレス(URL)。
preload すべてのモバイル ブラウザは preload を無視します。 動画全体を再生する前に、あらかじめ読み込むメタデータ(または動画の一部)についてブラウザに知らせます。オプションは、none、metadata、auto です(詳しくは、「事前読み込み」セクションをご覧ください)。
autoplay iPhone または Android ではサポートされていません。すべてのデスクトップ ブラウザ、iPad、Firefox、および Android 用 Opera ではサポートされています。 できるだけ早くダウンロードを開始して再生します(「自動再生」セクションをご覧ください)。
loop すべてのブラウザ 動画をリピート再生します。
controls すべてのブラウザ デフォルトの動画コントロール(再生、一時停止など)を表示します。

自動再生

デスクトップでは、autoplay によって、すぐに動画をダウンロードしてできるだけ早く再生するようブラウザに指示することができます。iOS および Chrome for Android では、autoplay は機能しません。動画を再生するには画面をタップする必要があります。

autoplay を使用できるプラットフォームでも、有効にすべきかどうかを検討する必要があります。

  • データの使用量が増えてコストがかかる場合があります。
  • ユーザーに確認せずにいきなりダウンロードと再生を開始すると、予想以上に帯域幅と CPU を独占し、ページのレンダリングに時間がかかる場合があります。
  • ユーザーにとって動画や音声の再生が好ましくない状況である可能性があります。

自動再生の動作は、Android WebView で WebSettings APIを使用して設定できます。 デフォルトでは true になっていますが、WebView アプリで無効にすることができます。

事前読み込み

preload 属性を使用すると、事前に読み込む情報またはコンテンツの量に関する情報をブラウザに知らせることができます。

説明
none ユーザーが動画を視聴できない可能性があるため、事前に何も読み込まない。
metadata メタデータ(長さ、サイズ、テキスト トラック)に加えて、最小限の動画を事前に読み込む必要があります。
auto すぐに動画全体をダウンロードすることが望ましいと見なされます。

preload 属性の効果は、プラットフォームによって異なります。 たとえば、Chrome は 25 秒間の動画をバッファしますが、iOS や Android ではバッファしません。したがって携帯端末では、デスクトップでは起こらない再生開始の遅延が発生する可能性があります。詳しくは、Steve Souders のテストページをご覧ください。

JavaScript

HTML5 Rocks Video の記事に、動画の再生を制御するための JavaScript のプロパティ、メソッド、イベントがわかりやすくまとめられています。その内容をここに転載し、関連するモバイル固有の懸念事項について更新しました。

プロパティ

プロパティ 説明
currentTime 再生の位置を秒単位で取得または設定します。
volume 動画の現在の音量を取得または設定します。
muted 音声のミュートを取得または設定します。
playbackRate 再生速度を取得または設定します。1 が通常の再生速度です。
buffered 動画のバッファサイズと再生の準備状況に関する情報(デモをご覧ください)。
currentSrc 再生中の動画のアドレス。
videoWidth ピクセル単位の動画の幅(動画要素の幅と異なる場合があります)。
videoHeight ピクセル単位の動画の高さ(動画要素の幅と異なる場合があります)。

playbackRate(デモをご覧ください)と volume は、携帯端末ではサポートされていません。

メソッド

メソッド 説明
load() 動画のソースの読み込みまたは再読み込みを行いますが、再生は開始しません。たとえば、JavaScript を使用して動画の src が変更された場合に使用します。
play() 現在の位置から動画を再生します。
pause() 現在の位置で動画を一時停止します。
canPlayType('format') サポートされている形式を検出します(「サポートされている形式を確認する」をご覧ください)。

携帯端末では(Android の Opera を除き)、ボタンをクリックするといったユーザーの操作に対するレスポンスとして呼び出されない限り、play() と pause() は 機能しません。デモをご覧ください(同様に、埋め込みの YouTube 動画など、コンテンツの再生を開始することはできません)。

イベント

以下のイベントは、発生する可能性があるメディア イベントの一部です。完全な一覧については、Mozilla Developer Network のメディア イベントに関するページ(英語)をご覧ください。

イベント 説明
canplaythrough 動画を中断せずに完全に再生できるとブラウザが判断するだけの十分なデータが利用可能になったときに発生します。
ended 動画の再生が完了したときに発生します。
error エラーが発生したときに発生します。
playing 初めて、一時停止後、または再開時に、動画の再生を開始するときに発生します。
progress ダウンロードの進行状況を示すために定期的に発生します。
waiting 別の操作の完了待ちのため、操作が遅延しているときに発生します。
loadedmetadata ブラウザが動画のメタデータ(長さ、サイズ、テキスト トラック)の読み込みを完了したときに発生します。