Archiving
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: The OpenTok archiving API is in a beta program. If you find any bugs, have any feedback or any feature requests, please let us know in the OpenTok Archiving forum.
There are three types of archive:
- Per-session archives record all streams in a session that are active during the archiving.
- Per-stream archives let you select the streams of a session that you want to record.
- Stand-alone archives, added in OpenTok v0.91.26, let you record videos outside of a session. You can then play the archive in a stand-alone player or in an OpenTok session. For more information, see Recording and playing back stand-alone archives.
The basic workflow for using the archiving API is as follows.
First, record the archive:
- A moderator creates a new archive. Clients that publish audio-video streams to
the session are notified that they may be recorded. They can agree to being
recorded or leave the session.
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.
- The moderator starts recording to the archive.
- The moderator stops recording to the archive.
- The moderator closes the archive. This makes it available for playback
Next, playback the archive:
- A moderator loads a previously recorded archive.
- The moderator plays the archive. Recorded streams start playing back and generate events that let connected clients subscribe to the streams.
- The moderator can stop the archive before it finishes or let the archive play to the end.
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:
- Capabilities
- Event
- Session
- Stream
- SessionConnectEvent
- StreamEvent
The following are new classes used in the archiving API:
- Archive
- ArchiveEvent
For details on these classes, see the OpenTok JavaScript library reference.
Creating an archive
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.
Note: When using the OpenTok staging environment, archives are limited to 5 minutes in length. Archives in the staging environment are deleted after 3 days.
You can use the created archive to record a session or stream. See the next section.
Recording a session
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:
- You can check the
archivesproperty of thesessionConnectevent object. If thearchivesproperty contains an archive of type"perSession", the session is being archived at the time of the session connection. - The Session object dispatches a
sessionRecordingevent 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("sessionConnect", 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.
Recording individual streams
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 (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 (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 (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 (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 (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.
Loading and playing back an archive
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 (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.
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.
Checking permissions for using the archiving API
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– forArchive.startPlayback()andRecorderManager.displayPlayer()capabilities.record– forSession.startRecording(),Stream.startRecording(), andRecorderManager.displayRecorder()
Recording and playing back stand-alone archives
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.
Recording a stand-alone archive
- To start recording, you first initialize a RecorderManger object by calling the initRecorderManager() method of the TB object.
recManager = TB.initRecorderManager(API_KEY); // Pass in your OpenTok API key.
- The
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. - Next call the displayRecorder() method of the RecorderManger object:
var recorder = recManager.displayRecorder("moderator_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:
- A Record button (to start recording) When the user clicks this button, the
Recorder object dispatches a
recordingStartedevent. - A Stop button (to stop the recording) When the user clicks this button, the
Recorder object dispatches a
recordingStoppedevent. - A Play button (to review a recording) When the user clicks this button, the
Recorder object dispatches a
playbackStartedevent. - A Re-record button (to redo a recording before saving it).
- A Save button (to save the recording) When the user clicks this button, the
archive is saved to the OpenTok servers. The Recorder object dispatches an
archiveSavedevent when the archive is saved. (Note: you can choose to hide this button by setting theshowSaveButtonproperty of thepropertiesparameter of thedisplayRecorder()method tofalse.) You can also save a recording by calling thesaveArchive()method of the Recorder object.
- A Record button (to start recording) When the user clicks this button, the
Recorder object dispatches a
- The recording is saved when the user clicks the Save button or when you call the
saveArchive()method of the Recorder object.The Recorder object dispatches a
archiveSavedevent when the archive is created on the OpenTok servers. This event is defined by the ArchiveEvent class. The value of thearchiveIdproperty is the unique archive ID.Important: You will want to store the
archiveIDproperty of this event for future playback of the archive. For example, you may want to store this in a server-side database table. - To remove the recorder from the page, call the
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.
Playing back a stand-alone archive
You can play a stand-alone archive (recorded using the Recorder class) in a stand-alone player:
- Instantiate a Player object by calling the
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 anarchiveLoadedevent.The player includes a button for starting playback. The Player object dispatches a
playbackStartedevent when playback starts. The Player object dispatches aplaybackStoppedevent when playback stops. - You can load another archive into a player. Call the
loadArchive()method of the Player object:player.loadArchive(archiveId);
This method takes one parameter: the archive ID of the archive you want to play.
- To remove the player from the page, call the
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.)
- Call the
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 thecreateSession()method of the server-side API to create an OpenTok session.) - Call the
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
typeproperty of an archive created with the Recorder object is set to"individual". - Call the
startPlayback()method of the Archive object:archive.startPlayback();
- When the archive starts playing back, the Session object in each connected client's page
dispatches a
streamCreatedevent for the archive's audio-video stream. Clients can subscribe to the stream by calling thesubscribe()method of the Session object.
Downloading archive videos
You can download videos you record, using the OpenTok server-side library or a RESTful web 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.
Deleting archive videos
You can delete videos you record, using a RESTful web 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.
IRC Live Chat
Have a quick question? Chat with other developers. Join chat
TokBox staff may not be online right now. To reach them during off-hours, visit the forums.