track 要素の基礎

HTML5 Rocks

HTML5 の track 要素の基礎

track 要素を使用すると、動画/音声ファイルに字幕やキャプション、スクリーン リーダーのテキスト、チャプターを簡単に、標準化された方法で追加することができます。

track はその他の時間指定用メタデータにも使用できます。各 track 要素のソース データは、時間情報を含む「キュー」のリストからなるテキスト ファイルです。キューには JSON や CSV といった形式のデータを含めることができます。便利なこの要素を使用すると、たとえばテキスト検索からのディープリンクやメディア ナビゲーションが可能になります。あるいはメディア再生と同期した DOM 操作やその他の動作も実現できます。

track 要素は現在、Internet Explorer 10Chrome 18 以上で使用できます。Firefox は未サポートです(リンク先はいずれも英語)。Chrome の場合、track 要素のサポートを有効にするには chrome://flags のページで設定する必要があります。

次は track 要素を使った動画の簡単な例です。動画を再生すると英語の字幕が表示されます:

このデモを確認するには、track 要素をサポートしているブラウザ(Google Chrome Canary など)が必要です。Chrome の場合、chrome://flags のページで track 要素のサポートを有効にする必要があります。

英語とドイツ語の字幕を表示する video 要素のコードは次のようになります:

<video src="foo.ogv">
  <track kind="subtitles" label="English subtitles" src="subtitles_en.vtt" srclang="en" default></track>
  <track kind="subtitles" label="Deutsche Untertitel" src="subtitles_de.vtt" srclang="de"></track>
</video>

この例では、video 要素によってセレクタが表示され、ユーザーが字幕の言語を選べるようになっています(記事執筆時点でこの機能はまだ実装されていません)。

track 要素は file:// の URL からは利用できないのでご注意ください。track の動作を確認するには、ファイルをウェブサーバーに置く必要があります。

track 要素ごとに、kind 属性で subtitlescaptionsdescriptionschaptersmetadata のいずれかの値を指定します。track 要素の src 属性では、時間指定トラックのキューのデータを含んだテキストファイルを指定します。ブラウザで解析できる形式であれば、どのようなファイル形式も可能です。Chrome では WebVTT がサポートされており、次のようになります:

WEBVTT FILE

railroad
00:00:10.000 --> 00:00:12.500
Left uninspired by the crust of railroad earth

manuscript
00:00:13.200 --> 00:00:16.900
that touched the lead to the pages of your manuscript.

トラック ファイルの各セグメントはキューと呼ばれます。各キューでは、最初の行に開始時間と終了時間を矢印で区切って指定し、その次の行にキューのテキストを指定します。必要であれば、キューに ID を指定することもできます(上記の例では「railroad」と「manuscript」が ID です)。キューの間は空の行で区切ります。

キューの時間形式は hh:mm:ss.sss となります。解析では厳密さが要求されるので、桁数が不足する場合は 0 を使って埋める必要があります。hh、mm、ss の部分は 2 桁(値ゼロの場合は 00)で、sss の部分は 3 桁(値ゼロの場合は 000)となります。quuz.org/webvtt(英語)にある WebVTT 検証ツールはおすすめです。このツールでは、時間形式のエラーや、時間が順番になっていないなどの問題をチェックできます。

以下のデモは、字幕を検索して動画内の特定部分にアクセスできる方法を示しています。

キューで HTML と JSON を使用する

WebVTT ファイル内のキューのテキストは、複数の行で指定することができます(ただし空白行は指定できません)。つまり、下記のようにキューに HTML を含めることができます。

WEBVTT FILE

multiCell
00:01:15.200 --> 00:02:18.800
<p>Multi-celled organisms have different types of cells that perform specialised functions.</p>
<p>Most life that can be seen with the naked eye is multi-cellular.</p>
<p>These organisms are though to have evolved around 1 billion years ago with plants, animals and fungi having independent evolutionary paths.</p>

さらに、キューでは JSON も使用できます:

WEBVTT FILE

multiCell
00:01:15.200 --> 00:02:18.800
{
"title": "Multi-celled organisms",
"description": "Multi-celled organisms have different types of cells that perform specialised functions.
  Most life that can be seen with the naked eye is multi-cellular. These organisms are though to
  have evolved around 1 billion years ago with plants, animals and fungi having independent
  evolutionary paths.",
"src": "multiCell.jpg",
"href": "http://en.wikipedia.org/wiki/Multicellular"
}

