MediaStream Recording

W3C ワーキングドラフト,

この文書の詳細
本バージョン:
https://www.w3.org/TR/2026/WD-mediastream-recording-20260316/
最終公開版:
https://www.w3.org/TR/mediastream-recording/
編集者草案:
https://w3c.github.io/mediacapture-record/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/mediastream-recording/
フィードバック:
public-webrtc@w3.org 件名行 “[mediastream-recording] … message topic …” (アーカイブ)
GitHub
編集者:
(Google Inc.)
前編集者:
Jim Barnett (Genesis)
(Microsoft Corp.)
参加方法:
メーリングリスト
GitHub リポジトリ (new issue, open issues)
実装:
Can I use Media Recording?
Chromium Encode Acceleration Support

要旨

この文書は、MediaStreamで使用するための録画APIを定義します。

この文書の状態

このセクションは、本書が公開された時点におけるそのステータスについて説明しています。 現在のW3Cの公開文書およびこの技術報告書の最新版は、W3C技術報告書インデックス にてご覧いただけます。

本書は Webリアルタイムコミュニケーションワーキンググループ により、勧告候補プロセスを用いて策定された作業草案です。 この文書は最終的にW3C勧告となることを意図しています。

本書に関するコメントがありましたら、 public-webrtc@w3.org購読アーカイブ) までお送りください。 メール送信時は、件名に「mediastream-recording」を記載してください。 可能であれば、次の形式でお送りください: 「[mediastream-recording] …コメントの要約…」。 すべてのご意見を歓迎します。

作業草案としての公開は W3Cおよびそのメンバーによる承認を意味するものではありません。 本文書はドラフトであり、今後更新・置換・廃止される可能性があります。 この文書を進行中の作業以外のものとして引用することは適切ではありません。

本書は W3C特許方針の下で運営されるグループによって作成されました。 W3Cは、グループの成果物に関連して開示された 特許開示の公開リスト を管理しています。 そのページには特許開示の手順も掲載されています。 特許が必須クレームを含むと信じる実際の知識を持つ個人は、 W3C特許方針第6節 に従い情報を開示する義務があります。

本書は2025年8月18日付W3Cプロセス文書に準拠しています。

1. 概要

この API は基本的な録画を非常に簡単に行えるようにすることを目指しつつ、より複雑なユースケースにも対応できるようにしています。最も単純な場合、アプリケーションは MediaRecorder オブジェクトをインスタンス化し、start() を呼び出し、その後 stop() を呼び出すか、MediaStreamTrack(複数可) が終了するのを待ちます [GETUSERMEDIA]。録画の内容はプラットフォームのデフォルトエンコーディングで ondataavailable イベントを通じて利用可能になります。プラットフォームが利用可能なエンコーディングの一覧を問い合わせたり、必要に応じて望ましいものを選択したりするための関数が提供されています。アプリケーションは一度に受け取りたいデータ量を選択することもできます。デフォルトでは、録画が終了したときに録画全体を含む Blob が返されます。ただし、アプリケーションは定期的により小さなデータバッファを受け取るように選択することもできます。

2. メディアレコーダー API

[Exposed=Window]
interface MediaRecorder : EventTarget {
  constructor(MediaStream stream, optional MediaRecorderOptions options = {});
  readonly attribute MediaStream stream;
  readonly attribute DOMString mimeType;
  readonly attribute RecordingState state;
  attribute EventHandler onstart;
  attribute EventHandler onstop;
  attribute EventHandler ondataavailable;
  attribute EventHandler onpause;
  attribute EventHandler onresume;
  attribute EventHandler onerror;
  readonly attribute unsigned long videoBitsPerSecond;
  readonly attribute unsigned long audioBitsPerSecond;
  readonly attribute BitrateMode audioBitrateMode;

  undefined start(optional unsigned long timeslice);
  undefined stop();
  undefined pause();
  undefined resume();
  undefined requestData();

  static boolean isTypeSupported(DOMString type);
};

2.1. コンストラクタ

