The OpenTok archiving API lets you record audio-video streams in a session to MP4 files. You use server-side code to start and stop archive recordings.
In order to archive OpenTok sessions (to save recordings of sessions), you need to have a server set up. There are many ways to implement archiving with a server, but for this tutorial we'll be quick-launching a simple PHP server.
To launch the server, simply click the Heroku button below, at which point you'll be sent to Heroku's website and prompted for your OpenTok API Key and API Secret — you can get these values on your project page in your Video API account. If you don't have a Heroku account, you'll need to sign up (it's free).
Want to explore the code? The button above launches server code from the learning-opentok-php GitHub repo. Visit the repo to review the code as well as additional documentation — you can even fork the repo and make changes before deploying.
To follow this tutorial, clone OpenTok's Android sample app repo on GitHub:
git clone https://github.com/opentok/opentok-android-sdk-samples.git
Then open the Archiving-Java project in Android Studio.
Note: This tutorial discusses the Java version of the Android sample app. For a Kotlin version with documentation, see the Android sample app repo.
Important: You can only archive sessions that use the OpenTok Media Router (sessions with the media mode set to routed). The default learning-opentok-php code used by this tutorial app uses routed sessions.
Note: The Android archiving sample app builds upon the Basic-Video-Chat app.
In the ServerConfig
file, you set the CHAT_SERVER_URL
property to the base URL:
public static final String CHAT_SERVER_URL = "https://YOURAPPNAME.herokuapp.com";
The endpoints of the web service the app calls to start archive recording, stop recording, and play back the recorded video are defined in the APIService
interface:
public interface APIService {
@GET("session")
Call getSession();
@POST("archive/start")
@Headers("Content-Type: application/json")
Call startArchive(@Body StartArchiveRequest startArchiveRequest);
@POST("archive/{archiveId}/stop")
Call stopArchive(@Path("archiveId") String archiveId);
}
When the user selects the start archive
, stop archive
, and play archive
menu items from the action
bar or the options menu, the app calls the startArchive()
and stopArchive()
, and playArchive()
methods. These methods internally call the web services defined above:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle app bar item clicks here. The app bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.action_start_archive:
startArchive();
return true;
case R.id.action_stop_archive:
stopArchive();
return true;
case R.id.action_play_archive:
playArchive();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The MainActivity
class includes an archiveListener
property that implements the
Session.ArchiveListener
interface providing callbacks for handling archive-related events: onArchiveStarted
and onArchiveStopped
.
When the user clicks the start archive
button, the app calls archive/start
endpoint via the startArchive()
method.
When the archive recording starts, the onArchiveStarted()
callback is triggered:
@Override
public void onArchiveStarted(Session session, String archiveId, String archiveName) {
currentArchiveId = archiveId;
setStopArchiveEnabled(true);
archivingIndicatorView.setVisibility(View.VISIBLE);
}
The onArchiveStarted()
method stores the archive identifier in a currentArchiveId
property.
The method also calls setStopArchiveEnabled(true)
, which causes the stop recording
menu item to be displayed. And it causes archivingIndicatorView
to be displayed (a red dot on the video).
When the user clicks the stop archive
button, the app calls archive/stop
endpoint via the stopArchive()
method.
When archive recording stops, the onArchiveStopped()
callback is triggered:
@Override
public void onArchiveStopped(Session session, String archiveId) {
playableArchiveId = archiveId;
currentArchiveId = null;
setPlayArchiveEnabled(true);
setStartArchiveEnabled(true);
archivingIndicatorView.setVisibility(View.INVISIBLE);
}
The onArchiveStopped()
method stores the archive identifier to a playableArchiveId
property
and sets currentArchiveId
to null
. The method also calls setPlayArchiveEnabled(false)
, which disables the Play Archive menu item, and it calls setStartArchiveEnabled(true)
to
enable the Start Archive menu item. And it causes the archivingIndicatorView
to be hidden.
When the user clicks the play archive
button, the playArchive()
method
opens a web page (in the device's web browser), which displays the archive recording.
Notes:
In most applications, control of the archive recording would not be granted to each end-user.
You can have automatically archived sessions, which are recorded whenever a client starts publishing a stream.
You will want to set up an Amazon S3 or Microsoft Azure target for storage of your archive recordings.
For more information on archiving, see the OpenTok archiving developer guide.
Congratulations! You've finished the Archiving Tutorial for Android.
You can continue to play with and adjust the code you've developed here, or check out the Next Steps below.
When you're finished here, continue building and enhancing your OpenTok application with these helpful resources: