Follow this step-by-step tutorial to implement the video playback Synchronization SDK.
While the client-side SDK will take care of most of the functionality, in order to make this sample application work, you will need to use the API_KEY provided to you.
An Access Token is needed in order to allow a client to connect to a sync group.
Note: It is important that the client application does not request an Access Token directly from the backend. By doing that you risk exposing the API_TOKEN and API_SECRET.
You can get your API_KEY and API_SECRET in your private area, here.
Note: Every Sync Token corresponds to one specific sync group only. To allow two different clients to connect to the same group, the clients need to use the same Access Token.
Create a project
Open the Android Studio and select New Project from the File menu
Select Empty Activity and click next
Choose Java or Kotlin as your programming language for the project
Configure your project's location, application, and package names
Set the minimum SDK version of the application to 21 or higher
Add the sync SDK library to your project
Create (if it does not exist) in the project a libs directory under the app folder
Add the file wtsyncsdk_v....aar to the libs folder
Edit the application's build.gradle file (in the app folder) with SDK
if (mSyncSdk !=null) {mSyncSdk.groupSeek(position);}
mSyncSdk?.groupSeek(position)
Group seek success
if (mSyncSdk !=null) {mSyncSdk.groupSeekSuccess(position);}
mSyncSdk?.groupSeekSuccess(position)
Managing synchronization logic
The synchronization logic is managed using callbacks, using them you will be able to create the interaction you need.
In the sample application, you can see an example for implementing the necessary callbacks
publicclassMainActivityextendsAppCompatActivityimplementsSyncListener {... @OverridepublicvoidonClientList(@NotNullList<SyncClient> syncClients) {// remote sync client joined to the group, update ui using adapter// update ui with the list of connected clients in the same group } @OverridepublicvoidonSetPlaybackRate(float rate) {// setting playback rate } @OverridepublicvoidonPlaybackFromPosition(long position) {// playback from position// player.seekTo(position); } @OverridepubliclongonGetPlayerPosition() {// getting player position// Implement your logic to extract player position in miliseconds,// be sure that all clients connected to the same group extracts relevant// and from the same content timestamps(position)// return player.getCurrentPosition();return0L; } @OverridepublicfloatonGetPlaybackRate() {// getting playback rate// Implement your logic to extract player rate/speed// return player.speed;return0f; } @OverridepublicvoidonSyncInfo(@NotNullSyncInfo syncInfo) {// information about synchronization's accuracy and delta// syncInfo.accuracy 0.0% - 100.0%// syncInfo.delta starts from 0L and describes how big is delay// in miliseconds, can be negative value } @OverridepublicvoidonSyncGroupPlay() {// received an event onSyncGroupPlay()// play function should be called if its not playing alreadyif (!player.isPlaying()) { player.play(); } } @OverridepublicvoidonSyncGroupPause() {// received an event onSyncGroupPause()// pause function should be called if its still playingif (player.isPlaying()) { player.pause(); } } @OverridepublicvoidonSyncGroupSeek(long position) {// received an event onSyncGroupSeek(long position) with position parameter// seek function should be called to the given position// works with VODif (!player.isCurrentWindowLive()) { player.seekTo(position); }// Client should send success seek request every time onSyncGroupSeek calledif (mSyncSdk !=null) {mSyncSdk.groupSeekSuccess(position); } } @OverridepublicvoidonSyncDisconnected() {// client has been disconnected from the group. All connections // will be closed. Clear ui and data }}
classMainActivity : AppCompatActivity(), SyncListener {...overridefunonClientList(syncClients: List<SyncClient>) {// remote client joined to the group, update ui using adapter// update ui with the list of connected clients in the same group }overridefunonSetPlaybackRate(rate: Float) {// setting playback rate }overridefunonPlaybackFromPosition(position: Long) {// playback from position// player.seekTo(position) }overridefunonGetPlayerPosition(): Long {// getting player position// Implement your logic to extract player position in miliseconds,// be sure that all clients connected to the same group extracts relevant// and from the same content timestamps(position)// return player.getCurrentPosition()// Important! In case if content is Http Live Stream// Value of position shoulb be based on Program-Date-Time tag return0L }overridefunonGetPlaybackRate(): Float {// getting playback rate// Implement your logic to extract player rate/speed// return player.speedreturn0f }overridefunonSyncInfo(syncInfo: SyncInfo)// information about synchronization's accuracy and delta// syncInfo.accuracy 0.0% - 100.0%// syncInfo.delta starts from 0L and describes how big is delay// in miliseconds, can be negative value }overridefunonSyncGroupPlay() {// received an event onSyncGroupPlay()// play function should be called player.play() }overridefunonSyncGroupPause() {// received an event onSyncGroupPause()// pause function should be called player.pause() }overridefunonSyncGroupSeek(position: Long) {// received an event onSyncGroupSeek(long position) with position parameter// seek function should be called to the given position// works with VODif (!player.isCurrentWindowLive) { player.seekTo(position) }// Client should send success seek request every time onSyncGroupSeek called mSyncSdk?.groupSeekSuccess(position) }overridefunonSyncDisconnected() {// client has been disconnected from the group. All connections will be closed.// clear ui and data }
Running the application
Once coding is finished, you should be able to run the application in the Android Studio emulator.
You can view the complete Watch Together sample application here