MediaRecorder(MediaStream stream, optional MediaRecorderOptions options = {})
MediaRecorder() のコンストラクターが呼び出されたとき、ユーザーエージェントは以下の手順を実行しなければならない(MUST):
  1. stream をコンストラクターの第一引数とする。
  2. options をコンストラクターの第二引数とする。
  3. typeoptionsmimeType とする。
  4. type と値 true を用いて is type supported を呼び出し、false を返した場合、 NotSupportedError DOMException をスローし、これらの手順を中止する。
  5. 新たに構築された MediaRecorder オブジェクトを recorder とする。
  6. recorder に、[[ConstrainedMimeType]] 内部スロットを持たせ、 optionsmimeType メンバーの値で初期化する。
  7. recorder に、[[ConstrainedBitsPerSecond]] 内部スロットを持たせ、 optionsbitsPerSecond メンバーが存在する場合はその値、そうでない場合は null で初期化する。
  8. recorder に、[[VideoKeyFrameIntervalDuration]] 内部スロットを持たせ、 optionsvideoKeyFrameIntervalDuration メンバーが存在する場合はその値、そうでない場合は null で初期化する。
  9. recorder に、[[VideoKeyFrameIntervalCount]] 内部スロットを持たせ、 optionsvideoKeyFrameIntervalCount メンバーが存在する場合はその値、そうでない場合は null で初期化する。
  10. recorderstream 属性を stream で初期化する。
  11. recordermimeType 属性を recorder[[ConstrainedMimeType]] スロットの値で初期化する。
  12. recorderstate 属性を inactive で初期化する。
  13. recordervideoBitsPerSecond 属性を optionsvideoBitsPerSecond メンバーが存在する場合はその値、そうでない場合はユーザーエージェントが動画に対して適切だと判断する目標値で初期化する。
  14. recorderaudioBitsPerSecond 属性を optionsaudioBitsPerSecond メンバーが存在する場合はその値、そうでない場合はユーザーエージェントが音声に対して適切だと判断する目標値で初期化する。
  15. recorder[[ConstrainedBitsPerSecond]] スロットが nullでない場合、recordervideoBitsPerSecond および audioBitsPerSecond 属性に、それぞれのメディアタイプに対してユーザーエージェントが適切だと判断する値を設定し、その合計値が recorder[[ConstrainedBitsPerSecond]] スロットの値に近くなるようにする。
  16. recorderoptionsaudioBitrateMode メンバーで指定された BitrateMode をサポートする場合は、recorderaudioBitrateMode 属性を optionsaudioBitrateMode メンバーの値で初期化し、そうでない場合は "variable" で初期化する。
  17. recorder を返す。

2.2. 属性

stream, of type MediaStream, readonly

MediaStream [GETUSERMEDIA] を録画するために使用します。

mimeType, of type DOMString, readonly

MediaRecorder オブジェクトが使用する MIME タイプ([RFC2046])。

ユーザーエージェントは、録画に対応する任意の MIME タイプを再生できるべきです。例えば、録画されたビデオを HTML の <video> タグで再生できるべきです。

mimeType は type/subtype の組み合わせで録画のメディアタイプとコンテナ形式を指定し、不明瞭な場合は codecs や profiles パラメータを [RFC6381] に従って指定します。個々のコーデックはさらに任意の特定パラメータを持つ場合があります。

state, of type RecordingState, readonly

現在の MediaRecorder オブジェクトの状態。

onstart, of type EventHandler

start イベントを処理するために呼び出されます。

onstop, of type EventHandler

stop イベントを処理するために呼び出されます。

ondataavailable, of type EventHandler

dataavailable イベントを処理するために呼び出されます。録画データの Blob はこのイベントに含まれ、その data 属性からアクセスできます。

onpause, of type EventHandler

pause イベントを処理するために呼び出されます。

onresume, of type EventHandler

resume イベントを処理するために呼び出されます。

onerror, of type EventHandler

エラーを表す ErrorEvent を処理するために呼び出されます。

videoBitsPerSecond, of type unsigned long, readonly

ビデオトラックのエンコードに使用される目標ビットレート。

audioBitsPerSecond, of type unsigned long, readonly

オーディオトラックのエンコードに使用される目標ビットレート。

audioBitrateMode, of type BitrateMode, readonly

BitrateMode がオーディオトラックのエンコードに使用されます。

2.3. メソッド