insects
00:02:18.800 --> 00:03:01.600
{
"title": "Insects",
"description": "Insects are the most diverse group of animals on the planet with estimates for the total
  number of current species range from two million to 50 million. The first insects appeared around
  400 million years ago, identifiable by a hard exoskeleton, three-part body, six legs, compound eyes
  and antennae.",
"src": "insects.jpg",
"href": "http://en.wikipedia.org/wiki/Insects"
}

キューで構造化データを使用できる track 要素は強力で柔軟性の高い要素と言えます。ウェブ アプリでは、キュー イベントをリッスンし各キューの実行時にテキストを抽出してデータを解析した後、その解析結果を使ってメディア再生と同期した DOM 変更(または他の JavaScript や CSS のタスクの実行)を行うことができます。

track 要素を使うと、音声/動画ファイルに対し、検索をより簡単、強力、正確に行えるという付加価値を与えることもできます。

キューのテキストはインデックスに登録可能で、キューの開始時間はメディア内でのコンテンツの時間的位置を示す役割を果たします。キューには動画フレーム内のオブジェクト位置に関するデータも含めることができます。track 要素を Media Fragment URI(リンク先は英語)と組み合わせて使用すると、音声/動画ファイル内のコンテンツを見つけてそのコンテンツに移動できるという優れた仕組みを提供できます。たとえば、「Etta James」と検索して返された結果をクリックすると、動画内で「Etta James」というテキストを含むキュー テキストがある位置に直接アクセスできるようになります。

Tree Of Life デモでは、track をメタデータとして使用して字幕検索からのナビゲーションを行う簡単な例を確認できます。このデモでは、時間指定用メタデータによってメディア再生と同期した DOM 操作を行う例も紹介しています。

JavaScriptを使って track とキューにアクセスする

audio 要素と video 要素には textTracks というプロパティがあり、このプロパティでは TextTrackList が返されます。このリストのメンバーである TextTrack は、1 つ 1 つが <track> 要素に対応します:

var videoElement = document.querySelector("video");
var textTracks = videoElement.textTracks; // one for each track element
var textTrack = textTracks[0]; // corresponds to the first track element
var kind = textTrack.kind // e.g. "subtitles"
var mode = textTrack.mode // 0 (TextTrack.OFF in spec, TextTrack.DISABLED in Chrome), 1 (TextTrack.HIDDEN) or 2 (TextTrack.SHOWING)

それぞれの TextTrack には cues というプロパティがあり、このプロパティでは TextTrackCueList が返されます。このメンバーの 1 つ 1 つが個々のキューに対応します。キュー データには、startTimeendTime などのプロパティを使ってアクセスできます。text プロパティでキューのテキスト コンテンツを取得することもできます:

var cues = textTrack.cues;
var cue = cues[0]; // corresponds to the first cue in a track src file
var cueId = cue.id // cue.id corresponds to the cue id set in the WebVTT file
var cueText = cue.text; // "The Web is always changing", for example (or some JSON!)

HTMLTrackElement を使って TextTrack オブジェクトを取得すると効率的な場合もあります:

