Code Snippets using the Native SDK for Android

Product(s)
Brightcove Player
Video Cloud
Role(s)
Device SDK Developer
Task(s)
Develop with the Native SDKs
Topic(s)
Code Samples
API(s)
Playback API
SDK
Android

In this topic, you will find a collection of code snippets which you may find useful as a reference while developing with the SDK. For more detailed solutions, see the Android player samples.

Table of contents

Advertising
Analytics
Captions
Concepts
Content security (DRM)
Live streams
Playback
Player controls
Playlists
Video content

Getting duration for live streams

To get the duration for a live stream, you can use the MAX_POSITION. This gives you the largest seekable position for a live stream (ie., the furthest you can drag the scrollbar). Your code should look similar to this:

		brightcoveVideoView.getEventEmitter().on(EventType.PROGRESS, new EventListener() {
  @Override
  public void processEvent(Event event) {
   int duration = (int) event.properties.get(Event.MAX_POSITION);
  }
});

Getting URL for thumbnail images

You may want to use the thumbnail or video still images from your Brightcove library. Use the following code to get the URL for your images:

Google analytics

If you use the Brightcove player and the catalog class, video analytics will be automatically collected and will appear in your Video Cloud Analytics module. For additional metrics, you can add Google Analytics to your app.

To integrate Google Analytics with your app, follow these steps:

  1. Add the Google Services plugin to your project.
  2. Get a Google configuration file and add it to your project.
  3. Extend the Application and provide a helper method that returns your applications tracker. It should look similar to the google-services AnalyticsApplication.
  4. In a separate class which extends the BrightcovePlayer, obtain the shared tracker instance:
            				// Obtain the shared Tracker instance
            				AnalyticsApplication application = (AnalyticsApplication) getApplication();
            				tracker = application.getDefaultTracker();
  5. Override appropriate methods to log screen changes and/or send custom events for tracking.

For detailed steps, see Google's document to Add Analytics to Your Android App.

Fullscreen mode

You can manage fullscreen mode using code.

Manually adding DRM content

As a Brightcove Player customer, you may want to use DRM protected content from your own server. You can manually load DRM content as follows:

        				import com.brightcove.player.display.WidevineMediaDrmCallback;

        				Video video = Video.createVideo("https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd");
        				video.getProperties().put(WidevineMediaDrmCallback.DEFAULT_URL, "https://proxy.uat.widevine.com/proxy?video_id=&provider=widevine_test");
        				brightcoveVideoView.add(video);
        				brightcoveVideoView.start();

Methods: synchronous or asynchronous?

Here are some of the asynchronous methods found in the Native Player SDK for Android:

  • The start(), seekTo() and stopPlayback() methods are asynchronous, because they emit an event for other components in the system to handle.
  • The clear() method is synchronous with respect to updating the list, but it's asynchronous with respect to unloading the current video.

Offline playback with DRM

For videos downloaded for offline playback, the download status can also be shown in the Notification Area. The notification title is set to the video title. The notification is removed if the download is paused or cancelled.

Download notification status
Download status Notification content text Notification icon
Downloading R.string.odrm_download_running - this is "Downloading…" by default

There will be a progress bar showing the percent complete.
The platform-default animated "downloading" icon - android.R.drawable.stat_sys_download
Retry R.string.odrm_download_waiting_retry - this is "Waiting retry..." by default  
Failed R.string.odrm_download_failed - this is "Failed!"" by default  
Completed R.string.odrm_download_complete - this is "Saved" by default The platform-default static "downloaded" icon - android.R.drawable.stat_sys_download_done

For a status of Retry or Failed, the notification subtext will be set to an appropriate resource based on the error type. Here is the full list:

  • R.string.odrm_error_none
  • R.string.odrm_error_cannot_resume
  • R.string.odrm_error_device_not_found
  • R.string.odrm_error_file_already_exists
  • R.string.odrm_error_file_error
  • R.string.odrm_error_http_data_error
  • R.string.odrm_error_insufficient_space
  • R.string.odrm_error_too_many_redirects
  • R.string.odrm_error_unhandled_http_code
  • R.string.odrm_error_unknown

Paging with the Playback API

When retrieving your Video Cloud content from the Playback API, you can implement paging for a playlist.

To page through a set of videos in a playlist, use the following request URL parameters:

  • limit - defines the number of videos to return from the Playback API
  • offset - sets the number of videos to skip in a playlist from the Playback API