歴史的理由により、以下のメソッドは state を同期的に変更し、イベントは非同期で発火されます。
start(optional unsigned long timeslice)
MediaRecorder オブジェクトの start() メソッドが呼び出された時、UAは 以下の手順を実行しなければならない(MUST):
  1. recorder を、メソッドが呼び出された MediaRecorder オブジェクトとする。
  2. timeslice を、メソッドの第一引数が与えられていればその値、 そうでなければ undefined とする。
  3. stream を、recorderstream 属性の値とする。
  4. tracks を、streamトラックセット内の live トラック群とする。
  5. recorderstate 属性の値が inactive でない場合、InvalidStateError DOMException を投げて、これらの手順を中止する。
  6. streamアイソレーションプロパティrecorder からのアクセスを禁止する場合、 SecurityError DOMException を投げてこれらの手順を中止する。
  7. streaminactive であれば、 NotSupportedError DOMException を投げてこれらの手順を中止する。
  8. [[ConstrainedMimeType]] スロットで メディアタイプ・コンテナ・コーデックが指定されている場合は、 recorder の設定をそれらに制約する。
  9. recorder[[ConstrainedBitsPerSecond]] スロットが null でなければ、recordervideoBitsPerSecond および audioBitsPerSecond に対して、ユーザーエージェントがそれぞれの媒体タイプに妥当だと考える値を設定し、 それらの和が recorder[[ConstrainedBitsPerSecond]] の値に 近くなるようにする。
  10. videoBitraterecordervideoBitsPerSecond 属性の値とし、recorder の設定を 全てのビデオトラックを videoBitrate ビット/秒にするよう制約する。 videoBitrate はエンコーダーへのヒントであり、 この値が超過・未達、もしくは長時間かけて達成される場合がある。
  11. audioBitraterecorderaudioBitsPerSecond 属性の値とし、recorder の設定を 全てのオーディオトラックを audioBitrate ビット/秒にするよう制約する。 audioBitrate もエンコーダーへのヒントであり、 この値が超過・未達、もしくは長時間かけて達成される場合がある。
  12. videoKeyFrameIntervalDurationrecorder.[[VideoKeyFrameIntervalDuration]] とし、 videoKeyFrameIntervalCountrecorder.[[VideoKeyFrameIntervalCount]] とする。UAは 以下のルールに従うようビデオエンコーダに設定することが望ましい(SHOULD):
    • videoKeyFrameIntervalDurationnull でなく videoKeyFrameIntervalCountnull の場合、 最後のキーフレームから videoKeyFrameIntervalDuration ミリ秒経過後に到着する最初のフレームでキーフレームを出力する。
    • videoKeyFrameIntervalCountnull でなく videoKeyFrameIntervalDurationnull の場合、 最後のキーフレームから videoKeyFrameIntervalCount フレーム経過後に到着する最初のフレームでキーフレームを出力する。
    • 両方 videoKeyFrameIntervalDuration および videoKeyFrameIntervalCountnull でない場合、 NotSupportedError DOMException を投げて手順を中止する。
    • 両方 videoKeyFrameIntervalDuration および videoKeyFrameIntervalCountnull の場合、 UA は適切だと考えるタイミングでキーフレームを出力してよい。

    エンコーダーは、独自判断でキーフレームを出力する場合があることに注意。

  13. recorderBitrateMode 属性値で指定されたモードで、すべてのオーディオトラックをエンコードするよう設定を制約する。
  14. tracks 内の各トラックが、ユーザーエージェントの現在の設定で録音できない場合、 NotSupportedError DOMException を投げて手順を中止する。
  15. recorderstaterecording に設定し、以下の手順を 並列で実行する:
    1. 録音に使用するコンテナとコーデックが未確定の場合、 UAは recorder の現在の設定にそれらを指定する。 トラックのソースを考慮して構成する場合もある。
      tracks のソースを考慮することで、 トラックコンテンツの再エンコードを避けた構成選択が可能。 例: MediaStreamTrack が RTCPeerConnection の remote trackの時、対応するRTPストリームのコーデック を選択できる。録音中にRTPコーデック変更が起きた場合、 UA側は再エンコードを準備しておく必要あり。
    2. 指定されたメディアタイプ/サブタイプ・コーデック・コンテナの 組み合わせをUAがサポートしない場合、残りの手順を中止し DOM 操作タスクソースでタスクをキューして以下を実行:
      1. レコーダーの非アクティブ化recorderに適用する。
      2. エラーイベント(名前はNotSupportedError)を recorderで発火する。
      3. イベント(名前は stop)を recorderで発火する。
    3. recorder の現在の設定で tracks の全トラックを 録音し、データを Blob blob に集約。 DOM 操作タスクソースで下記を実行:
      1. extendedMimeTyperecorder[[ConstrainedMimeType]] スロットの値とする。
      2. extendedMimeType に、MediaRecorder が tracks 内の 全トラックを記録する際に用いたメディアタイプ、サブタイプ、および codec パラメータを、 まだ含まれていなければ付加する。これには profiles パラメータ [RFC6381] や他のコーデック固有パラメータを含んでもよい(MAY)。
      3. recordermimeType 属性を extendedMimeType に設定する。
      4. start という名前のイベントrecorder で発火する。
    4. 途中で streamアイソレーションプロパティMediaRecorder からのアクセスを不許可に変更された場合、UAはデータ収集を停止し、 収集済みデータを破棄し、下記のステップをDOM 操作タスクソースで実行:
      1. レコーダーの非アクティブ化recorderに適用する。
      2. エラーイベント(名前はSecurityError)を recorderで発火する。
      3. Blobイベント(名前は dataavailable)を recorderblobを添えて発火する。
      4. イベント(名前はstop)をrecorderで発火する。
    5. streamトラックセット に トラックが追加/削除された場合、UAはデータ収集を停止し、 下記タスクをDOM 操作タスクソースで実行:
      1. レコーダーの非アクティブ化recorderに適用する。
      2. エラーイベント(名前はInvalidModificationError)を recorderで発火する。
      3. Blobイベント(名前は dataavailable)を recorderblobを添えて発火する。
      4. イベント(名前はstop)をrecorderで発火する。
    6. UAが アイソレーションプロパティ または streamトラックセット 以外の理由で データ収集ができなくなった場合、データ収集を停止し 下記タスクをDOM 操作タスクソースで実行:
      1. レコーダーの非アクティブ化recorderに適用する。
      2. エラーイベント(名前はUnknownError)を recorderで発火する。
      3. Blobイベント(名前は dataavailable)を recorderblobを添えて発火する。
      4. イベント(名前はstop)をrecorderで発火する。
    7. timesliceundefined でなければ、 最低 timeslice ミリ秒分のデータ、またはUAが課す最小タイムスライス分の データが溜まったら、新たな Blob blob へのデータ蓄積を始め、それを Blobイベント dataavailable として recorderblob を添えて発火

      timesliceundefined の場合は 最大の unsigned long 値とみなされる。

    8. すべての記録対象トラックが ended となった場合、データ収集を停止しDOM 操作タスクソースで下記を実行:
      1. レコーダーの非アクティブ化recorderに適用する。
      2. Blobイベント(名前は dataavailable)を recorderblobを添えて発火する。
      3. イベント(名前はstop)を recorderで発火する。

