Media Session API を使用してメディア通知と再生コントロールをカスタマイズする

ハードウェアのメディアキーとの統合方法、メディア通知のカスタマイズ方法など。

François Beaufort
François Beaufort

ブラウザで現在再生中のコンテンツをユーザーに知らせ、そのコンテンツを制御するため 起動したページに戻ることなく 導入しました。ウェブ デベロッパーはこのエクスペリエンスをカスタマイズするために カスタム メディア通知のメタデータ(再生、一時停止、 移動、追跡変更、ビデオ会議イベント(ミュートやミュート解除など) マイク、カメラのオン/オフ、電話を切るなどの操作を行えます。これらのカスタマイズは デスクトップのメディアハブや ウェアラブルデバイスにも対応していますこれらのカスタマイズについては ご覧ください。

<ph type="x-smartling-placeholder">
</ph> メディア セッションのコンテキストのスクリーンショット。
パソコンのメディアハブ、モバイルのメディア通知、ウェアラブル デバイス。

Media Session API について

Media Session API にはいくつかの利点と機能があります。

  • ハードウェアのメディアキーがサポートされています。
  • メディア通知は、モバイル、パソコン、ペア設定されたウェアラブル デバイスでカスタマイズされます。
  • メディアハブはパソコンで利用できます。
  • ロック画面のメディア コントロールは、ChromeOS とモバイルで使用できます。
  • ピクチャー イン ピクチャーのウィンドウ コントロールは、音声再生に使用できます。 ビデオ会議プレゼンテーションなどがあります。
  • モバイルでもアシスタントを統合できます。

対応ブラウザ

  • Chrome: 73。 <ph type="x-smartling-placeholder">
  • Edge: 79。 <ph type="x-smartling-placeholder">
  • Firefox: 82。 <ph type="x-smartling-placeholder">
  • Safari: 15。 <ph type="x-smartling-placeholder">

ソース

そのいくつかを、例で説明します。

例 1: ユーザーが「次のトラック」を押した場合キーボードのメディアキー ブラウザがフォアグラウンドにあるかどうかに関係なく、ウェブ デベロッパーはこのユーザー操作を処理できる 背景を選択できます。

例 2: ユーザーがデバイスでポッドキャストを聴いている場合 「戻る」アイコンを押せばアイコンから スクリーン メディア コントロールにより、ウェブ デベロッパーが再生時間を少し早戻し可能に 秒です。

例 3: 音声を再生しているタブがある場合、ユーザーは簡単にそのタブを停止できます。 デスクトップのメディアハブから再生できるため、ウェブ デベロッパーは 状態をクリアします。

例 4: ビデオ通話中に、ユーザーは マイク」コントロールを使用してウェブサイトを停止し、 受信しています。

これはすべて、2 つの異なるインターフェース(MediaSession インターフェース)を介して行われます。 MediaMetadata インターフェースがあります。1 つ目の方法では、ユーザーは GCP 上の 再生します。2 つ目は、制御する必要があるものを MediaSession に伝える方法です。

下の画像は、これらのインターフェースが特定のサービス アカウントに メディア コントロール。この例では、モバイルのメディア通知です。

<ph type="x-smartling-placeholder">
</ph> メディア セッションのインターフェースの図。
モバイルのメディア通知の構造。

再生中の曲をユーザーに知らせましょう

ウェブサイトで音声や動画を再生しているときには、メディアが自動的に表示されます。 モバイルの場合は通知トレイ、または Google Meet の できます。ブラウザは、最善を尽くして適切な情報を表示し、 ドキュメントのタイトルと、ドキュメント内で見つかった最も大きなアイコン画像などです。メディア セッションを使用 API を使用すると、リッチ メディアを使用してメディア通知をカスタマイズできます。 タイトル、アーティスト名、アルバム名、アートワークなどのメタデータを以下のように指定できます。

Chrome が「フル」をリクエスト音声フォーカスを使用して、音声フォーカスが メディア再生時間が5 秒以上。これにより偶発的なサウンドが 通知は表示されません。

// After media (video or audio) starts playing
await document.querySelector("video").play();

if ("mediaSession" in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    artist: 'Rick Astley',
    album: 'Whenever You Need Somebody',
    artwork: [
      { src: 'https://via.placeholder.com/96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
      { src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
      { src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  });

  // TODO: Update playback state.
}

再生が終了したら、「離す」必要がない指定したメディア セッションを 通知は自動的に消えます。注意点として navigator.mediaSession.metadata は、次の再生が開始されたときに使用されます。 ありますそのため、メディア再生ソースの変更時には、イベント オブジェクトをアップデートすることが重要です。 メディア通知に関連情報が表示されるように変更する必要があります。

メディアのメタデータについては、いくつか注意すべき点があります。

  • 通知アートワークの配列は、blob URL とデータ URL をサポートしています。
  • アートワークが定義されておらず、適切なサイズのアイコン画像(<link rel=icon> を使用して指定)がある場合は、メディア通知でその画像が使用されます。
  • Chrome for Android での通知アートワークのターゲット サイズは 512x512 です。対象 ローエンドのデバイスの場合は、256x256 です。
  • メディア HTML 要素の title 属性は、「この曲なに?」機能で使用されています。 macOS ウィジェット。
  • メディア リソースが埋め込まれている場合(iframe など)、Media Session API 埋め込みコンテキストから設定する必要があります。以下のスニペットをご覧ください。
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

また、セクションのタイトル、タイムスタンプ、スクリーンショット画像など、個々のチャプター情報をメディアのメタデータに追加することもできます。これにより、ユーザーはメディアのコンテンツ内を移動できます。

navigator.mediaSession.metadata = new MediaMetadata({
  // title, artist, album, artwork, ...
  chapterInfo: [{
    title: 'Chapter 1',
    startTime: 0,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }, {
    title: 'Chapter 2',
    startTime: 42,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }]
});
<ph type="x-smartling-placeholder">
</ph> ChromeOS のメディア通知に表示されるチャプター情報。
ChromeOS のチャプターを使用したメディア通知。
で確認できます。

ユーザーが再生中のコンテンツを操作できるようにする

メディア セッションのアクションとは、ウェブサイトで実行できる操作(「再生」や「一時停止」など)です。 ユーザーが現在のメディア再生を操作するときのハンドルを設定します。アクション: イベントとほぼ同じように機能します。イベントと同様に、アクションは 適切なオブジェクト( この場合は MediaSession です。ユーザーが ヘッドセット、別のリモート デバイス、キーボードなどのボタンや、 通知を受け取れます。

<ph type="x-smartling-placeholder">
</ph> Windows 10 のメディア通知のスクリーンショット
Windows 10 のカスタム メディア通知

一部のメディア セッション操作はサポートされていない場合があるため、 設定時に try…catch ブロックを使用します。

const actionHandlers = [
  ['play',          () => { /* ... */ }],
  ['pause',         () => { /* ... */ }],
  ['previoustrack', () => { /* ... */ }],
  ['nexttrack',     () => { /* ... */ }],
  ['stop',          () => { /* ... */ }],
  ['seekbackward',  (details) => { /* ... */ }],
  ['seekforward',   (details) => { /* ... */ }],
  ['seekto',        (details) => { /* ... */ }],
  /* Video conferencing actions */
  ['togglemicrophone', () => { /* ... */ }],
  ['togglecamera',     () => { /* ... */ }],
  ['hangup',           () => { /* ... */ }],
  /* Presenting slides actions */
  ['previousslide', () => { /* ... */ }],
  ['nextslide',     () => { /* ... */ }],
];

for (const [action, handler] of actionHandlers) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch (error) {
    console.log(`The media session action "${action}" is not supported yet.`);
  }
}

メディア セッション アクション ハンドラの設定解除は、null に設定するのと同じくらい簡単です。

try {
  // Unset the "nexttrack" action handler at the end of a playlist.
  navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
  console.log(`The media session action "nexttrack" is not supported yet.`);
}

設定すると、メディア セッション アクション ハンドラはメディアの再生中も維持されます。 これはイベント リスナー パターンと似ていますが、イベントを処理して ブラウザはデフォルトの動作を停止し、これを ウェブサイトがメディア アクションをサポートしていることを示します。つまりメディアアクションのコントロールは 適切なアクション ハンドラを設定しない限り、各プロパティは表示されません。

<ph type="x-smartling-placeholder">
</ph> macOS Big Sur の「この曲なに?」ウィジェットのスクリーンショット。
macOS Big Sur の「この曲なに?」ウィジェット。

再生 / 一時停止

"play" アクションは、ユーザーがメディアの再生を再開したいことを示します。 "pause" は一時的に停止します。

「再生/一時停止」アイコンは常にメディア通知と関連する通知に メディア イベントはブラウザによって自動的に処理されます。デフォルトの設定をオーバーライドするには 「再生」を処理します。および「一時停止」次のようなメディア アクションを指定します。

メディアの再生中または再生中に、ブラウザでウェブサイトがメディアを再生していないと判断される場合があります。 読み込むことができますこの場合は、動作をオーバーライドするために、 navigator.mediaSession.playbackState"playing" または "paused" に設定して、 ウェブサイトの UI をメディア通知コントロールと同期させる。

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('play', async () => {
  // Resume playback
  await video.play();
});

navigator.mediaSession.setActionHandler('pause', () => {
  // Pause active playback
  video.pause();
});

video.addEventListener('play', () => {
  navigator.mediaSession.playbackState = 'playing';
});

video.addEventListener('pause', () => {
  navigator.mediaSession.playbackState = 'paused';
});

前のトラック

"previoustrack" アクションは、ユーザーが 現在のメディア再生を先頭から再開します。これは、メディア再生に プレイリスト内の前のアイテムに移動するか、メディアの再生中に プレイリストという概念があります

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

次のトラック

"nexttrack" アクションは、ユーザーがメディア再生の移動先を示すことを示します。 メディア再生に再生リストの概念がある場合、再生リストの次のアイテム。

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

停止

"stop" アクションは、ユーザーがメディアの再生の停止を希望することを示します。 必要に応じて状態をクリアできます。

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

巻き戻し / 早送り

"seekbackward" アクションは、ユーザーがメディアを移動することを示します。 再生時間を少し逆戻り、"seekforward" はリクエストを表示 メディアの再生時間を少し早送りします。どちらの場合も、 短い期間とは数秒を意味します。

アクション ハンドラで指定される seekOffset 値は、API 呼び出しに メディアの再生時間をずらす。指定されていない場合(undefined など)、 適切な時間(10 ~ 30 秒など)を使用する必要があります。

const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.max(video.currentTime - skipTime, 0);
  // TODO: Update playback state.
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
  // TODO: Update playback state.
});

特定の時間に移動

"seekto" アクションは、ユーザーがメディア再生の移動を希望していることを示します。 適用できます。

アクション ハンドラで指定される seekTime 値は、API 呼び出しに メディアの再生時間を移動できます。

アクション ハンドラで提供される fastSeek ブール値は、アクションが シーケンスの一部として複数回呼び出されており、これが最後の呼び出しではない 必要があります。

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    // Only use fast seek if supported.
    video.fastSeek(details.seekTime);
    return;
  }
  video.currentTime = details.seekTime;
  // TODO: Update playback state.
});

