Customizing the player

Subtitles

In case your media doesn't contain any subtitles and you wish to add your own, create an ArrayList<Subtitle> and then pass this list as an argument to the ExternalMedia that will be used to prepare FlowplayerView. The Subtitle constructor takes two parameters: label of subtitle and url of subtitle.

Copy
Copied
val subtitlesList = ArrayList<Subtitle>("English", "https://link.to.a.subtitle.file")
val externalMedia = ExternalMedia("https://url.to.a.media.file", subtitles = subtitlesList)

Subtitle files must be in one of the following formats: WebVTT, TTML/SMPTE-TT, SubRip or SubStationAlpha (SSA/ASS).

IMA Settings

You can create your own IMA SDK settings using ImaSettings.Builder class, and then pass them to the player.

Copy
Copied
val imaSettings = ImaSettings.Builder()
  .setLanguage("eng")
  .build()

flowplayerView.setImaSettings(imaSettings)

Set maximum bitrate

The Wowza Flowplayer Android SDK supports media formats, such as HLS, that contain video sources encoded at multiple bitrates. Setting a maximum bitrate limit forces the player to load and play only these encodings whose bitrate is below this limit.

The constructor ExternalMedia has an int parameter, maxVideoBitrate, to set a maximum bitrate to your media.

Copy
Copied
val externalMedia = ExternalMedia("https://link.t.o.a.media.file.m3u8", maxVideoBitrate = 500000)

Player controls

The Wowza Flowplayer Android SDK comes with built-in controls to further simplify its integration into your project. The built-in controls are, by default, enabled and shown over the FlowplayerView. If, however, you wish to disable them to provide your own custom UI, you can do so by setting:

Copy
Copied
flowplayerView.setUseControls(false)

Fullscreen

By default, when the FlowplayerView enters fullscreen, it displays on top of all other content and hides all of the system UI, such as the system tray, the ActionBar, and the soft keys. See Custom fullscreen behavior for more information on how to customize fullscreen handling.

In addition, FlowplayerView will, by default, change the Activity's orientation to landscape every time it enters fullscreen and to portrait every time it exits from fullscreen. See Orientation changes for more information on how orientation changes affect the player's fullscreen state and vice versa.

While the player is in fullscreen, you can not listen to key events in your Activity. This happens because behind the scenes the player is moved into a fullscreen Dialog.

Dialogs on Android are shown in a separate window on top of the Activity's window, resulting in the Activity losing focus for key events. When the player exits fullscreen, the focus returns to your Activity's window. If you want to listen to key events while the player is in fullscreen, you'll need to set a key listener to the player:

Copy
Copied
flowplayerView.setOnKeyListener(listener)

Custom fullscreen behavior

If you need to define a custom fullscreen behavior, you can create a class that implements the FullscreenManager interface and add your logic inside enterFullscreen() and exitFullscreen(). Then, tell the player to use your custom manager like below, where MyCustomFullscreenManager is your custom implementation of FullscreenManager.

Copy
Copied
flowplayerView.setFullscreenManager(MyCustomFullscreenManager())

Now, every time the player is requested to enter or exit fullscreen, your manager's enterFullscreen() and exitFullscreen() will be triggered.

info

A FullscreenManager is meant to handle layout changes as well as hiding and showing the system UI. Do not try to change the Activity's orientation from a FullscreenManager as this may lead to unexpected results. See Orientation changes for more information on how it works and how to change the default behavior.

Orientation changes

As mentioned, FlowplayerView will, by default, change the Activity's orientation to landscape every time it enters fullscreen and to portrait every time it exits from fullscreen.

You can disable this feature by simply setting:

Copy
Copied
flowplayerView.setFullscreenControlOrientation(false)

If you have disabled the built-in player controls (and therefore you only toggle the FlowplayerView's fullscreen state programmatically), then you can also tell the player to request a specific orientation every time you change its fullscreen state.

This can be achieved with a call to FlowplayerView.setFullscreen(fullscreen: Boolean, requestedOrientation: Int) together with an orientation constant:

Copy
Copied
flowplayerView.setFullscreen(true, ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE)
info

The info above only works if you have disabled the built-in controls, since they only use FlowplayerView.setFullscreen(fullscreen: Boolean).

Finally, if you use FlowplayerFragment or FlowplayerSupportFragment, the player's fullscreen state will be, by default, tied to the Activity's orientation.

That is, when the activity rotates to landscape, the player will enter fullscreen mode. Similarly, when the Activity rotates to portrait, the player will exit from fullscreen. This can be disabled by setting:

Copy
Copied
flowplayerFragment.setForceFullscreenOnLandscape(false)

Player plugins

In addition to the pre-defined controls, you can also enable player plugins.

The following sample enables the pre-defined mute control, and adds the speed plugin along with option values and labels.

Copy
Copied
val config = PlayerControlConfigBuilder()
    .setMuteControl(true)
    .enablePlugins(["speed"])
    .setCustom(key: "speed.options", value: [0.5, 1, 2, 5])
    .setCustom(key: "speed.labels", value: ["Slow", "Normal", "Double", "Fast"])
    .build()
flowplayerViewController.setControlConfig(config)

The table below lists all the player plugins that are currently supported together with the version of Wowza Flowplayer Android SDK where they were added.

Player plugin ID string Version
Speed selection "speed" 1.2.0
Audio selection "asel" 1.2.0

Custom controls

To further customize the player, you can, instead of using the built-in controls, offer your own HTML webcontrol implementation. Instructions for creating webcontrols can be found in the iOS SDK documentation pages.

Accordingly, you can ease development by using a single webcontrol setup for both platforms.

When the HTML file is in place, you can configure your player to use that:

Copy
Copied
val config = PlayerControlConfig.Builder()
    .setControlUrl("https://cdn.example.com/my-sdk-controls/index.html")
    .build()
player.setControlConfig(config)