stop(), requestData(), pause() も録音動作に影響する点に注意。

UA は stream を、再生時に元のトラックが取得できる方法で 記録しなければならない(MUST)。Blob が複数返される場合 (timeslicerequestData() により)、 個々の Blob が再生可能でなくてもよいが、 完了した記録から得たすべての Blob を組み合わせたものは 再生できなければならない(MUST)。

MediaStream 内の任意のトラックが muted または enabled でない場合、 UAは黒いフレームまたは無音のみを記録する。 これはトラックによる出力のためである。

レコーダーの非アクティブ化アルゴリズムは recorderに対し、次を行う:

  1. recordermimeType 属性を [[ConstrainedMimeType]] スロットの値に設定
  2. recorderstate 属性を inactive にする
  3. recorder[[ConstrainedBitsPerSecond]] スロットが undefined でなければ、recordervideoBitsPerSecond および audioBitsPerSecond を妥当な値に設定し、その和が [[ConstrainedBitsPerSecond]] に 近くなるようにする。
stop()
MediaRecorder オブジェクトの stop() メソッドが呼び出された場合、UAは 以下の手順を実行しなければならない(MUST):
  1. recorder を、メソッドが呼び出された MediaRecorder オブジェクトとする。
  2. recorderstate 属性が inactive の場合は処理を中止。
  3. レコーダーの非アクティブ化recorder へ適用。
  4. DOM 操作タスクソースで下記ステップを実行:
    1. データの収集を停止する。
    2. blob をこれまで収集した Blob とし、 Blobイベント (名前は dataavailable)を recorderblob を添えて発火する。
    3. イベント(名前は stop)を recorder で発火する。
  5. return undefined
pause()
MediaRecorder オブジェクトの pause() メソッドが呼び出された場合、UAは 以下の手順を実行しなければならない(MUST):
  1. stateinactive の場合は InvalidStateError DOMException を投げて手順を中止。
  2. statepaused の場合は処理を中止。
  3. statepaused にし、以下をDOM 操作タスクソースで実行:
    1. blob へのデータ収集を停止(再開のために保持しておく)。
    2. target を MediaRecorder のコンテキストオブジェクトとし、 イベント pausetarget で発火。
  4. return undefined