var trackElements = document.querySelectorAll("track");
// for each track element
for (var i = 0; i < trackElements.length; i++) {
  trackElements[i].addEventListener("load", function() {
    var textTrack = this.track; // gotcha: "this" is an HTMLTrackElement, not a TextTrack object
    var isSubtitles = textTrack.kind === "subtitles"; // for example...
    // for each cue
    for (var j = 0; j < textTrack.cues.length; ++j) {
      var cue = textTrack.cues[j];
      // do something
    }
}

この例に示すとおり、TextTrack プロパティには track 要素そのものではなく track 要素の track プロパティを使ってアクセスします。

TextTrack には load イベントが発生した後でアクセスすることができます。発生前はアクセスできません。

track とキューのイベント

キュー イベントには次の 2 種類があります:

  • キューに発生した enter イベントと exit イベント
  • track に発生した cuechange イベント

上記の例では、キュー イベントのリスナーを次のように追加できます:

cue.onenter = function(){
  // do something
};

cue.onexit = function(){
  // do something else
};

enter イベントと exit イベントは、再生によってキューに入った(またはキューから出た)場合にのみ発生します。ユーザーがタイムラインのスライダーを手動でドラッグした場合は、track の新しい時間位置で cuechange イベントが発生しますが、enter イベントと exit イベントは発生しません。この動作を回避することもできます。回避するには、cuechange track イベントをリッスンして、有効なキューを取得します(有効なキューは 1 つとは限らないので注意が必要です)。

下記は、キューが変わったときに現在のキューを取得し、キュー テキストを解析してオブジェクトを作成しようとする例です:

textTrack.oncuechange = function (){
  // "this" is a textTrack
  var cue = this.activeCues[0]; // assuming there is only one active cue
  var obj = JSON.parse(cue.text);
  // do something
}

動画以外の用途

track は動画だけでなく音声ファイルとも組み合わせて使用できます。また、HTML マークアップの audio、video、track 要素を使用しなくても、track の API を活用することができます。TextTrack API に関するドキュメント(英語)では、この良い例として、音声の「スプライト」を効率良く実装する方法が示されています:

var sfx = new Audio('sfx.wav');
var track = sfx.addTextTrack('metadata'); // previously implemented as addTrack()

// Add cues for sounds we care about.
track.addCue(new TextTrackCue('dog bark', 12.783, 13.612, '', '', '', true));
track.addCue(new TextTrackCue('kitten mew', 13.612, 15.091, '', '', '', true));

function playSound(id) {
  sfx.currentTime = track.getCueById(id).startTime;
  sfx.play();
}

playSound('dog bark');
playSound('kitten mew');

addTextTrack メソッドは kind(上記の「metadata」など)、label(「Sous-titres français」など)、language(「fr」など)の 3 つのパラメータをとります。

上記の例では addCue も使用されていますが、これは TextTrackCue オブジェクトをとります。このオブジェクトのコンストラクタは、id(「dog bark」など)、startTimeendTime、キューの textwebVTT cue settings 引数(位置、サイズ、整列の指定用)、ブール値の pauseOnExit フラグ(教育動画で質問後に再生を一時停止するなどに使用)をとります(リンク先はすべて英語)。

startTimeendTime では、WebVTT で使用される hh:mm:ss:sss の形式ではなく、浮動小数点値の秒数が使用されます。

removeCue() を使ってキューを削除することもできます。この引数にはキューを次のように指定します:

var videoElement = document.querySelector("video");
var track = videoElement.textTracks[0];
var activeCue = track.activeCues[0];
track.removeCue(activeCue);

これを試してみると、レンダリングされたキューがコード呼び出し後すぐに削除されることがわかります。

track 要素には mode 属性を指定でき、値は 0(仕様上では TextTrack.OFF、Chrome では TextTrack.DISABLED)、1(TextTrack.HIDDEN)、2(TextTrack.SHOWING)のいずれかになります。この属性は、track イベントを使用するけれどデフォルトのレンダリングは無効にするという場合に便利です。次の動画でこの例を確認できます(Eric Bidelman 氏(リンク先は英語)による制作):

test1
asdf2

この例では、getCueAsHTML() メソッドが使用されています。このメソッドは、WebVTT キュー テキストの解析結果と DOM 構造の規則に基づいて WebVTT 形式から HTML の DocumentFragment への変換を行い、各キューの HTML バージョンを返します(リンク先はいずれも英語)。変換前のキュー テキスト値を src ファイルの状態で取得するだけの場合は、キューの text プロパティを使用します。

この状況では getCueAsHTML() メソッドを使用するのが便利です。このメソッドは WebVTT キュー テキストの解析結果と DOM 構造の規則に基づいて WebVTT 形式から HTML の DocumentFragment への変換を行い、各キューの HTML バージョンを返します(リンク先はいずれも英語)。変換前のキュー テキスト値を src ファイルの状態で取得するだけの場合は、キューの text プロパティを使用します。

マークアップについての補足

キューのタイムスタンプ行にマークアップを追加して、テキストの方向、整列、位置を指定できます。また、キュー テキストにマークアップを追加して、音声の紹介(話し手の名前紹介など)や書式の追加ができます。字幕とキャプションは CSS で操作でき、たとえば次のようになります:

::cue {
  color: #444;
  font: 1em sans-serif;
}
::cue .warning {
  color: red;
  font: bold;
}

Silvia Pfeiffer 氏による HTML5 動画のユーザー補助スライド(英語)では、マークアップの使い方、ナビゲーション用のチャプター トラックやスクリーン リーダーのテキスト トラックの作成方法についてさらに例が紹介されています。

まとめ

キュー データを音声/動画ファイルに帯域内エンコードする代わりにテキスト ファイルに保存する方法で、字幕とキャプションを簡単に作成できます。この方法には、ユーザー補助の機能を高めることができるというメリット、検索やデータ移植がしやすくなるというメリットもあります。

track 要素を使用すると、時間指定用メタデータやメディア再生にリンクした動的コンテンツを使用できるようにもなり、これによって audio 要素と video 要素に付加価値を与えることができます。

強力で柔軟、シンプルな track 要素は、ウェブ上のメディアをさらにオープンで動的なものにする大きな飛躍と言えます。

関連資料

Comments

0