The query parameters will be passed to the Catalog method as a Map object, as key-value pairs. This example returns 6 videos starting with the 10th video in the playlist:

		Map<String, String> queryParameters = new HashMap<>();
queryParameters.put("limit", "6");
queryParameters.put("offset", "9");

Catalog catalog = new Catalog(eventEmitter, "myAccount", "myPolicy");
catalog.findPlaylistByID("myPlaylistId", null, queryParameters, myListener);

Playing local videos

If you want to play MP4 videos that are stored locally, then you should save them in the application asset folder.

        				String PACKAGE_NAME = getApplicationContext().getPackageName();
        				Uri video = Uri.parse("android.asset://" + PACKAGE_NAME + "/" + R.video.getting_started);
        				brightcoveVideoView.add(Video.createVideo(video.toString()));
        				brightcoveVideoView.start();

Seek without ads

You can use the adsDisabled property for the VideoPlaybackController to disable ad playback while you are seeking through a video.

To use this feature, follow these steps:

  1. Get the VideoPlaybackController instance from the BrightcoveVideoView.

            				VideoPlaybackController playbackController = brightcoveVideoView.getPlaybackController();
  2. Disable ad playback.

            				playbackController.setAdsDisabled(true);
  3. Seek to the desired time position in the current video.
  4. Resume normal ad behavior.

            				playbackController.setAdsDisabled(false);

Your code should look something like this:

	final VideoPlaybackController playbackController = brightcoveVideoView.getPlaybackController();
	eventEmitter.on(EventType.VIDEO_DURATION_CHANGED, new EventListener() {
  @Override
  public void processEvent(final Event event) {
    playbackController.setAdsDisabled(true);
    brightcoveVideoView.seekTo(10000);
  }
	});

	eventEmitter.on(EventType.DID_SEEK_TO, new EventListener() {
  @Override
  public void processEvent(final Event event) {
    playbackController.setAdsDisabled(false);
  }
	});

Setting the buffer size

You may consider increasing the buffer length to eliminate buffering in the player if the delivery of the next segment is delayed from the CDN. But, you may not be able to do anything better manually that HLS already does.

HLS is designed to play right away and drop quality if it can't keep up. This way, it does not need to preload a buffer. If it can't keep up, it will load as much of the video as it can at the best quality to prevent interruption.

That being said, if you are using the ExoPlayer implementation, you can control the following:

For example, if you want to set the buffer length to 120 seconds, you could set minBufferMs to 120 * 1000.

Setting captions and themes

Currently, the BrightcoveCaptionPropertiesActivity is set in the Brightcove Player SDK’s manifest file, so developers don’t need to specify it in their applications:

		<?xml version="1.0" encoding="utf-8"?>
<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.brightcove.player"
  android:versionCode="1"
  android:versionName="1.0">

  <application>
    <!-- If we don't register this Activity in the Manifest, apps using the SDK will crash when they try to access it. -->
    <!-- During the app's build process, this manifest will be merged with the app-level one. -->
    <activity android:name="com.brightcove.player.captioning.BrightcoveCaptionPropertiesActivity"/>
  </application>
</manifest>

The BrightcoveCaptionPropertiesActivity will inherit the platform default theme, as long as you set themes for your app at the <activity> level in your app’s manifest.

If you set a single app theme at the <application> level, then the BrightcoveCaptionPropertiesActivity will inherit the properties of this application-level theme. For some themes, this can cause the activity to look oddly styled or even illegible.

In those cases, you should specify the BrightcoveCaptionPropertiesActivity in your own manifest and apply a theme there, like so:

		<activity
  android:name="com.brightcove.player.captioning.BrightcoveCaptionPropertiesActivity"
  android:theme="@style/MyCustomCaptionSettingsTheme"/>

Setting default captions

If your video uses multiple language captions, you can programmatically set a default language when playback starts. Your code should look similar to this:

  brightcoveVideoView.getEventEmitter().once(EventType.CAPTIONS_LANGUAGES, new EventListener() {
    @Override
    public void processEvent(Event event) {
      brightcoveVideoView.setClosedCaptioningEnabled(true);
      brightcoveVideoView.setSubtitleLocale("fr");
    }
});

Setting the peak bitrate

To help you implement a bitrate selector in your player, you can use the following code to set the peak bitrate:

  ((ExoPlayerVideoDisplayComponent) videoView.getVideoDisplay()).setPeakBitrate(bitRate);

Setting VR Goggles mode for 360° videos

When playing a 360° video, users can select the Video 360 button on the control bar to switch to VR Goggles mode. If you are using either the BrightcovePlayer or BrightcovePlayerFragment activity, then the screen orientation will change to landscape when VR Goggles mode is enabled.

