Skip to main content
Skip table of contents

Controlling playback and zapping between streams

To view and test the full “controlbar” example code referenced here, please see the (5.33.x) Android SDK 5 Example Code Quick Start guide.

The CONNECT Player does not provide a control bar UI for pausing, playing and seeking through content, or zapping between different content, so the application must provide one. There is an implementation of a control bar provided in the example code that provides guidance.

Note that the OTVVideoView class requires all operations to be executed from the Android app's UI thread. This is particularly important when we want the application to act programatically to events, which may be triggered in background threads.

Pause and play

The play and pause button - here named mPlayButton - is provided with an OnClickListener object that will pause or resume the content as appropriate. It will then update the button to display a play or pause icon.

JAVA
private final OnClickListener mPlayListener = new OnClickListener() {
  @Override
  public void onClick(View view) {
    showController(VIEW_TIMEOUT_DELAY);
    if(mPlayerView.isPlaying()){
      mPlayerView.pause();
    } else {
      mPlayerView.start();
    }
    updateButtonImage();
  }
};

public void updateButtonImage() {
  // ...
  if (mPlayerView.isPlaying()) {
    mPlayButton.setImageResource(R.drawable.pause_light);
  } else {
    mPlayButton.setImageResource(R.drawable.play_light);
  }
  // ...
}

Find the play/pause button in the layout, and attach OnClickListener:

JAVA
mPlayButton = mControllerView.findViewById(R.id.play_btn);

mPlayButton.setOnClickListener(mPlayListener);

Seeking

The example code demonstrates two methods of seeking: Using a seekbar (sometimes referred to as a scrubber) to seek to arbitrary points in the content, and fast-forward and rewind buttons to seek in ten-second increments.

Using a seek bar

Android provides the SeekBar class that is instantiated in the layout - here it is called mProgress - and the example code provides the implementation of the OnSeekBarChangeListener that defines what happens when the user interacts with the SeekBar.

  • onProgressChanged() will track the location of the cursor on the SeekBar to determine where in the stream to seek. If the seek is performed using the fast-forward or rewind button, it will also perform the seek

  • onStartTrackingTouch() will ensure the controller remains on screen while the seeking is being performed

  • onStopTrackingTouch() will perform a seek when the cursor is released (or no longer being moved)

  • handleVodProgress() will update the UI to show the current position and length of a VOD stream

  • handleLiveProgress() will update the to UI to show how far the stream is behind the live broadcast

JAVA
private OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
  @Override
  public void onStartTrackingTouch(SeekBar bar) {
    showController(VIEW_TIMEOUT_DELAY);
    setSeeking(true);
  }

  @Override
  public void onStopTrackingTouch(SeekBar bar) {
    if (mSeekingTouch) {
      mPlayerView.seekTo(mSeekedTime);
    }
    setSeeking(false);
    mPlayerView.resume();
  }

  @Override
  public void onProgressChanged(SeekBar bar, int progress, boolean fromuser) {
    mSeekedTime = progress;
    if(mSeekingButton){
      //seek on button press
      mPlayerView.seekTo(mSeekedTime);
    }
    if (mProgress != null) {
      //get duration returns -1 for live streams, can be used to tell between vod/live
      if (mPlayerView.getDuration() > 0) {
        // VOD Content
        handleVodProgress();
      } else {
        // Live Content
        handleLiveProgress();
      }
    }
    // ...
  }
};

// ...

private void setSeeking(boolean seeking) {
  if (mSeekingTouch && !seeking) {
    mPlayerView.seekTo(mSeekedTime);
    mPlayerView.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
      @Override
      public void onSeekComplete(MediaPlayer mediaPlayer) {
        startProgressUpdater();
      }
    });
  }
  mSeekingTouch = seeking;
}

The OnSeekBarChangeListener must be attached to the SeekBar in the layout:

CODE
private SeekBar mProgress;

// ...

mProgress = mControllerView.findViewById(R.id.mediacontroller_progress);
mProgress.setOnSeekBarChangeListener(mSeekListener);

Fast-forward and rewind buttons

The fast-forward and rewind buttons will get the current position in the stream, calculate a point ten seconds ahead or behind, and then update the SeekBar with the calculated position. This will then trigger the SeekBar’s onProgressChanged() method that will perform the actual seek operation.

The fast-forward implementation is shown below. The rewind operation has been omitted for brevity.

JAVA
private final OnClickListener mFastForwardListener = new OnClickListener() {
  @Override
  public void onClick(View view) {
    showController(VIEW_TIMEOUT_DELAY);
    int skipTime = 10000;
    int currentTime = mPlayerView.getCurrentPosition();
    int seekPos = currentTime + skipTime;
    mSeekingButton = true;
    //if live make sure that seek pos is less than seekable range. if you would seek past end, does not seek
    if((mPlayerView.getSeekableRangeInfo() != null && mPlayerView.getSeekableRangeInfo()[1] > seekPos) || seekPos < mPlayerView.getDuration()){
      mProgress.setProgress(seekPos);
    } else {
      mProgress.setProgress(mPlayerView.getDuration());
    }
    mSeekingButton = false;
  }
};

Zapping

The example code provides a simplified implementation using buttons with hard-coded stream URIs.

Zapping to different content is done by calling OTVVideoView’s setVideoPath() method which handles the player lifecycle and plays the selected content:

JAVA
private final View.OnClickListener mClickListener = (view -> {
  if(mCurrentStream != ((Button) view).getText().toString()){
    //...
    switch (mCurrentStream){
      case "Clear Stream":
        mOTVVideoView.setVideoPath(STREAM_URI_CLEAR);
        break;
      case "Live Stream":
        mOTVVideoView.setVideoPath(STREAM_URI_LIVE);
        break;
      case "Multi Audio":
        mOTVVideoView.setVideoPath(STREAM_URI_AUDIO);
        break;
      case "Subtitles":
        mOTVVideoView.setVideoPath(STREAM_URI_SUBTITLE);
        break;
      default:
        return;
    }
  }
});

Stopping playback

This is not demonstrated in the control bar example

To stop the currently-playing content - usually to return to the previous screen, for instance a main menu - the SDK provides the stopPlayback method.

CODE
mOTVVideoView.stopPlayback();
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.