再生位置を設定する

メディアの再生位置を通知に正確に表示する方法 以下のように、適切なタイミングで位置状態を設定することをおすすめします。「 position state は、メディアの再生速度、再生時間、 現在の時刻が表示されます。

<ph type="x-smartling-placeholder">
</ph> ChromeOS でのロック画面のメディア コントロールのスクリーンショット。
ChromeOS でのロック画面のメディア コントロール

期間には正の値を指定してください。位置は正の値で、 短い時間です再生速度には 0 より大きい値を指定してください。

const video = document.querySelector('video');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: video.duration,
      playbackRate: video.playbackRate,
      position: video.currentTime,
    });
  }
}

// When video starts playing, update duration.
await video.play();
updatePositionState();

// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
  /* ... */
  updatePositionState();
});

// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
  updatePositionState();
});

位置状態のリセットは、null に設定するのと同じくらい簡単です。

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

ビデオ会議の操作

ユーザーがビデオ通話をピクチャー イン ピクチャー ウィンドウに入れると、 ブラウザには、マイクやカメラのコントロールや、通話を終了するためのコントロールが表示されることがあります。 ユーザーがこれらをクリックすると、ウェブサイトが動画全体で処理します 会議に関する操作は以下のとおりです。例については、ビデオ会議のサンプルをご覧ください。

