This document defines a recording API for use with MediaStreams as defined in [[!GETUSERMEDIA]]

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is not complete. It is subject to major changes and, while early experimentations are encouraged, it is therefore not intended for implementation. The Media Capture Task Force expects this specification to evolve significantly based on:

This document was published by the Web Real-Time Communication Working Group as an Editor's Draft. If you wish to make comments regarding this document, please send them to public-media-capture@w3.org (subscribe, archives). All feedback is welcome.

Publication as an Editor's Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures (Web Real-Time Communication Working Group, Device APIs Working Group) made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Overview

This API attempts to make basic recording very simple, while still allowing for more complex use cases. In the simplest case, the application instatiates the MediaRecorder object, calls record() and then calls stop() or waits for the MediaStream to be ended. The contents of the recording will be made available in the platform's default encoding via the dataavailable event. Functions are available to query the platform's available set of encodings, and to select the desired ones if the author wishes. The application can also choose how much data it wants to receive at one time. By default a Blob containing the entire recording is returned when the recording finishes. However the application can choose to receive smaller buffers of data at regular intervals.

Media Recorder API

For the definition of the Constrainable API, see [[!GETUSERMEDIA]]. For the definition of MediaRecorder's constrainable properties see MediaRecorder Constrainable Properties.

readonly attribute MediaStream stream
The MediaStream passed in to the constructor.
readonly attribute RecordingStateEnum state
The current state of the MediaRecorder object.
attribute EventHandler onstart
Called to handle the start event.
attribute EventHandler onstop
Called to handle the stop event.
attribute EventHandler ondataavailable
Called to handle the dataavailable event. Note that the Blob (see [[!FILE-API]]) of recorded data is contained in this event and can be accessed via the 'data' attribute.
attribute EventHandler onpause
Called to handle the pause event.
attribute EventHandler onresume
Called to handle the resume event.
attribute EventHandler onerror
Called to handle the DOMError event.
attribute EventHandler onwarning
Called to handle the recordingwarning event.
void start()
When a MediaRecorder object’s start() method is invoked, the UA must queue a task, using the DOM manipulation task source, that runs the following steps:
  1. If the state is not "inactive", raise a DOM InvalidState error and terminate these steps. Otherwise:
  2. Set state to 'recording' and wait until media becomes available from stream.
  3. Once data becomes available raise a start event and start gathering the data into a Blob (see [[!FILE-API]]).
  4. If the timeSlice argument has been provided, then once timeSlice milliseconds of data have been colleced, or some minimum time slice imposed by the UA, whichever is greater, raise a dataavailable event containing the Blob of collected data, and start gathering a new Blob of data. Otherwise (if timeSlice has not been provided), continue gathering data into the original Blob.
  5. When the stream is ended set recording to 'false' and stop gathering data. . Callers SHOULD not rely on exactness of the timeSlice value, especially if the timeSlice value is small. Callers SHOULD consider timeSlice as a minimum value
  6. Then raise a dataavailable event containing the Blob of data.
  7. Finally, raise a stop event.

Note that stop(), requestData(), and pause also affect the recording behavior.

The UA must record the MediaStream in such a way that the original Tracks can be retrieved at playback time. When multiple Blobs are returned (because of timeSlice or requestData), the individual Blobs need not be playable, but the combination of all the Blobs from a completed recording must be playable. If any Track within the MediaStream is muted at any time (i.e., if its readyState is set to muted), the UA must insert black frames or silence until the Track is unmuted. If the UA is unable to start recording or at any point is unable to contine recording, it must raise a DOMError event, followed by a dataavailable event containing the Blob it has gathered, follwed by the stop event.

optional long timeslice
The number of milliseconds of data to return in a single Blob.
void stop()
When a MediaRecorder object’s stop method is invoked, the UA must queue a task, using the DOM manipulation task source, that runs the following steps:
  1. If state is "inactive", raise a DOM InvalideStateErrorevent and terminate these steps. Otherwise:
  2. Set state to 'inactive' and stop gathering data.
  3. Raise a dataavailable event containing the Blob of data that has been gathered.
  4. Raise a stop event
void pause()
When a MediaRecorder object’s pause()method is invoked, the UA must queue a task, using the DOM manipulation task source, that runs the following steps:
  1. If state is "inactive" raise a DOM InvalidState error and terminate these steps. Otherwise:
  2. Set state to "paused".
  3. Stop gathering data into its current Blob (but keep the Blob available so that recording can be resumed in the future).
  4. Raise a pause event
