本文へ移動
easeweb
ご相談
トピックを検索

ナレーションが途切れず、音声解説が入りきらない動画

冷ます時間と注ぎ方のカードが出ている間も焙煎店の店主が話し続けるため、音声解説版は最初のカードしか解説できず、動画も止まらない

WCAG 2.2
SC 1.2.7AAA
必須とする規格
Section 508、EN 301 549、JIS X 8341-3 では必須ではない
問題あり
アクセシビリティの問題を示した図: 全盲:お湯は何秒冷ますの?
01

問題

動画が見えない人には最初の分量しか伝わらず、冷ます時間も注ぐのを止めるタイミングも分からない

02

試してみる

映像を隠し、音声解説をオンにして動画を再生してみましょう。お湯は何秒冷ましますか?

スイッチをオンにすると映像が隠れ、見えない人と同じ状態になります。プレーヤーの操作はそのまま使えます。「音声解説」ボタンはプレーヤーの下にあり、音声の内容は動画の下に書いてあります。

修正を適用すると、解説の間は映像を止めておく拡張版や、端末の声で解説を読み上げ、間に収まらないときに一時停止するプレーヤーを試せます。

問題あり 修正できますか?

問題間が足りなくなる音声解説版

ハウスブレンドの淹れ方

店主が話しながら説明します・待ち時間は短縮しています。

音声の内容

  • ナレーション:当店のハウスブレンドの淹れ方です。
  • ナレーション:このくらい量ります。
  • ナレーション:お湯は少し置きます。沸かしたてだと、粉が焦げてしまうんです。
  • ナレーション:ゆっくり注いで、ここで止めます。細く注いで、粉がふくらんで落ち着くのを待ちます。
  • [キッチンタイマーの音]

再現デモです。「問題あり」は意図的にアクセシブルでない状態にしています。

03

修正方法

解説している間は、映像を止めておく

修正前
問題間が足りなくなる音声解説版
<video id="brew-video" controls preload="metadata"  src="brew-talk.webm" poster="brew-talk.jpg"  data-described="brew-talk.described.webm">  <track kind="captions" srclang="ja" label="日本語"    src="brew-talk.ja.vtt" data-described="brew-talk.described.ja.vtt"></video><button type="button" id="describe" aria-pressed="false">  音声解説</button> <script>  const video = document.getElementById('brew-video');  const track = video.querySelector('track');  const plain = { video: video.getAttribute('src'), captions: track.getAttribute('src') };  document.getElementById('describe').addEventListener('click', (event) => {    const button = event.currentTarget;    const on = button.getAttribute('aria-pressed') !== 'true';    const { currentTime, paused, playbackRate } = video;    const captions = track.track.mode;    video.src = on ? video.dataset.described : plain.video;    track.src = on ? track.dataset.described : plain.captions;    // 同じ位置、同じ速度で、字幕も元の表示のまま続ける。    video.addEventListener('loadedmetadata', () => {      video.currentTime = currentTime;      video.playbackRate = playbackRate;      track.track.mode = captions;      if (!paused) video.play();    }, { once: true });    button.setAttribute('aria-pressed', String(on));  });</script>
問題点3点

ボタンと切り替えは正しく、最初の解説も正しく入っています。どこで解説が尽きるかは、音声解説版の字幕ファイルに表れています。

  • 最初のカードの後は、ナレーションが終わって0.5秒もしないうちに次のナレーションが始まり、解説を入れる間がありません。
  • そのため音声解説版は、「沸騰後、30秒冷ます」も「3回に分けて注ぐ・3:00で止める」も言いません。
  • 時間を作るために動画が止まることはなく、拡張版も用意されていません。
修正後

映像を止めておく拡張版

<video id="brew-video" controls preload="metadata"  src="brew-talk.webm" poster="brew-talk.jpg"  data-described="brew-talk.extended.webm"  data-holds="[[15.22, 2.54], [21.06, 3.82]]">  <track kind="captions" srclang="ja" label="日本語"    src="brew-talk.ja.vtt" data-described="brew-talk.extended.ja.vtt"></video><button type="button" id="describe" aria-pressed="false">  音声解説</button> <script>  const video = document.getElementById('brew-video');  const track = video.querySelector('track');  const plain = { video: video.getAttribute('src'), captions: track.getAttribute('src') };  // 拡張版が映像を止める位置:元の動画での時刻と、止める秒数。  const holds = JSON.parse(video.dataset.holds);  const toExtended = (time) => time + holds    .filter(([at]) => at < time)    .reduce((sum, [, held]) => sum + held, 0);  const toOriginal = (time) => {    let shift = 0;    for (const [at, held] of holds) {      if (time < at + shift) break;      // 止めている途中なら、止め始めた位置に戻す。      shift += Math.min(held, time - at - shift);    }    return time - shift;  };  document.getElementById('describe').addEventListener('click', (event) => {    const button = event.currentTarget;    const on = button.getAttribute('aria-pressed') !== 'true';    const { currentTime, paused, playbackRate } = video;    const captions = track.track.mode;    video.src = on ? video.dataset.described : plain.video;    track.src = on ? track.dataset.described : plain.captions;    // 同じ位置、同じ速度で、字幕も元の表示のまま続ける。    video.addEventListener('loadedmetadata', () => {      video.currentTime = on ? toExtended(currentTime) : toOriginal(currentTime);      video.playbackRate = playbackRate;      track.track.mode = captions;      if (!paused) video.play();    }, { once: true });    button.setAttribute('aria-pressed', String(on));  });</script>
修正の手順4ステップ
  1. 音声解説版を編集し直して、拡張版を作ります(W3Cの達成方法G8)。解説を入れる間がない所では、解説する内容がまだ映っているフレームで映像を止め、映像を止めたまま解説を流し、その後に動画を再開させます。この例では、2枚目と3枚目のカードで店主が話し終えた直後に、それぞれ2.54秒と3.82秒、映像を止めています。
  2. 専用の字幕ファイルを用意し、各解説を「解説」と示して、聞こえる時刻に入れます。
  3. 「音声解説」ボタンが切り替える先を、音声解説版から拡張版のファイルに替えます。
  4. 映像を止める位置を video の data-holds に書いておきます。拡張版は長いため、同じ場面でも時刻が後ろにずれます。スクリプトはこの一覧で、一方のファイルの再生位置をもう一方の同じ場面に換算します。

これで修正前の例は直り、1.2.7を満たします。解説は録音なので、どのブラウザーでも同じように聞こえます。ファイルはどのプレーヤーでも再生でき、音声解説の機能を持たない動画サービスにもそのまま上げられます。

04

修正の確認

4項目、マウス不要

確認方法: 画面を見ずに視聴、キーボード、スクリーンリーダー

4件中0件を確認済み

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。動画、ナレーション、解説を差し替えた際は、再度確認します。

制限

これは出発点となる実装例であり、すべてのアプリケーションでの適合を保証するものではありません。動画に拡張音声解説が必要か、各解説で何を言うべきかは動画によって決まり、このガイドが代わりに判断することはできません。拡張音声解説はレベルAAAのため、WCAGのレベルAAを基準とする多くの法令や方針では求められていません。それでも、映像なしで内容が伝わる方法がこれしかない動画もあります。実際に聞く人と一緒に、動画が実際に再生されるプレーヤーやサービスで、一連の流れ全体を試してください。

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

EaseWebのサービス

修正した問題を、次のリリースで再発させない

このガイドのような修正方法を、コーディングエージェントが従うルールと、CIのチェックに組み込みます。あわせて定期的に、キーボードとスクリーンリーダーで手動の再テストを行います。

サービス内容を見る