Chromecast

To enable Chromecast, you need to follow the steps listed below.

Add dependency

Add the dependency in your app level build.gradle and replace "x.x.x" with the latest version as noted below:

dependencies {
    implementation 'com.flowplayer.android.player:flowplayer-chromecast:x.x.x'
}

Specify OptionsProvider

Add the following <meta-data> in your AndroidManifest.xml:

<meta-data
    android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
    android:value="com.flowplayer.android.chromecast.ChromecastOptionsProvider" />

(Optional) Specify custom receiver

The ChromecastOptionsProvider by default uses Flowplayer's Chromecast receiver application. If you wish to use your own receiver, then simply add it to your strings resource file with the following name:

<string name="flowplayer_chromecast_app_id">ID_OF_YOUR_CHROMECAST_RECEIVER</string>

Additionally, you can specify an array of namespaces by declaring an array with the following name in your strings resource file:

<string-array name="flowplayer_chromecast_namespaces">
    <item>YOUR_NAMESPACE</item>
</string-array>

Initialize ChromecastManager

Before you can start using Chromecast, you need to initialize the ChromecastManager. A good place to do this is inside your Application class.

override fun onCreate() {
    super.onCreate()
    ChromecastManager.initialize(this)
}

Add a Chromecast button

To allow users to select a Chromecast device and play their media on it, you need to add a Chromecast button to your application. You can add this either to your ActionBar or anywhere inside your view's layout.

Add a Chromecast button to the ActionBar

First, add the following menu item to your Activity's menu layout:

<item
    android:id="@+id/media_route_menu_item"
    android:title="Cast"
    app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
    app:showAsAction="always" />

Then use ChromecastManager to bind the button with Chromecast. Add the following line inside onCreateOptionsMenu:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_activity_player, menu)

    // Bind the button with Chromecast.
    ChromecastManager.getInstance().setMediaRouteButton(this, menu, R.id.media_route_menu_item)

    ... 

    return true
}

Add a Chromecast button to the layout

Fist, add the button to the layout:

<androidx.mediarouter.app.MediaRouteButton
    android:id="@+id/media_route_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:mediaRouteTypes="user"
    android:visibility="gone" />

Then use ChromecastManager to bind the button with Chromecast. Add the following line inside onCreate:

val mediaRouteButton = findViewById<MediaRouteButton>(R.id.media_route_button)

// Bind the button with Chromecast.
CastManager.getInstance().setMediaRouteButton(this, mediaRouteButton)

Connect ChromecastPlayer with FlowplayerView

Finally, you need to connect ChromecastPlayer with FlowplayerView in order for the media to be played on the appropriate player (Chromecast or local) depending on whether there is a Chromecast session established.

// Get Chromecast player instance
val chromecastMediaPlayer = ChromecastPlayer.getInstance(this)

// Pass the chromecast player to the flowplayerView
flowplayerView.setChromecastMediaPlayer(chromecastMediaPlayer)

Control ChromecastPlayer's playback

If you don't wish to manually control ChromecastPlayer's playback, you can simply add a PlayerControlView to your layout and pass it to the ChromecastPlayer.

First add the control view:

<com.google.android.exoplayer2.ui.PlayerControlView
    android:id="@+id/cast_control_view"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:visibility="gone"
    app:repeat_toggle_modes="all|one"
    app:show_timeout="-1" />

Then pass it to the player:

val chromecastControlView = findViewById<PlayerControlView>(R.id.cast_control_view)
chromecastMediaPlayer.setControlView(chromecastControlView)

For more information on how to customize the PlayerControlView read the API reference.

Control playback using Mini and Expanded Controllers

Mini and Expanded Controllers are parts of the Cast UX Widgets that enable you to control ChromecastPlayer playback and multiple subtitle, audio, and video tracks that a media may contains.

For a basic usage of these two widgets, follow the next steps:

  1. Subclass abstract class ExpandedControllerActivity and declare your activity in your app's manifest.

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.menu_activity_player, menu)
        CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
        return true
    }
    <application>
    ...
    <activity
        android:name=".expandedcontrols.ExpandedControlsActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:theme="@style/Theme.CastVideosDark"
        android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
      </intent-filter>
      <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
    </activity>
    </application>
  2. Extend ChromecastOptionsProvider class and override getCastMediaOptions function, in order to add your activity as the expanded controller of your sender app, and replace ChromecastOptionsProvider with your class in the <meta -data> of your AndroidManifest.xml.

    override fun getCastMediaOptions(): CastMediaOptions? {
        val notificationOptions = NotificationOptions.Builder()
                .setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
                .build()
    
        return CastMediaOptions.Builder()
                .setNotificationOptions(notificationOptions)
                .setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
                .build()
    }
    <meta-data
        android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
        android:value="com.package.MyChromecastOptionsProvider" />
  3. Add a mini controller to your sender app, simply by adding MiniControllerFragment to your layout.

    <fragment
       android:id="@+id/castMiniController"
       android:layout_alignParentBottom="true"
       class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:visibility="gone" />

    For more information on how to customize Cast UX Widgets UI read API reference.

Results