resume()
MediaRecorder オブジェクトの resume() メソッドが呼び出された場合、 UAは以下の手順を実行しなければならない(MUST):
  1. stateinactive なら InvalidStateError DOMException を投げて手順を中止。
  2. staterecording なら処理を中止。
  3. staterecording にし、次をDOM 操作タスクで実行:
    1. 現在の blob へのデータ収集を再開または続行。
    2. target を MediaRecorder コンテキストオブジェクトとし、 イベント resumetarget で発火。
  4. return undefined
requestData()
MediaRecorder オブジェクトの requestData() メソッドが呼び出された場合、 UAは以下の手順を実行しなければならない(MUST):
  1. stateinactive なら InvalidStateError DOMException を投げてステップを終了。そうでなければUAは DOM 操作タスクソースで以下を実行:
    1. blob を、ここまで収集した Blob とし、targetMediaRecorder コンテキストオブジェクトとしたうえで、 Blobイベント dataavailabletargetblob として発火。 (まだデータがなければ blob は空)
    2. 新たな Blob を作成し、以降のデータをそこへ貯める。
  2. return undefined
isTypeSupported(DOMString type)
このメソッドは非推奨であり、レガシー互換のためだけに存在する。 同期的に公開されるコーデック識別子一覧 は以下の通り: "vp8", "vp9", "h264" (= "avc1"), "av1"(= "av01"), "hvc1", "hev1", "avc1", "avc3", "opus" および "pcm"
ハードウェアサポートを同期で検出するのは難しいため、 正確な答えはタイミング依存な場合がある。ユーザーは MediaCapabilities を通じて具体的なプロファイルレベルや新コーデックを 見つけることが期待される:
const {supported} = await navigator.mediaCapabilities.encodingInfo({
  type: "record",
  video: {
    contentType: "video/webm;codecs=av01.0.19M.08",
    width: 640,
    height: 480,
    framerate: 30,
    bitrate: 300000,
  }
});
指定した MIME タイプで MediaRecorder が録音できるかどうかを確認する。 true が返った場合、その型で MediaRecorder 実装が Blob オブジェクトを記録できることを示すだけである。十分なリソースがない場合は 実際のメディアエンコードに失敗することがある。このメソッド呼び出し時、 UAは is type supported の結果(第1引数と false を与える)を返す。
is type supported アルゴリズムは type と boolean deferNewerCodecsCheck を受けて 次の手順からなる。
  1. type が空文字列なら true を返す(このケースは コンテナ/コーデックの選択をUAに委ねるのとほぼ同等)。
  2. type が有効な MIME タイプ文字列でなければ false を返す。
  3. MediaRecorder が type で指定された メディアtype/subtype、およびコンテナ組み合わせを サポートしない場合、false を返す。
  4. codecStringsリスト で、typecodecs= があればその後ろを 厳密分割(カンマ)した結果、なければ空リストとする。
  5. codecStrings に オーディオコーデックまたはビデオコーデックが複数ある場合、false を返す。
  6. codecIdentifiers を空リストとする。
  7. codecStrings のそれぞれについて以下を実行:
    1. codecIdentifierASCII小文字化し、 ピリオドで厳密分割した先頭部とする。
    2. appendcodecIdentifiercodecIdentifiers に追加。
    続くアルゴリズムは コーデック指定子(例:"av01")の識別子部分のみをテストする。 ピリオド以降(例:"av01.0.19M.08")は無視される。
  8. codecIdentifiers の各 codecIdentifier について 同期的に公開されている場合、 以下を実行:
    1. MediaRecorder が type で指定された メディアtype/subtype・コンテナと codecIdentifier の 組み合わせをサポートしない場合、false を返す
  9. codecIdentifiers 内に 同期的に公開されていない 項目があれば deferNewerCodecsCheck を返す。
  10. true を返す。
同期的に公開されているか アルゴリズムは codecIdentifier を受けて 次の手順からなる:
  1. 同期公開コーデック識別子一覧 いずれかに正確一致すれば true、それ以外は false。

2.4. データの取り扱い

Blobイベントを発火する とは、Blob blob を用いて、 イベントを発火し、target に対し BlobEvent を使い、 その data 属性を blob で初期化することを意味する。

通常、blob はUAが 最後に recording state へ遷移した後に集めたデータとなる。

2.5. MediaRecorderOptions

dictionary MediaRecorderOptions {
  DOMString mimeType = "";
  unsigned long audioBitsPerSecond;
  unsigned long videoBitsPerSecond;
  unsigned long bitsPerSecond;
  BitrateMode audioBitrateMode = "variable";
  DOMHighResTimeStamp videoKeyFrameIntervalDuration;
  unsigned long videoKeyFrameIntervalCount;
};

2.5.1. メンバー

