「Feature-Policy: speaker-selection」でWebサイトのオーディオ出力を安全に管理


「Feature-Policy: speaker-selection」は、HTTPヘッダーで指定される特別な指令の一つです。これは、Webサイトがユーザーのデバイス上のスピーカーやヘッドホンなどのオーディオ出力機器を列挙したり、選択したりすることを許可するか否かを制御するために使用されます。

役割

この指令は、プライバシーとセキュリティ上の理由から重要です。悪意のあるWebサイトがユーザーの同意なしにスピーカーを選択して、不要な音声を再生したり、周囲の音声を録音したりするのを防ぐことができます。

構文

「Feature-Policy: speaker-selection」指令の構文は次のとおりです。

Feature-Policy: speaker-selection <allowlist>;
  • 例:
  • ワイルドカード文字 (*) を使用して、サブドメイン全体を許可することができます。
  • オリジンは、スキーム、ホスト名、ポート番号を含む完全修飾URLで表されます。
  • <allowlist> は、スピーカー選択を許可するオリジンのリストです。カンマ区切りで複数のオリジンを指定できます。
Feature-Policy: speaker-selection https://example.com, https://*.example.com;

動作

Webブラウザは、Webサイトから受信したHTTPヘッダーを解析し、「Feature-Policy: speaker-selection」指令が存在するかどうかを確認します。指令が存在する場合、ブラウザは指令の内容に従ってスピーカー選択機能の動作を決定します。

  • 指令で許可されていないオリジンの場合、Webサイトはスピーカーの選択を許可されません。
  • 指令で許可されているオリジンの場合、Webサイトはスピーカーの選択を許可されます。

次の例は、https://example.com およびそのサブドメインのみスピーカー選択を許可するWebサイトを示しています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Speaker Selection Example</title>
</head>
<body>
  <script>
    navigator.mediaDevices.enumerateAudioOutputs().then(function(outputs) {
      console.log(outputs);
    });
  </script>
</body>
</html>

この例では、ブラウザは https://example.com からのアクセスに対してのみスピーカー選択機能を許可するため、スクリプトはスピーカーのリストを出力します。一方、https://other.com からのアクセスに対しては、スピーカー選択機能は許可されないため、スクリプトはエラーを出力します。

互換性

「Feature-Policy: speaker-selection」指令は、比較的新しい機能であり、すべてのWebブラウザでサポートされているわけではありません。現時点では、Chrome、Firefox、Edgeなどの主要なブラウザでサポートされています。



<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Speaker Selection Example</title>
</head>
<body>
  <script>
    if (navigator.permissions && navigator.permissions.query) {
      navigator.permissions.query({ name: 'speaker-selection' })
        .then(function(permission) {
          if (permission.state === 'granted') {
            navigator.mediaDevices.enumerateAudioOutputs().then(function(outputs) {
              console.log(outputs);
            });
          } else {
            console.log('Speaker selection is not allowed.');
          }
        });
    } else {
      console.log('Permissions API is not supported.');
    }
  </script>
</body>
</html>

この例では、https://example.com からのアクセスに対してのみスピーカー選択機能を許可します。スクリプトはまず、navigator.permissions.query()を使用して、スピーカー選択機能に対するユーザーの許可状態を取得します。許可されている場合、スクリプトは navigator.mediaDevices.enumerateAudioOutputs()を使用してスピーカーのリストを出力します。許可されていない場合、スクリプトはメッセージを出力します。

例2:スピーカー選択機能を完全に無効にする

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Speaker Selection Example</title>
</head>
<body>
  <script>
    if (navigator.permissions && navigator.permissions.query) {
      navigator.permissions.query({ name: 'speaker-selection' })
        .then(function(permission) {
          if (permission.state === 'denied') {
            console.log('Speaker selection is disabled.');
          } else {
            console.log('Speaker selection is allowed.');
          }
        });
    } else {
      console.log('Permissions API is not supported.');
    }
  </script>
</body>
</html>

この例では、スピーカー選択機能を完全に無効にします。スクリプトはまず、navigator.permissions.query()を使用して、スピーカー選択機能に対するユーザーの許可状態を取得します。許可されていない場合、スクリプトはメッセージを出力します。許可されている場合、これは単にスピーカー選択機能が無効であることを示すメッセージを出力します。

例3:スピーカー選択機能のデフォルト動作を許可する

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Speaker Selection Example</title>
</head>
<body>
  <script>
    if (navigator.mediaDevices && navigator.mediaDevices.enumerateAudioOutputs) {
      navigator.mediaDevices.enumerateAudioOutputs().then(function(outputs) {
        console.log(outputs);
      });
    } else {
      console.log('Audio output enumeration is not supported.');
    }
  </script>
</body>
</html>

この例では、スピーカー選択機能のデフォルト動作を許可します。スクリプトは navigator.mediaDevices.enumerateAudioOutputs()を使用して、スピーカーのリストを出力します。

  • Web開発者は、この指令を適切に使用して、ユーザーの同意なしにスピーカー選択が行われないようにする必要があります。
  • 「Feature-Policy: speaker-selection」指令は、比較的新しい機能であり、すべてのWebブラウザでサポートされているわけではありません。


また、スピーカー選択機能を完全に無効にすることは、ユーザーにとって不便になる可能性があります。そこで、「Feature-Policy: speaker-selection」の代替方法として、以下の方法が考えられます。

ユーザーの同意を明示的に取得する

スピーカー選択機能を使用する前に、ユーザーにポップアップウィンドウなどで許可を求める方法です。この方法であれば、ユーザーはスピーカー選択機能の利用を許可するかどうかの判断を自分で下すことができます。

<script>
  if (navigator.mediaDevices && navigator.mediaDevices.enumerateAudioOutputs) {
    navigator.mediaDevices.enumerateAudioOutputs().then(function(outputs) {
      console.log(outputs);
    });
  } else {
    console.log('Audio output enumeration is not supported.');
  }
</script>

制限付きスピーカー選択機能を提供する

スピーカー選択機能を完全に無効にするのではなく、ユーザーが選択できるスピーカーのリストを制限する方法です。例えば、Webサイトで使用されているオーディオプレーヤーのみでスピーカーを選択できるようにしたり、ユーザーが最近使用したスピーカーのみを表示したりすることができます。

<script>
  if (navigator.mediaDevices && navigator.mediaDevices.enumerateAudioOutputs) {
    navigator.mediaDevices.enumerateAudioOutputs().then(function(outputs) {
      // ユーザーが最近使用したスピーカーのみを表示
      const recentOutputs = outputs.filter(function(output) {
        // ... ここに最近使用したスピーカーを判定するロジックを記述
      });
      console.log(recentOutputs);
    });
  } else {
    console.log('Audio output enumeration is not supported.');
  }
</script>

代替のオーディオ出力方法を提供する

スピーカー選択機能を使用せずに、ユーザーがオーディオ出力を選択できる方法を提供する方法です。例えば、Webサイト内にオーディオプレーヤーを埋め込み、ユーザーがプレーヤーの設定で出力機器を選択できるようにすることができます。

<audio controls>
  <source src="audio.mp3" type="audio/mpeg">
  Your browser does not support the audio tag.
</audio>

スピーカー選択機能を必要としないWebサイトを設計する

そもそもスピーカー選択機能を必要としないWebサイトを設計する方法です。例えば、音声のみのコンテンツを提供するWebサイトであれば、スピーカー選択機能は必要ありません。