void resume()
When a MediaRecorder object’s resume() method is invoked, the UA must queue a task, using the DOM manipulation task source, that runs the following steps:
  1. If state is "inactive" raise a DOM InvalidState error and terminate these steps. Otherwise:
  2. Set state to "recording".
  3. Resume (or continue) gathering data into its current Blob.
  4. Raise a resume event.
void requestData()
When a MediaRecorderobject’s requestData() method is invoked, the UA must queue a task, using the DOM manipulation task source, that runs the following steps:
  1. If state is not "recording" raise a DOM InvalidState error and terminate these steps. Otherwise:
  2. Raise a dataavailable event containing the current Blob of saved data. (Note that this Blob will be empty if no data has been gathered yet.)
  3. Create a new Blob and gather subsequent data into it.

The MediaRecorder() constructor takes one argument which must be of type MediaStream (see [[!GETUSERMEDIA]]). When the constructor is invoked, the UA must construct a new MediaRecorder object, set its mediaStream attribute to be the provided MediaStream, set its state attribute to 'inactive' and return the object.

RecordingStateEnum

inactive
Recording is not occuring. (Either it has not been started or it has been stopped.).
recording
Recording has been started and the UA is capturing data..
paused
Recording has been started, then paused, and not yet stopped or resumed.

Blob Event

readonly attribute Blob data
Returns a Blob object whose type attribute indicates the encoding of the blob data.

BlobEventInit

Blob data
A Blob object containing the data to deliver via this event.

MediaRecorder Constrainable Properties

IANA is requested to register the following properties as specified in [[!RTCWEB-CONSTRAINTS]]:

Property Name Values Notes
MimeType list of DOMString The MIME types that can be selected as encodings for recording. The UA should be able to play back any of the MIME types it supports for recording. For example, it should be able to display a video recording in the HTML <img> tag.
imageHeight PropertyValueRange The maximum and minimum height, in pixels, for the capture of videomages
imageWidth PropertyValueRange The maximum and minimum width, in pixels, for the capture of videomages

Error Handling

General Principles

Errors are indicated in two ways: exceptions and objects passed to error callbacks. In the former case, a DOMException is raised (see [[!DOM4]]). An exception must be thrown when the error can be detected at the time that the call is made. In all other cases, an DOMError object(see [[!DOM4]]) must be provided to the failure callback. The error name in the object provided must be picked from the RecordingErrorName enums. If recording has been started and not yet stopped when the error occurs, then after raising the error, the UA must raise a dataavailable event, containing any data that it has gathered, and then a stop event. The UA may set platform-specific limits, such those for the minimum and maximum Blob size that it will support, or the number of Tracks it will record at once. It must signal a fatal error if these limits are exceeded. If a non-fatal error occurs during recording, the UA should raise a recordingwarning event, with data indicating the nature of the problem, and continue recording.

RecordingErrorNameEnum

InvalidState
The MediaRecorder is not in a state in which the proposed operation is allowed to be executed.
OutOfMemory
The UA has exhaused the available memory. User agents SHOULD provide as much additional information as possible in the message attribute.
IllegalStreamModification
A modification to the stream has occurred that makes it impossible to continue recording. An example would be the addition of a Track while recording is occurring. User agents SHOULD provide as much additional information as possible in the message attribute.
OtherRecordingError
Used for an fatal error other than those listed above. User agents SHOULD provide as much additional information as possible in the message attribute.

RecordingExceptionEnum

InvalidMediaStreamTrackId
The argument provided is not the ID of any MediaStreamTrack belonging to the MediaRecorder's stream.
UnsupportedOption
The UA cannot provide the codec or recording option that has been requested.

Event summary

The following additional events fire on MediaRecorder objects:

Event name Interface Fired when...
start Event The UA has started recording data on the MediaStream.
stop Event The UA has stopped recording data on the MediaStream.
dataavailable BlobEvent The UA generates this even to return data to the application. The 'data' attribute of this event contains a Blob of recorded data.
pause Event The UA has paused recording data on the MediaStream.
resume Event The UA has resumed recording data on the MediaStream.
DOMError DOMError A fatal error has occurred and the UA has stopped recording. More detailed error information is available in the 'message' attribute.
warning CustomEvent A problem has occurred, but the UA has not stopped recording. More detailed information is available in the 'message' attribute. [Not clear if we need this event.]

Open Issues

  1. Do we need an MTI format?
  2. Do we need a "setSyncPoint()" operator and a "syncpoint" signal, so that the client can tell the recorder to insert a point at which a recording can be broken up (typically a new I-frame)?
  3. Do we need warning events?
  4. Do we need to ask the user's permission before we record?