mimeType, 型:DOMString、デフォルトは ""
録画時のコンテナおよびコーデック形式 [RFC2046]。 フォーマットで定義されている任意のパラメータを含む場合がある。
mimeType は、type/subtype の組み合わせで録画対象のメディア タイプおよびコンテナを指定し、あいまいさが生じうる場合は codecs や profiles パラメータ [RFC6381] で明記します。個々のコーデックにはさらにオプションまたは必須の特定パラメータがある場合があります。
audioBitsPerSecond, 型:unsigned long
音声トラック(Audio track)が存在する場合、そのエンコード時の合計ターゲットビットレート(ビット/秒)。
videoBitsPerSecond, 型:unsigned long
映像トラック(Video track)が存在する場合、そのエンコード時の合計ターゲットビットレート(ビット/秒)。
bitsPerSecond, 型:unsigned long
映像および音声トラック全体のエンコード時の合計ターゲットビットレート(ビット/秒)。 このメンバーは audioBitsPerSecondvideoBitsPerSecond を上書きし、割り振りはUA(ユーザーエージェント)が適切に決定することができます。
audioBitrateMode, 型:BitrateMode、デフォルトは "variable"
音声トラックのエンコードに用いるBitrateMode を指定します。
videoKeyFrameIntervalDuration, 型:DOMHighResTimeStamp
エンコードされたビデオストリームのキーフレーム間の想定時間間隔を指定します。 UAはこの要素および videoKeyFrameIntervalCount を考慮してキーフレーム生成を制御します。
videoKeyFrameIntervalCount, 型:unsigned long
エンコードされたビデオストリームでキーフレーム間のフレーム数を指定します。 UAはこの要素および videoKeyFrameIntervalDuration を考慮してキーフレーム生成を制御します。

2.6. BitrateMode

enum BitrateMode {
  "constant",
  "variable"
};

2.6.1.

constant
固定ビットレートでエンコード。
variable
可変ビットレートでエンコードし、信号が複雑なときは多く、単純なときは少ないデータ量を使用できる。

2.7. RecordingState

enum RecordingState {
  "inactive",
  "recording",
  "paused"
};

2.7.1.

inactive
録画はされていない状態(開始前または停止後)。
recording
録画が開始され、UAがデータを取り込み中。
paused
録画中に一時停止され、まだ停止や再開が行われていない状態。

3. Blobイベント

[Exposed=Window]
interface BlobEvent : Event {
  constructor(DOMString type, BlobEventInit eventInitDict);
  [SameObject] readonly attribute Blob data;
  readonly attribute DOMHighResTimeStamp timecode;
};

3.1. コンストラクタ

BlobEvent(DOMString type, BlobEventInit eventInitDict)

3.2. 属性

data, 型:Blob、読み取り専用
エンコード済みの Blob。 その type 属性がblobデータのエンコーディングを示す。
timecode, 型:DOMHighResTimeStamp、読み取り専用
MediaRecorder インスタンスの場合、最初に生成される BlobEventtimecode には 0 が入っていなければならない(MUST)。次以降の BlobEventtimecode には、その BlobEvent 内で最初に生成されたチャンクのタイムスタンプと、 最初に生成された BlobEvent の 最初のチャンクのタイムスタンプとの差分を DOMHighResTimeStamp で格納する。

3.3. BlobEventInit

dictionary BlobEventInit : EventInit {
  required Blob data;
  DOMHighResTimeStamp timecode;
};

3.3.1. メンバー

data, 型:Blob
Blob オブジェクトで、BlobEvent を介して配信するデータを含む。
timecode, 型:DOMHighResTimeStamp
BlobEvent を初期化する際に使用される BlobEvent の timecode。

4. エラー処理

4.1. 一般原則

このセクションは規範的ではありません。

UAは、呼び出し時にエラーを検出できる場合、DOMException をスローします。それ以外の場合、UAはエラーイベントを発火します。録音が開始され、まだ停止していない状態でエラーが発生した場合、blob をここまで収集した Blob とします。エラーを送出した後、UAはblob を使って dataavailable イベントを発火します。直後に UA は stop という名前のイベント stop を発火します。 UAは、対応可能な Blob サイズや同時に録音できる MediaStreamTrack 数など、プラットフォーム固有の制限を課す場合があります。 これらの制限を超えた場合、致命的なエラーを通知します。

4.2. エラーイベント

エラーイベントを発火するとは、ErrorEventeventConstructor として イベントを発火することです。

4.3. 例外サマリ

このドキュメントで定義されている各例外は、特定の型を持つ DOMException です。

