Caster is a small Android library that provides a media player for Chromecast. It's fully compliant with Google Cast v3.
Add the following repository and dependency to build.gradle
file of your project (repository to the main gradle file, dependency to the app module):
repositories {
// ...
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.mradzinski:Caster:1.2.2'
}
Caster requires Google Play Services and I assume that the target device has it installed (if not this example won't work). If you need a Caster's working example you can check the project included with the library.
First, you need to initialize a Caster instance in every Activity you want to use it in:
public class MainActivity extends AppCompatActivity {
private Caster caster;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
caster = Caster.create(this);
}
}
If you want to add a Mini Controller widget:
caster.addMiniController() // Or
caster.addMiniController(R.layout.custom_mini_controller)
Alternatively you can place it in your layout XML, just like in the official Google Cast example (remember to change fill_parent to match_parent!). You can also have a custom mini controller (more on this later).
To support device discovery, add a menu item in an overriden onCreateOptionsMenu
method on your Activity:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
caster.addMediaRouteMenuItem(menu, true); // To display an Introductory Overlay
// Or
caster.addMediaRouteMenuItem(menu, false); // To avoid displaying an Introductory Overlay
getMenuInflater().inflate(R.menu.your_menu, menu);
return true;
}
Optionally, An Introduction Overlay (with text "Touch to cast media to your TV") will be shown
at the first device discovery if requested. If you want to change it or add another language override the string with
id caster_introduction_text
in an XML resource. More information about overridable attributes can be found here
You can also add a discovery button anywhere else by placing the official MediaRouteButton in an XML layout:
<android.support.v7.app.MediaRouteButton
android:id="@+id/media_route_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And then set in up in your Activity (optionally showing an Introduction Overlay):
MediaRouteButton mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
caster.setupMediaRouteButton(mediaRouteButton, true); // To display an Introductory Overlay
// Or
caster.setupMediaRouteButton(mediaRouteButton, false); // To avoid displaying an Introductory Overlay
Althugh not necessary (you can manually setup everything), you can add the above functionality (except MediaRouteButton
) simply by extending CasterActivity
. It will add a caster
field and set up the rest for you:
public class MainActivity extends CasterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (caster.isConnected()) {
caster.getPlayer().loadMediaAndPlay(...)
}
}
}
All media player actions are included in a CasterPlayer
object, which you can access by calling caster.getPlayer()
.
When you are connected to the device, you can play media the following way:
MediaData mediaData = new MediaData.Builder(VIMEO_URL)
.setStreamType(MediaData.STREAM_TYPE_BUFFERED)
.setContentType("application/x-mpegURL") // Or "videos/mp4"... or any supported content type
.setMediaType(MediaData.MEDIA_TYPE_MOVIE)
.setTitle("Two birds, many stones.")
.setDescription("Isaac searches for Rebekah to retrieve Arachnid's stolen XP.")
.setThumbnailUrl("...")
.setPlaybackRate(MediaData.PLAYBACK_RATE_NORMAL)
.setAutoPlay(true)
.build();
caster.getPlayer().loadMediaAndPlay(mediaData);
Alternativly you can use loadMediaAndPlay(MediaInfo, autoPlay, position, playbackRate)
similar to Google Cast example, though this is more limited and less flexible.
To react to Chromecast connect and disconnect events, you can simply register a listener:
caster.setOnConnectChangeListener(new Caster.OnConnectChangeListener() {
@Override
public void onConnected() {
Log.d("Caster", "Connected with Chromecast");
}
@Override
public void onDisconnected() {
Log.d("Caster" "Disconnected from Chromecast");
}
});
In case the library doesn't fit you, there's the possibility to change everything like in Google Cast v3.
You can set a receiver ID or even the whole CastOptions
in your Application
class:
Caster.configure(receiverId); // Or
Caster.configure(customCastOptions); // Rr
Caster.configure(launchOptions)
Get CastContext
by calling:
CastContext.getSharedInstance(context);
Get CastSession
(so RemoteMediaClient
) by register OnCastSessionUpdatedListener:
caster.setOnCastSessionUpdatedListener(new Caster.OnCastSessionUpdatedListener() {
@Override
public void onCastSessionUpdated(CastSession castSession) {
if (castSession != null) {
RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
//...
}
}
});
Caster allows for custom styling of the mini controller and the expanded controls activity. For styling the mini controller you must add your own mini controller XML layout and pass it to your Caster instance.
<fragment
android:id="@+id/caster_mini_controller"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:castProgressBarColor="@color/green"
app:castBackground="@color/dark_gray"
app:castButtonColor="@color/white"
app:castTitleTextAppearance="@style/MiniControllerTextAppearace"
app:castSubtitleTextAppearance="@style/MiniControllerTextAppearace"/>
<!-- More styling props are available at https://developers.google.com/cast/docs/android_sender_advanced#customize-theme-mini-controller -->
caster.addMiniController(R.layout.custom_mini_controller);
For styling the expanded controls activity, you must build an instance of the ExpandedControlsStyle
class and pass it to
your Caster instance before any connection is available.
ExpandedControlsStyle style = new ExpandedControlsStyle.Builder()
.setSeekbarLineColor(getResources().getColor(R.color.green))
.setSeekbarThumbColor(getResources().getColor(R.color.white))
.setStatusTextColor(getResources().getColor(R.color.green))
.build();
caster.setExpandedPlayerStyle(style);
A sample app for Caster is included withing this repository. Please feel free to check it out before filing any issues :)