<ph type="x-smartling-placeholder">
</ph> ピクチャー イン ピクチャー ウィンドウのビデオ会議コントロールのスクリーンショット。
ピクチャー イン ピクチャー ウィンドウに表示されたビデオ会議コントロール。
で確認できます。

マイクを切り替える

"togglemicrophone" アクションは、ユーザーがミュートまたはミュート解除を希望していることを示します。 できます。setMicrophoneActive(isActive) メソッドはブラウザに対して、 ウェブサイトでマイクがアクティブであると認識されているかどうか。

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

カメラの切り替え

"togglecamera" アクションは、ユーザーがアクティブな オンとオフを切り替えられます。setCameraActive(isActive) メソッドは、Pod が ブラウザはウェブサイトをアクティブとみなします。

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

通話を終了

"hangup" アクションは、ユーザーが通話を終了することを示します。

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

プレゼンテーション用スライドの操作

ユーザーがスライドのプレゼンテーションをピクチャー イン ピクチャー ウィンドウに配置すると、 スライドを操作するコントロールがブラウザに表示される場合があります。ユーザーが ウェブサイトが Media Session API を通じて処理します。1 つの プレゼンテーション用スライドのサンプルをご覧ください。

前のスライド

"previousslide" アクションは、ユーザーが前のページに戻ろうとすることを示します。 前のスライドで詳しく解説します

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

対応ブラウザ

  • Chrome: 111。 <ph type="x-smartling-placeholder">
  • Edge: 111。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

次のスライド

"nextslide" アクションは、ユーザーが次のスライドに進むことを示します。 重要になります。

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

対応ブラウザ

  • Chrome: 111。 <ph type="x-smartling-placeholder">
  • Edge: 111。 <ph type="x-smartling-placeholder">
  • Firefox: サポートされていません。 <ph type="x-smartling-placeholder">
  • Safari: サポートされていません。 <ph type="x-smartling-placeholder">

サンプル

Blender Foundation を取り上げたメディア セッションのサンプルをご覧ください。 Jan Morgenstern 氏の研究

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
Media Session API を示すスクリーンキャスト。

リソース