名前 説明
InvalidStateError オブジェクト上で許可されていない操作、または許可されていないタイミングでの操作が呼び出された場合や、 削除・除去されたソースオブジェクトへの要求の場合に発生します。
NotSupportedError MIMEタイプがサポートされていない、またはそのMIMEタイプでトラックセットが録音できない場合に発生します。 ユーザーエージェントはmessage属性にできるだけ追加情報を含めるべきです。
SecurityError MediaStreamアイソレーションプロパティにより、 MediaRecorder のアクセスが許可されていない場合に発生します。
InvalidModificationError 録音対象のMediaStreamMediaStreamTrack セットが変更され、これ以上録画できなくなった場合に発生します。

5. イベント概要

次の追加イベントが MediaRecorder オブジェクト上で発生します:

イベント名 インターフェース 発火条件
start Event UA(ユーザーエージェント)が MediaStream からのデータ記録を開始したとき。
stop Event UA が MediaStream からのデータ記録を停止したとき。
dataavailable BlobEvent UAがデータをアプリケーションに返すためにこのイベントを発火します。 このイベントの data 属性には録音されたデータの Blob が含まれます。
pause Event UAが MediaStream からのデータ記録を一時停止(ポーズ)したとき。
resume Event UAが MediaStream からのデータ記録を再開したとき。
error ErrorEvent エラーが発生したとき(例:メモリ不足や、録音中の stream に対して変更(例:トラックの追加や削除)が発生し継続が不可能になった場合など)。

6. プライバシーとセキュリティの考慮事項

このセクションは規範的ではありません

MediaRecorder のデータソースは常に MediaStream となるので、セキュリティ上の多くは [GETUSERMEDIA] の「プライバシーとセキュリティ考慮事項」節に委ねられます。 特にソース MediaStream安全なコンテキストから供給されることが前提です。

6.1. リソース枯渇

ビデオおよびオーディオエンコーディングは多くの計算資源を消費します。 悪意のあるウェブサイトは、フレーム解像度やフレームレートを大きくすることでUAに過大な負荷をかけて動作不能にしようとする可能性があります。

MediaRecorderstart() 時に timeslice パラメータを使ってエンコード済みデータを一定期間保持できます。timesliceの値が大きすぎると大量データバッファリングを強いられ、動作のもたつきやメモリ枯渇を招きます。

UAは、エンコードやバッファリング過程でリソース枯渇を防ぐ対策を行うべきです。

6.2. 指紋採取

MediaRecorder はサポートされるビデオ・オーディオのMIME型を isTypeSupported() メソッドから知ることができます。また MediaRecorderOptions で明示しなかった場合、UAが最適と判断したコーデックや帯域幅割当てを選び、 type 属性経由で通知します(ondataavailableイベントで取得)。 MediaRecorderOptions の指定も尊重します。

悪意あるウェブサイトがこの情報を アクティブフィンガープリンティング に使う可能性があります。例:

UAは フィンガープリントの表面積を広げないため、可能な限り幅広いコーデック/MIME型をサポートし、 ハードウェアやOSに依存した差異を減らし、デバイス識別を困難にする対応を取る必要があります。 またUAの既定値は情報漏洩や過度な能力識別を防止する方向で設計すべきです。

7.

これらの例の若干修正されたバージョンは例えば このCodepenコレクション などで参照できます。

7.1. MediaRecorder とコンテンツタイプの対応確認

この例では、実装がいくつかの一般的なコーデック/コンテナの組み合わせをサポートしているかを調べます。

以下のサンプルは このCodepen でも最小限の変更で見ることができます。
if (window.MediaRecorder == undefined) {
  console.error('MediaRecorder not supported, boo');
} else {
  var contentTypes = ["video/webm",
                      "video/webm;codecs=vp8",
                      "video/x-matroska;codecs=avc1",
                      "audio/webm",
                      "video/mp4;codecs=avc1",
                      "video/invalid"];
  contentTypes.forEach(contentType => {
    console.log(contentType + ' is '
        + (MediaRecorder.isTypeSupported(contentType) ?
            'supported' : 'NOT supported '));
  });
}

7.2. ウェブカメラの動画と音声を録画する

この例は、MediaStream を使って映像+音声の取得を getUserMedia() で行い、<video> タグに流し、それを録画して ondataavailable イベントで録画片を取得する例です。録画は MediaRecorder を stop() するか、録画された MediaStreamTrack が全て ended になるまで続きます。

