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: 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:

  • 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 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:

  1. 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.

  2. The moderator starts recording to the archive.
  3. The moderator stops recording to the archive.
  4. The moderator closes the archive. This makes it available for playback

Next, playback the archive:

  1. A moderator loads a previously recorded archive.
  2. The moderator plays the archive. Recorded streams start playing back and generate events that let connected clients subscribe to the streams.
  3. 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.

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 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.
  • The Session object dispatches a 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.

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 (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.

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 (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.

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 – for Archive.startPlayback() and RecorderManager.displayPlayer()
  • capabilities.record – for Session.startRecording(), Stream.startRecording(), and RecorderManager.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

  1. 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.
  2. 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.
  3. Next call the displayRecorder() method of the RecorderManger object:
    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:

    • A Record button (to start recording) — When the user clicks this button, the Recorder object dispatches a recordingStarted event.
    • A Stop button (to stop the recording) — When the user clicks this button, the Recorder object dispatches a recordingStopped event.
    • A Play button (to review a recording) — When the user clicks this button, the Recorder object dispatches a playbackStarted event.
    • 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 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.
  4. 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 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.

  5. To remove the recorder from the page, call the removeRecorder() method of the RecorderManager object:
  6. 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:

  1. 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 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.

  2. 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.

  3. 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.)

  1. 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 the createSession() method of the server-side API to create an OpenTok session.)
  2. 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 type property of an archive created with the Recorder object is set to "individual".

  3. Call the startPlayback() method of the Archive object:
    archive.startPlayback();
  4. When the archive starts playing back, the Session object in each connected client's page dispatches a streamCreated event for the archive's audio-video stream. Clients can subscribe to the stream by calling the subscribe() method of the Session object.

Downloading archive videos

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.

Deleting 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.

Creating composite videos of multi-stream 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.

IRC Live Chat

Have a quick question? Chat with TokBox Support on IRC. Join chat