dependencies { compile 'com.google.android.libraries.cast.companionlibrary:ccl:2.8.4' }
// Core.java public class Core extends Application { @Override public void onCreate() { super.onCreate(); CastConfiguration options = new CastConfiguration.Builder("CC1AD845") .enableAutoReconnect() // .enableDebug() // , .enableLockScreen() // .enableNotification() // + .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_REWIND, false) .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_PLAY_PAUSE, true) .addNotificationAction(CastConfiguration.NOTIFICATION_ACTION_DISCONNECT, true) .enableWifiReconnection() // , wifi .setForwardStep(10) // .build(); VideoCastManager.initialize(this, options); } }
<receiver android:name="com.google.android.libraries.cast.companionlibrary.remotecontrol.VideoIntentReceiver" > <intent-filter> <action android:name="android.media.AUDIO_BECOMING_NOISY" /> <action android:name="android.intent.action.MEDIA_BUTTON" /> <action android:name="com.google.android.libraries.cast.companionlibrary.action.toggleplayback" /> <action android:name="com.google.android.libraries.cast.companionlibrary.action.stop" /> </intent-filter> </receiver> <service android:name="com.google.android.libraries.cast.companionlibrary.notification.VideoCastNotificationService" android:exported="false" > <intent-filter> <action android:name="com.google.android.libraries.cast.companionlibrary.action.toggleplayback" /> <action android:name="com.google.android.libraries.cast.companionlibrary.action.stop" /> <action android:name="com.google.android.libraries.cast.companionlibrary.action.notificationvisibility" /> </intent-filter> </service> <service android:name="com.google.android.libraries.cast.companionlibrary.cast.reconnection.ReconnectionService"/> <activity android:name="com.google.android.libraries.cast.companionlibrary.cast.player.VideoCastControllerActivity"/>
// SingleVideoCastConsumer.java public abstract class SingleVideoCastConsumer extends VideoCastConsumerImpl { private AppCompatActivity activity; private final String videoUrl; private final String title; private final String subtitle; private final String imageUrl; private final String contentType; public SingleVideoCastConsumer(AppCompatActivity activity, String videoUrl, String title, String subtitle, String imageUrl, String contentType) { this.activity = activity; this.videoUrl = videoUrl; this.title = title; this.subtitle = subtitle; this.imageUrl = imageUrl; this.contentType = contentType; } public abstract void onPlaybackFinished(); public abstract void onQueueLoad(final MediaQueueItem[] items, final int startIndex, final int repeatMode, final JSONObject customData) throws TransientNetworkDisconnectionException, NoConnectionException; @Override public void onMediaQueueUpdated(List<MediaQueueItem>queueItems, MediaQueueItem item, int repeatMode, boolean shuffle) { // , if(queueItems != null && queueItems.size() == 0) { onPlaybackFinished(); } } @Override public void onApplicationConnected(ApplicationMetadata appMetadata, String sessionId, boolean wasLaunched) { // Cast activity.invalidateOptionsMenu(); // MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE); // movieMetadata.putString(MediaMetadata.KEY_TITLE, title); // movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, subtitle); // , movieMetadata.addImage(new WebImage(Uri.parse(imageUrl))); // MediaInfo info = new MediaInfo.Builder(videoUrl) .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) .setContentType(contentType) .setMetadata(movieMetadata) .build(); // MediaQueueItem item = new MediaQueueItem.Builder(info).build(); try { // Chromecast, 1 , .. 1 onQueueLoad(new MediaQueueItem[]{item}, 0, MediaStatus.REPEAT_MODE_REPEAT_OFF, null); } catch (TransientNetworkDisconnectionException e) { e.printStackTrace(); } catch (NoConnectionException e) { e.printStackTrace(); } } @Override public void onDisconnected() { // Cast activity.invalidateOptionsMenu(); } }
ublic class MainActivity extends AppCompatActivity { private VideoCastManager castManager; private VideoCastConsumer castConsumer; private Toolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); castManager = VideoCastManager.getInstance(); castConsumer = new SingleVideoCastConsumer(this, http://example.com/somemkvfile.mkv", // "Jet Packs Was Yes", "Periphery", // "http://fugostudios.com/wp-content/uploads/2012/02/periphery720p-600x338.jpg", // "video/mkv" // ) { @Override public void onPlaybackFinished() { // disconnectDevice(); } @Override public void onQueueLoad(MediaQueueItem[] items, int startIndex, int repeatMode, JSONObject customData) throws TransientNetworkDisconnectionException, NoConnectionException { // SingleVideoCastConsumer castManager castManager.queueLoad(items, startIndex, repeatMode, customData); } }; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); // Cast toolbar castManager.addMediaRouterButton(menu, R.id.media_route_menu_item); return true; } @Override public boolean dispatchKeyEvent(@NonNull KeyEvent event) { // // return castManager.onDispatchVolumeKeyEvent(event, 0.05) || super.dispatchKeyEvent(event); } @Override protected void onResume() { // castConsumer if (castManager != null) { castManager.addVideoCastConsumer(castConsumer); castManager.incrementUiCounter(); } super.onResume(); } @Override protected void onPause() { // castConsumer castManager.decrementUiCounter(); castManager.removeVideoCastConsumer(castConsumer); super.onPause(); } // // , 100-500 , // . private void disconnectDevice() { new Handler().postDelayed(new Runnable() { @Override public void run() { castManager.disconnect(); } },500); } }
options.setMediaRouteDialogFactory(new MediaRouteDialogFactory() { @NonNull @Override public MediaRouteChooserDialogFragment onCreateChooserDialogFragment() { return new MediaRouteChooserDialogFragment() { @Override public MediaRouteChooserDialog onCreateChooserDialog(Context context, Bundle savedInstanceState) { return new MediaRouteChooserDialog(context, R.style.Theme_MediaRouter_Light); } }; } @NonNull @Override public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { return new MediaRouteControllerDialogFragment(){ @Override public MediaRouteControllerDialog onCreateControllerDialog(Context context, Bundle savedInstanceState) { return new MediaRouteControllerDialog(context, R.style.Theme_MediaRouter_Light); } }; } })
<style name="Theme.MediaRouter.Light" parent="Base.Theme.AppCompat.Light.Dialog.Alert"> <item name="android:windowNoTitle">false</item> <item name="mediaRouteButtonStyle">@style/Widget.MediaRouter.Light.MediaRouteButton</item> <item name="MediaRouteControllerWindowBackground">@drawable/mr_dialog_material_background_light</item> <item name="mediaRouteOffDrawable">@drawable/ic_cast_off_light</item> <item name="mediaRouteConnectingDrawable">@drawable/mr_ic_media_route_connecting_mono_light</item> <item name="mediaRouteOnDrawable">@drawable/ic_cast_on_light</item> <item name="mediaRouteCloseDrawable">@drawable/mr_ic_close_light</item> <item name="mediaRoutePlayDrawable">@drawable/mr_ic_play_light</item> <item name="mediaRoutePauseDrawable">@drawable/mr_ic_pause_light</item> <item name="mediaRouteCastDrawable">@drawable/mr_ic_cast_light</item> <item name="mediaRouteAudioTrackDrawable">@drawable/mr_ic_audiotrack_light</item> <item name="mediaRouteDefaultIconDrawable">@drawable/ic_cast_grey</item> <item name="mediaRouteBluetoothIconDrawable">@drawable/ic_bluetooth_grey</item> <item name="mediaRouteTvIconDrawable">@drawable/ic_tv_light</item> <item name="mediaRouteSpeakerIconDrawable">@drawable/ic_speaker_light</item> <item name="mediaRouteSpeakerGroupIconDrawable">@drawable/ic_speaker_group_light</item> <item name="mediaRouteChooserPrimaryTextStyle">@style/Widget.MediaRouter.ChooserText.Primary.Light</item> <item name="mediaRouteChooserSecondaryTextStyle">@style/Widget.MediaRouter.ChooserText.Secondary.Light</item> <item name="mediaRouteControllerTitleTextStyle">@style/Widget.MediaRouter.ControllerText.Title.Dark</item> <item name="mediaRouteControllerPrimaryTextStyle">@style/Widget.MediaRouter.ControllerText.Primary.Light</item> <item name="mediaRouteControllerSecondaryTextStyle">@style/Widget.MediaRouter.ControllerText.Secondary.Light</item> </style>
Source: https://habr.com/ru/post/310498/