Slide 1

Slide 1 text

New Google Cast SDK wasabeef shibuya.apk #9

Slide 2

Slide 2 text

About me Daichi Furiya wasabeef @wasabeef_jp AbemaTV, Inc.

Slide 3

Slide 3 text

Chromecast http://www.google.co.jp/intl/ja_jp/chromecast

Slide 4

Slide 4 text

Sender

Slide 5

Slide 5 text

Sender

Slide 6

Slide 6 text

Sender

Slide 7

Slide 7 text

Receiver

Slide 8

Slide 8 text

Receiver

Slide 9

Slide 9 text

Receiver

Slide 10

Slide 10 text

Receiver

Slide 11

Slide 11 text

Receiver

Slide 12

Slide 12 text

Google Cast SDK v3

Slide 13

Slide 13 text

Session state management Connect, disconnect, and reconnect logic UX implementation and UI Google Cast SDK v3

Slide 14

Slide 14 text

Sender

Slide 15

Slide 15 text

Gradle dependencies { compile "com.android.support:appcompat-v7:23.4.0" compile "com.android.support:mediarouter-v7:23.4.0" compile "com.google.android.gms:play-services-cast-framework:9.2.1" }

Slide 16

Slide 16 text

Initialize the Cast Context class CastOptionsProvider implements OptionsProvider { @Override Public CastOptions getCastOptions(Context context) { CastOptions castOptions = new CastOptions.Builder() .setReceiverApplicationId("415D36F5") .build(); return castOptions; } }

Slide 17

Slide 17 text

Initialize the Cast Context

Slide 18

Slide 18 text

Initialize the Cast Context @Override public CastOptions getCastOptions(Context context) { NotificationOptions notificationOptions = new NotificationOptions.Builder() .setActions(Arrays.asList(MediaIntentReceiver.ACTION_SKIP_NEXT, MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK, MediaIntentReceiver.ACTION_STOP_CASTING), new int[]{1, 2}) .setTargetActivityClassName(ExpandedControlsActivity.class.getName()) .build(); CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions) .build(); return new CastOptions.Builder() .setReceiverApplicationId("415D36F5") .setCastMediaOptions(mediaOptions) .build(); }

Slide 19

Slide 19 text

Initialize the Cast Context @Override public CastOptions getCastOptions(Context context) { NotificationOptions notificationOptions = new NotificationOptions.Builder() .setTargetActivityClassName(MainActivity.class.getName()).build(); CastMediaOptions castMediaOptions = new CastMediaOptions.Builder() .setNotificationOptions(notificationOptions).build(); CastOptions castOptions = new CastOptions.Builder().setReceiverApplicationId("415D36F5") .setEnableReconnectionService(true) .setResumeSavedSession(true) .setCastMediaOptions(castMediaOptions) .setSupportedNamespaces(Collections.singletonList("urn:x-cast:jp.wasabeef")) .build(); return castOptions; }

Slide 20

Slide 20 text

Add a Cast Button

Slide 21

Slide 21 text

IntroductoryOverlay

Slide 22

Slide 22 text

IntroductoryOverlay new IntroductoryOverlay.Builder(this, button) .setTitleText("キャストを始めよう") .setOverlayColor(R.color.holo_blue_light) .setSingleTime() .build() .show();

Slide 23

Slide 23 text

Add a Cast Button @Override protected void onResume() { super.onResume(); CastButtonFactory.setUpMediaRouteButton(this, binding.mediaRouteButton); }

Slide 24

Slide 24 text

How session management works public class MainActivity extends Activity { private CastSession castSession; private SessionManager sessionManager; private SessionManagerListener listener = new SessionManagerListener(){ @Override public void onSessionStarted(Session session, String sessionId) { // Connected } @Override public void onSessionEnded(Session session, int error) { // Disconnected } } @Override protected void onCreate() { super.onCreate(); CastContext cc = CastContext.getSharedInstance(this); sessionManager = cc.getSessionManager(); sessionManager.addSessionManagerListener(listener); } }

Slide 25

Slide 25 text

How session management works public class MainActivity extends Activity { // … private CastSession castSession; private SessionManagerListener listener = new SessionManagerListener(){ @Override public void onSessionStarted(Session session, String sessionId) { // Connected } @Override public void onSessionEnded(Session session, int error) { // Disconnected } } }

Slide 26

Slide 26 text

How session management works public class MainActivity extends Activity { private CastSession castSession; private SessionManager sessionManager; private SessionManagerListener listener; // … @Override protected void onCreate() { super.onCreate(); CastContext cc = CastContext.getSharedInstance(this); sessionManager = cc.getSessionManager(); sessionManager.addSessionManagerListener(listener); } }

Slide 27

Slide 27 text

Load Media MediaMetadata meta = new MediaMetadata(MediaMetadata.MEDIA_TYPE_TV_SHOW); meta.putString(MediaMetadata.KEY_TITLE, “わさビーフの奇妙な冒険 #1”); meta.putString(MediaMetadata.KEY_SUBTITLE, "堅あげポテトは砕けない "); meta.addImage(new WebImage(Uri.parse(“https://wasabeef.jp/cover.webp")); MediaInfo mediaInfo = new MediaInfo.Builder(“https://wasabeef.jp/jojo-anim.m3u8") .setStreamType(streamType) .setContentType("application/x-mpegurl") .setMetadata(meta) .setCustomData(/** カスタムデータ:JSONObject **/) .build(); RemoteMediaClient client = castSession.getRemoteMediaClient(); client.load(mediaInfo, true, 0);

Slide 28

Slide 28 text

Recover from a temporary loss of WiFi Recover from device sleep Recover from backgrounding the app Recover if the app crashed Automatic Reconnection

Slide 29

Slide 29 text

googlecast/ CastVideos-android

Slide 30

Slide 30 text

Receiver

Slide 31

Slide 31 text

Google Cast SDK Developer Console

Slide 32

Slide 32 text

Custom Receiver Styled Media Receiver Remote Display Receiver Receiver

Slide 33

Slide 33 text

Custom Receiver https://developers.google.com/cast/docs/custom_receiver

Slide 34

Slide 34 text

googlecast/ CastReferencePlayer

Slide 35

Slide 35 text

Conclusion

Slide 36

Slide 36 text

Thank you. twitter.com/wasabeef_jp wasabeef.jp github.com/wasabeef