It's simplest to think of an archive as a VCR recording of a set of streams. The OpenTok archiving API lets you archive video streams in sessions. You can then play back archived streams. You can also record stand-alone archives outside of a session and play them back later in OpenTok sessions.
Note: Archiving is only supported in the OpenTok JavaScript library, and it is not supported in the OpenTok on WebRTC JavaScript library.
There are three types of archive:
The basic workflow for using the archiving API is as follows.
First, record the archive:
Note: Many of the methods in the archiving API are restricted to clients who have connected to a session with a token that has been assigned a role of moderator. This documentation refers to such clients as moderators.
Next, playback the archive:
The OpenTok archiving API includes new methods of existing classes of the OpenTok JavaScript library.
The OpenTok archiving API is currently only implemented in the OpenTok JavaScript library. It is not implemented in the OpenTok ActionScript library.
The following existing classes have new methods to support archiving:
The following are new classes used in the archiving API:
For details on these classes, see the OpenTok JavaScript library reference.
Before you can record a session or stream, you need to
create an archive to record into. To create an archive, you call the createArchive()
method of the Session object. You pass three parameters to the createArchive()
method:
apiKey – the API key (a string) that TokBox
provided you when you registered for the OpenTok API.type – a string representing the type of archive.
This can either be "perSession" or "perStream".
Use a per-session archive (of type "perSession") to
record all streams in a session. Use a per-stream archive (of type "perStream")
to record individual streams. title – The title for the archive (a string). This
is optional.When the archive is created, the Session object dispatches an archiveCreated
event. The archiveCreated event includes an archives
property, which is an array of Archive objects. This array contains one
element: the Archive object for the created archive. Make sure to store a
record of the archive ID of the archive you create, so that you can reference
it later when loading the archive for playback. The Archive object has an archiveID
property (which is the archive ID that is unique to the archive).
If an archive has already been created for the session (and
not closed) when you call the createArchive() method, the TB object
will dispatch an exception event.
The application dispatches an error event if the client creating the archive is not a moderator.
The following code creates a per-session archive:
var archive;
var session = TB.initSession(SESSION_ID);
var archiveTitle = "Archive " + new Date().getTime();
session.addEventListener("archiveCreated",
archiveCreateHandler);
session.createArchive(API_KEY, "perSession",
archiveTitle);
function archiveCreateHandler(event) {
archive = event.archives[0];
}
The following code creates a per-stream archive:
var archive;
var session = TB.initSession(SESSION_ID);
var archiveTitle = "Archive " + new Date().getTime();
session.addEventListener("archiveCreated", archiveCreateHandler);
session.createArchive(API_KEY, "perStream",
archiveTitle);
function archiveCreateHandler(event) {
archive = event.archives[0];
}
For details, see the Session.createArchive()
method in the OpenTok JavaScript library reference.
You can use the created archive to record a session or stream. See the next section.
Once you have created a per-session archive (see the previous section), you can record the session to it.
Only clients with appropriate capabilities can record to
archives. Only clients that connect to the session with a moderator token have
this capability. Once you have connected to a session, you can check the capabilities.record
property of the Session object. (See Checking permissions for using the
archiving API.)
Call the startRecording() method of the Session
class to start recording a session. The startRecording()
method takes an Archive object as a required parameter.
When the recording starts, the Session object (in each
connected client's page) dispatches a sessionRecordingStarted event.
This event type is defined by the ArchiveEvent class.
If the session is already being archived when you call the startRecording()
method of the Session object, the Session object dispatches a sessionRecordingInProgress
event. This event type is defined by the ArchiveEvent class.
For each stream that the application records, the publisher's local stream displays the recording-in-progress indicator, which blinks in the upper-right-hand corner of the stream:

The following code creates a per-session archive, calls the startRecording()
method of the Session object, and sets up event listeners:
var archive;
var session = TB.initSession(SESSION_ID);
var archiveTitle = "Archive " + new Date().getTime();
session.addEventListener("archiveCreated", archiveCreatedHandler);
session.createArchive(API_KEY,
"perSession", archiveTitle);
function archiveCreatedHandler(event) {
archive = event.archives[0];
session.addEventListener("sessionRecordingInProgress", recordingInProgressHandler);
session.addEventListener("sessionRecordingStarted", recordingStartedHandler);
session.startRecording(archive);
}
function recordingInProgressHandler(event) {
alert("There is a recording in progress already.");
}
function recordingStartedHandler(event) {
alert("The session is being recorded.");
}
Clients that do not initiate the recording process can check to see if and when the session is being recorded:
archives property of the sessionConnect
event object. If the archives property contains an archive of type "perSession",
the session is being archived at the time of the session connection. sessionRecording
event when the session archive starts. Here is a code sample showing how to check for session recording on a client:
var session = TB.initSession(SESSION_ID);
session.addEventListener("sessionConnected", sessionConnectHandler);
session.addEventListener("sessionRecordingStarted", recordingStartedHandler);
function sessionConnectHandler(event) {
if (event.archives.length > 0
&& event.archives[0].type == "perSession")
{
alert("The session is being recorded.");
}
}
function recordingStartedHandler(event) {
alert("The session is being recorded.");
}
To stop archiving the session, call the stopRecording()
method of the Session object. This method takes one required parameter, archive,
which is the Archive object representing the archive you are recording to. The
Session object dispatches a sessionRecordingStopped event when the
archiving stops. The Session object of every connected client (not just that of
the moderator) dispatches this event. Here is a code sample:
session.addEventListener("sessionRecordingStopped", recordingStoppedHandler);
session.stopRecording(archive); // Call on the moderator page only.
function recordingStoppedHandler(event) {
alert("The session recording has stopped.");
}
Once you have finished archiving the session, call the Session.closeArchive()
method. This method takes the Archive object that you want to close as its one
parameter. Closing an archive makes it available to be loaded and played back.
It also lets you (or another moderator) create another archive for recording.
For more details, see the Session.startRecording()
method, the Session.stopRecording() method, and the Session.closeArchive()
method in the OpenTok JavaScript library reference.
Once you have created a per-stream archive (see Creating an archive), you can record streams to it.
Only clients with appropriate capabilities can record to
archives. Only clients that connect to the session with a moderator token
have this capability. Once you have connected to a session, you can check the capabilities.record
property of the Session object. (See Checking permissions for using the
archiving API.)
The startRecording() method of the Stream
class takes an Archive object as a parameter.
When the recording starts, the Session object (in each
connected client's page) dispatches a streamRecordingStarted event.
This event type is defined by the StreamEvent class.
The following code creates a per-stream archive, adds UI
controls to call the startRecording() method for each Stream object, and sets
up event listeners:
var archive;
var activeStreams;
var session = TB.initSession(SESSION_ID);
session.addEventListener("sessionConnected", sessionConnectedHandler);
session.addEventListener("streamCreated", streamCreatedHandler);
session.connect(API_KEY, TOKEN); // Add values for these.
function sessionConnectedHandler(event) {
var archiveTitle = "Archive " + new Date().getTime();
session.addEventListener("archiveCreated",
archiveCreatedHandler);
session.createArchive(API_KEY, "perStream", archiveTitle);
activeStreams = event.streams;
}
function archiveCreatedHandler(event) {
archive = event.archives[0];
addUIforStreams(activeStreams );
}
function addUIforStreams(streams) {
for (var i = 0; i < streams.length; i++)
{
var startRecording = document.createElement('div');
startRecording.style.float = "bottom";
var link = document.createElement('a');
link.setAttribute("href", "#");
link.setAttribute("onclick", "startRecording('" + streams[i].streamId + "')");
link.innerHtml = "Record stream" + streams[i].streamId;
startRecording.appendChild(link);
document.body.appendChild(startRecording);
// Or append it to a specific DIV
}
}
function startRecording(streamId) {
stream = getStreamForId(streamId);
stream.startRecording(archive);
}
function getStreamForId(streamId) {
for (var i = 0; i < activeStreams.length; i ++) {
if (activeStreams[i].streamId == streamId) {
return activeStreams[i];
}
}
}
Clients that are not initiating the recording process can
check to see if the session is being recorded by checking the archives
property of the sessionConnect event object. If the archives
property contains an archive of type "perStream", individual
streams can be recorded. You can add event listeners for the streamRecordingStarted
event. The Session object dispatches this event when a stream recording starts.
You can check the stream ID of each of the Stream objects in the streams
property of the event, to see if it corresponds to a stream you are publishing.
Here is a code sample showing how to check to see if your stream is being recorded:
var session = TB.initSession(SESSION_ID);
session.addEventListener("sessionConnected", sessionConnectedHandler);
session.connect(API_KEY, TOKEN); // Add values for these.
function sessionConnectedHandler(event) {
session.addEventListener("streamRecordingStarted", recordingStartedHandler);
}
function recordingStartedHandler(event) {
for (var i = 0; i < event.streams.length; i++) {
if (event.streams[i].connection.connectionId == session.connection.connectionId)
{
alert("Your video stream is being recorded.");
}
}
}
To stop recording the stream, the moderator can call the stopRecording()
method of the Stream object. This method takes one required parameter – archive,
the Archive object representing the archive you are recording to. The Session
object dispatches a streamRecordingStopped event when the recording stops.
The Session object on every connected client's page dispatches this event (not
just the recorder's page). Here is a code sample:
session.addEventListener("streamRecordingStopped", recordingStoppedHandler);
myStream.stopRecording(archive);
function recordingStoppedHandler(event) {
for (var i = 0; i < event.streams.length; i++) {
if (event.streams[i].streamId == myStream.streamId)
{
alert("The stream recording has stopped.");
}
}
}
Clients can check to see if a recording of stream they are
publishing has stopped by listening for the streamRecordingStopped
event, which is dispatched by the Session object. Consider the following code:
session.addEventListener("streamRecordingStopped", recordingStoppedHandler);
function recordingStoppedHandler(event) {
for (var i = 0; i < event.streams.length; i++) {
if (event.streams[i].connection.connectionId == session.connection.connectionId)
{
alert("Your video stream is no longer being recorded.");
}
}
}
Once you have finished archiving streams, call the Session.closeArchive()
method. This method takes the Archive object that you want to close as its one required
parameter. Closing an archive makes it available to be loaded and played back.
It also lets you (or another moderator) create another archive for recording.
For more details, see the Stream.startRecording()
method, the Stream.stopRecording() method, and the Session.closeArchive()
method in the Archiving API JavaScript reference.
Clients with appropriate capabilities can load an archive
and play it back. Only clients that connect to the session with a moderator
token have this capability. Once you have
connected to a session, you can check the capabilities.playback
property of the Session object. (See Checking permissions for using the
archiving API.)
Call the loadArchive() method of a Session
object to load an Archive object. You pass in the archive ID to the loadArchive()
method.
Note that you must store a record of the archive IDs of archives you create (so that you can reference them later when loading the archive for playback).
Then you can call the startPlayback()
method of the Archive object to start playback. Call the stopPlayback()
method of the Archive object to stop playback.
As streams of the archive playback, the Session object of
all connected clients dispatches streamCreated events. You can then
subscribe to the streams and display them on the page by calling the subscribe()
method of the Session object.
You subscribe to archive streams just as you subscribe to
live streams: by calling the the subscribe() method of the Session
object. Note that the type property of archive streams is
set to "archive".
Here is a basic code sample:
var session = TB.initSession(SESSION_ID); // Add a value for SESSION_ID.
var archive;
var ARCHIVE_ID = "replace_me";
// Replace this with the archive ID for
// the archive you want to play.
session.addEventListener("sessionConnected", sessionConnectedHandler);
session.addEventListener("streamCreated", streamCreatedHandler);
session.addEventListener("archiveLoaded", archiveLoadedHandler);
session.connect(API_KEY, TOKEN); // Add values for API_KEY and TOKEN.
function sessionConnectedHandler(event) {
session.loadArchive(ARCHIVE_ID); // You will need to store this.
}
function archiveLoadedHandler(event) {
loadedArchive = event.archives[0];
loadedArchive.startPlayback();
}
function streamCreatedHandler(event) {
for (var i = 0; i < event.streams.length; i++) {
if (event.streams[i].type == "archive") {
subscribeToStream(event.streams[i]);
}
}
}
function subscribeToStream(stream) {
var replacementDiv = document.createElement('div');
document.body.appendChild(replacementDiv); // Just an example.
session.subscribe(stream, replacementDiv);
}
The Session object dispatches a playbackStarted
event when the archive starts playing. The Session object also dispatches streamCreated
events as streams of the archive play back. Streams will play back with the
same relative timing as when they were created during the recording.
You can call the stopPlayback() method of the
Archive object to stop playback. This stops playing the archive for all clients
connected to the session. The Session object for each connected client
dispatches streamDestroyed events (for streams playing in the
archive). It also dispatches a playbackStopped event.
Note: If all clients disconnect from a session, any archive playing in that session stops.
A session can only playback one archive at a time.
Otherwise, the TB object dispatches an exception event.
For details, see the Session.loadArchive()
method, the Session.startPlayback() method, and the Session.stopPlayback()
method in the OpenTok JavaScript library reference.
In order to call any of the following methods, the client must be assigned a moderator token:
Archive.startPlayback();RecorderManager.displayRecorder();RecorderManager.displayPlayer();Session.startRecording();Stream.startRecording();To check if the client has adequate permissions, check the following properties of the Session object:
capabilities.playback – for Archive.startPlayback() and RecorderManager.displayPlayer()capabilities.record – for Session.startRecording(), Stream.startRecording(),
and RecorderManager.displayRecorder()Stand-alone archives are recordings of videos that are recorded outside of the context of an OpenTok session. You can then play back a stand-alone video by itself, or you can play it in an OpenTok session.
recManager = TB.initRecorderManager(API_KEY); // Pass in your OpenTok API key.
initRecorderManager() takes one parameter: your OpenTok API key. The recordings you make will be available to all
OpenTok sessions and Player objects associated with this API key.
var TOKEN = ""; // Replace with a generated token that has been assigned the moderator role.
// See https://dashboard.tokbox.com/projects
var recorder = recManager.displayRecorder(TOKEN, "recorderReplacementElementId");
The displayRecorder() method returns a Recorder object. The recorder is displayed in the HTML page. The first parameter of the method is a token string. The token must have been created with a role of moderator to use this API. The second parameter is the HTML DOM element ID that is replaced by the recorder.
The recorder includes the following user interface controls:
recordingStarted event.recordingStopped event.playbackStarted event.archiveSaved event when the archive is saved. (Note: you
can choose to hide this button by setting the showSaveButton property of the
properties parameter of the displayRecorder() method to
false.) You can also save a recording by calling the saveArchive()
method of the Recorder object.saveArchive() method of the Recorder object.
The Recorder object dispatches a archiveSaved event when the archive
is created on the OpenTok servers. This event is defined by the ArchiveEvent class.
The value of the archiveId property is the unique archive ID.
Important: You will want to store the archiveID property of this event
for future playback of the archive. For example, you may want to store this in a
server-side database table.
removeRecorder() method of the
RecorderManager object:recManager.removeRecorder(recorder);
The removeRecorder() method takes one parameter: the Recorder object that you
wish to remove.
Once you have recorded and saved an archive, you can play the archive back in a stand-alone player, or you can play it back in an OpenTok session. If you play an archive back in an OpenTok session, all clients connected to the session can view the archive playback.
You can play a stand-alone archive (recorded using the Recorder class) in a stand-alone player:
displayPlayer() method of
the RecorderManager object:
var player = recManager.displayPlayer(archiveId, token, replacementElementId);
The displayPlayer() method takes the following parameters:
archiveId (String) The archive ID of the archive
you wish to play back. This can only be an archive that was created using the
Recorder class.token (String) An OpenTok token string. The token must have been
assigned the role of moderator.replacementElementId (String) The ID of the DOM element that
the player will replace. Calling the displayPlayer() method results in the player being added
to the HTML DOM. The player loads and plays the specified archive. When the archive
is loaded, the Player object dispatches an archiveLoaded event.
The player includes a button for starting playback. The Player object
dispatches a playbackStarted event when playback starts. The Player object
dispatches a playbackStopped event when playback stops.
loadArchive() method of
the Player object:
player.loadArchive(archiveId);
This method takes one parameter: the archive ID of the archive you want to play.
removePlayer() method of the
RecorderManager object:
recManager.removePlayer(player);
The removePlayer() method takes one parameter: the Player object that you
wish to remove.
You can also play back an archive in an OpenTok session.
In an OpenTok session, you can play back an archive recorded with the stand-alone recorder. The workflow for playing back such an archive is the same as that for playing back a per-stream or per-session recording. The archive plays back as a stream that clients can subscribe to. (Note: there are no play and stop buttons when you play back an archive in a session.)
TB.initSession() method to create a Session object. The
session must be created with the same API key as was used when you recorded the archive.
(Use the createSession() method of the server-side API to create an
OpenTok session.)loadArchive() method of the Session object, and set up an event listener
for the archive :
session.addEventListener("archiveLoaded", archiveLoadedHandler);
session.loadArchive(archiveId);
var archive;
function archiveLoadedHandler(event) {
archive = event.archives[0];
}
The type property of an archive created with the Recorder object is set to
"individual".
startPlayback() method of the Archive object:
archive.startPlayback();
streamCreated event for the archive's audio-video stream. Clients
can subscribe to the stream by calling the subscribe() method of the Session
object.
You can download videos you record, using the OpenTok server-side library or a REST API. You pass in a token (created with your API key and assigned a role of moderator), and an archive ID. Downloaded videos are FLV files. For more information, see Downloading archive videos.
You can delete videos you record, using a REST API. You pass in a token (created with your API key and assigned a role of moderator) and an archive ID. For more information, see Deleting archives.
You can composite videos of multi-stream archives, using a REST API. You pass in a token (created with your API key and assigned a role of moderator) and an archive ID. For more information, see Generating a composite video of a multi-stream archive.