以下の例も このCodepen でほぼ同じ形で確認できます。
<html>
<body>
<video autoplay/>
<script>
  var recordedChunks = [];

  function gotMedia(stream) {
    // |video| は取得された MediaStream のライブ映像を表示します。
    var video = document.querySelector('video');
    video.src = URL.createObjectURL(stream);

    var recorder = null;
    try {
      recorder = new MediaRecorder(stream, {mimeType: "video/webm"});
    } catch (e) {
      console.error('Exception while creating MediaRecorder: ' + e);
      return;
    }

    recorder.ondataavailable = (event) => {
      console.log(' Recorded chunk of size ' + event.data.size + "B");
      recordedChunks.push(event.data);
    };

    recorder.start(100);
  }

  navigator.mediaDevices.getUserMedia({video: true, audio: true})
      .then(gotMedia)
      .catch(e => { console.error('getUserMedia() failed: ' + e); });
</script>
</body>
</html>
recordedChunks は例えば MediaRecorder Web Fundamentals記事download() 関数などでファイル保存が可能です。

索引

本仕様で定義されている用語

他仕様で定義される用語

参考文献

規範的な参考文献

[DOM]
Anne van Kesteren. DOM Standard(DOM標準). Living Standard(リビングスタンダード). URL: https://dom.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. 2025年12月3日. WD. URL: https://www.w3.org/TR/FileAPI/
[FINGERPRINTING-GUIDANCE]
Nick Doty; Tom Ritter. Web仕様における ブラウザフィンガープリント対策. 2025年9月25日. NOTE. URL: https://www.w3.org/TR/fingerprinting-guidance/
[GETUSERMEDIA]
Cullen Jennings; 他. Media Capture and Streams(メディアキャプチャとストリーム). 2025年10月9日. CRD. URL: https://www.w3.org/TR/mediacapture-streams/
[HR-TIME]
Yoav Weiss. High Resolution Time(高精度時刻). 2026年3月2日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; 他. HTML標準. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard(インフラ標準). Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2046]
N. Freed; N. Borenstein. Multipurpose Internet Mail Extensions (MIME) 第2部:メディアタイプ. 1996年11月. Draft Standard. URL: https://www.rfc-editor.org/rfc/rfc2046
[WEBDRIVER-BIDI]
James Graham; Alex Rudenko; Maksim Sadym. WebDriver BiDi. 2026年3月9日. WD. URL: https://www.w3.org/TR/webdriver-bidi/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. Living Standard. URL: https://webidl.spec.whatwg.org/

参考情報

[MEDIA-CAPABILITIES]
Jean-Yves Avenard; Mark Foltz. メディア機能(Media Capabilities). 2026年3月16日. WD. URL: https://www.w3.org/TR/media-capabilities/
[RFC6381]
R. Gellens; D. Singer; P. Frojdh. 「Bucket」メディアタイプの "Codecs" および "Profiles" パラメータ. 2011年8月. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6381

IDL 索引

[Exposed=Window]
interface MediaRecorder : EventTarget {
  constructor(MediaStream stream, optional MediaRecorderOptions options = {});
  readonly attribute MediaStream stream;
  readonly attribute DOMString mimeType;
  readonly attribute RecordingState state;
  attribute EventHandler onstart;
  attribute EventHandler onstop;
  attribute EventHandler ondataavailable;
  attribute EventHandler onpause;
  attribute EventHandler onresume;
  attribute EventHandler onerror;
  readonly attribute unsigned long videoBitsPerSecond;
  readonly attribute unsigned long audioBitsPerSecond;
  readonly attribute BitrateMode audioBitrateMode;

  undefined start(optional unsigned long timeslice);
  undefined stop();
  undefined pause();
  undefined resume();
  undefined requestData();

  static boolean isTypeSupported(DOMString type);
};

dictionary MediaRecorderOptions {
  DOMString mimeType = "";
  unsigned long audioBitsPerSecond;
  unsigned long videoBitsPerSecond;
  unsigned long bitsPerSecond;
  BitrateMode audioBitrateMode = "variable";
  DOMHighResTimeStamp videoKeyFrameIntervalDuration;
  unsigned long videoKeyFrameIntervalCount;
};

enum BitrateMode {
  "constant",
  "variable"
};

enum RecordingState {
  "inactive",
  "recording",
  "paused"
};

[Exposed=Window]
interface BlobEvent : Event {
  constructor(DOMString type, BlobEventInit eventInitDict);
  [SameObject] readonly attribute Blob data;
  readonly attribute DOMHighResTimeStamp timecode;
};

dictionary BlobEventInit : EventInit {
  required Blob data;
  DOMHighResTimeStamp timecode;
};