If you are using a custom activity, then you will need to add the following:

			brightcoveVideoView.getEventEmitter().on(EventType.CHANGE_ORIENTATION, new EventListener() {
	@Override
	public void processEvent(Event event) {
    int orientation = event.getIntegerProperty(Event.REQUESTED_ORIENTATION);
    setRequestedOrientation(orientation);
	}
});

Showing/ hiding video still images

You can show the video still at any time by emitting a SET_VIDEO_STILL event with a VIDEO_STILL property set to the URI of the video still.

Hiding should happen automatically whenever a CUE_POINT, DID_PLAY, DID_SEEK_TO, WILL_INTERRUPT_CONTENT, ACTIVITY_STOPPED, or FRAGMENT_STOPPED event occurs.

In general, we try to promote doing things via events, rather than direct method calls.

Starting playback in the middle of a video

Sometimes, you may need to start playback from somewhere in the middle of the video. To do this, you can call BrightCoveVideoView.seekTo() before starting playback.

        				catalog.findVideoByID(getString(R.string.videoId), new VideoListener() {
	@Override
	public void onVideo(Video video) {
    Log.v(TAG, "onVideo: video = " + video);

    brightcoveVideoView.getEventEmitter().on(EventType.DID_SET_VIDEO, new EventListener() {
      @Override
      public void processEvent(Event event) {
      	brightcoveVideoView.seekTo(60000);
      	brightcoveVideoView.start();
      }
    });
    brightcoveVideoView.add(video);
    brightcoveVideoView.pause();
  }
});

Swapping videos

This example shows one approach for swapping videos in the player.

Using single videos

Since the clear() method is asynchronous when unloading the current video, you need to wait before adding a new video to the player. Here are two options.

Using a playlist

If you are working with a playlist, keep in mind that calling the clear() method removes all the elements of the playlist. So, you may get an IndexOutOfBounds exception when trying to jump to the first video in the playlist.

Instead, you can try something like this:

			brightcoveVideoView.pause();
			brightcoveVideoView.stopPlayback();
			brightcoveVideoView.setCurrentIndex(0);

Switching between videos in a playlist

If you are using a playlist, you can use the following code to switch between videos in the playlist:

		private void setupControls(List<Video> videos) {
  previousVideoButton = (Button) findViewById(R.id.previous_video_button);
  nextVideoButton = (Button) findViewById(R.id.next_video_button);

  if (videos != null) {
    previousVideoButton.setEnabled(false);
    previousVideoButton.setOnClickListener(new View.OnClickListener() {
    	public void onClick(View view) {
    		int index = brightcoveVideoView.getCurrentIndex();
    		int size = brightcoveVideoView.getList().size();
    		previousVideoButton.setEnabled(index > 1);
    		nextVideoButton.setEnabled((index + 1) < size);

    		if (index > 0) {
    			brightcoveVideoView.setCurrentIndex(index - 1);
    		}
    	}
  	});

  	nextVideoButton.setEnabled(videos.size() > 1);
  	nextVideoButton.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
      	int index = brightcoveVideoView.getCurrentIndex();
      	int size = brightcoveVideoView.getList().size();
      	previousVideoButton.setEnabled(index >= 0);
      	nextVideoButton.setEnabled((index + 2) < size);

      	if ((index + 1) < size) {
      		brightcoveVideoView.setCurrentIndex(index + 1);
      	}
      }
  	});
  }
}

Working with volume control

When using the BrightcoveExoPlayerVideoView, you can programmatically mute or unmute the player by doing the following:

        				float volume = 100;
  private void setMute(boolean mute) {
    volume = mute ? 0 : 100;
    Map<String, Object> properties = new HashMap<>();
    properties.put(Event.VOLUME, volume);
    brightcoveVideoView.getEventEmitter().emit(EventType.SET_VOLUME, properties);
  }

Brightcove recommends using the BrightcoveExoPlayerVideoView whenever possible. If you need to use the BrightcoveVideoView, which uses Android's MediaPlayer, you can programmatically mute or unmute the player with the following code:

              float volume = 100;
  private void setMute(boolean mute) {
    volume = mute ? 0 : 1;
    Map<String, Object> properties = new HashMap<>();
    properties.put(Event.LEFT_VOLUME, volume);
    properties.put(Event.RIGHT_VOLUME, volume);
    brightcoveVideoView.getEventEmitter().emit(EventType.SET_VOLUME, properties);
  }