1 // CHECKSTYLE:OFF Generated code 2 /* This file is auto-generated from OnboardingDemoFragment.java. DO NOT MODIFY. */ 3 4 /* 5 * Copyright (C) 2016 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 8 * in compliance with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed under the License 13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 14 * or implied. See the License for the specific language governing permissions and limitations under 15 * the License. 16 */ 17 package com.example.android.leanback; 18 19 import android.net.Uri; 20 import android.os.Bundle; 21 import android.support.v4.media.session.MediaSessionCompat; 22 23 import androidx.leanback.app.VideoSupportFragmentGlueHost; 24 import androidx.leanback.media.MediaPlayerAdapter; 25 import androidx.leanback.media.PlaybackGlue; 26 import androidx.leanback.media.PlaybackTransportControlGlue; 27 import androidx.leanback.widget.PlaybackControlsRow; 28 29 /** 30 * Fragment demonstrating the use of {@link androidx.leanback.app.VideoSupportFragment} to 31 * render video with playback controls. And demonstrates video seeking with thumbnails. 32 * 33 * Generate 1 frame per second thumbnail bitmaps and put on sdcard: 34 * <pre> 35 * sudo apt-get install libav-tools 36 * avconv -i input.mp4 -s 240x135 -vsync 1 -r 1 -an -y -qscale 8 frame_%04d.jpg 37 * adb shell mkdir /sdcard/seek 38 * adb push frame_*.jpg /sdcard/seek/ 39 * </pre> 40 * Change to 1 frame per minute: use "-r 1/60". 41 * For more options, see https://wiki.libav.org/Snippets/avconv 42 * 43 * <p> 44 * Showcase: 45 * </p> 46 * <li>Auto play when ready</li> 47 * <li>Set seek provider</li> 48 * <li>switch MediaSource</li> 49 * <li>switch PlaybackGlue</li> 50 */ 51 public class SampleVideoSupportFragment extends androidx.leanback.app.VideoSupportFragment { 52 53 // Media Session Token 54 private static final String MEDIA_SESSION_COMPAT_TOKEN = "media session support video"; 55 56 private PlaybackTransportControlGlueSample<MediaPlayerAdapter> mMediaPlayerGlue; 57 58 private MediaSessionCompat mMediaSessionCompat; 59 60 final VideoSupportFragmentGlueHost mHost = new VideoSupportFragmentGlueHost(SampleVideoSupportFragment.this); 61 playWhenReady(PlaybackGlue glue)62 static void playWhenReady(PlaybackGlue glue) { 63 if (glue.isPrepared()) { 64 glue.play(); 65 } else { 66 glue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 67 @Override 68 public void onPreparedStateChanged(PlaybackGlue glue) { 69 if (glue.isPrepared()) { 70 glue.removePlayerCallback(this); 71 glue.play(); 72 } 73 } 74 }); 75 } 76 } 77 loadSeekData(final PlaybackTransportControlGlue glue)78 static void loadSeekData(final PlaybackTransportControlGlue glue) { 79 if (glue.isPrepared()) { 80 glue.setSeekProvider(new PlaybackSeekDiskDataProvider( 81 glue.getDuration(), 82 1000, 83 "/sdcard/seek/frame_%04d.jpg")); 84 } else { 85 glue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 86 @Override 87 public void onPreparedStateChanged(PlaybackGlue glue) { 88 if (glue.isPrepared()) { 89 glue.removePlayerCallback(this); 90 PlaybackTransportControlGlue transportControlGlue = 91 (PlaybackTransportControlGlue) glue; 92 transportControlGlue.setSeekProvider(new PlaybackSeekDiskDataProvider( 93 transportControlGlue.getDuration(), 94 1000, 95 "/sdcard/seek/frame_%04d.jpg")); 96 } 97 } 98 }); 99 } 100 } 101 102 @Override onCreate(Bundle savedInstanceState)103 public void onCreate(Bundle savedInstanceState) { 104 super.onCreate(savedInstanceState); 105 mMediaPlayerGlue = new PlaybackTransportControlGlueSample(getActivity(), 106 new MediaPlayerAdapter(getActivity())); 107 108 // create a media session inside of a fragment, and app developer can determine if connect 109 // this media session to glue or not 110 // as requested in b/64935838 111 mMediaSessionCompat = new MediaSessionCompat(getActivity(), MEDIA_SESSION_COMPAT_TOKEN); 112 mMediaPlayerGlue.connectToMediaSession(mMediaSessionCompat); 113 114 mMediaPlayerGlue.setHost(mHost); 115 mMediaPlayerGlue.setMode(PlaybackControlsRow.RepeatAction.INDEX_NONE); 116 mMediaPlayerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 117 boolean mSecondCompleted = false; 118 @Override 119 public void onPlayCompleted(PlaybackGlue glue) { 120 if (!mSecondCompleted) { 121 mSecondCompleted = true; 122 mMediaPlayerGlue.setSubtitle("Leanback artist Changed!"); 123 mMediaPlayerGlue.setTitle("Leanback team at work"); 124 String uriPath = "https://storage.googleapis.com/android-tv/Sample videos/" 125 + "April Fool's 2013/Explore Treasure Mode with Google Maps.mp4"; 126 mMediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); 127 loadSeekData(mMediaPlayerGlue); 128 playWhenReady(mMediaPlayerGlue); 129 } else { 130 mMediaPlayerGlue.removePlayerCallback(this); 131 switchAnotherGlue(); 132 } 133 } 134 }); 135 mMediaPlayerGlue.setSubtitle("Leanback artist"); 136 mMediaPlayerGlue.setTitle("Leanback team at work"); 137 String uriPath = "https://storage.googleapis.com/android-tv/Sample videos/" 138 + "April Fool's 2013/Explore Treasure Mode with Google Maps.mp4"; 139 mMediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); 140 loadSeekData(mMediaPlayerGlue); 141 playWhenReady(mMediaPlayerGlue); 142 } 143 144 @Override onPause()145 public void onPause() { 146 if (mMediaPlayerGlue != null) { 147 mMediaPlayerGlue.pause(); 148 } 149 super.onPause(); 150 } 151 152 @Override onDestroy()153 public void onDestroy() { 154 super.onDestroy(); 155 mMediaPlayerGlue.disconnectToMediaSession(); 156 } 157 switchAnotherGlue()158 void switchAnotherGlue() { 159 mMediaPlayerGlue = new PlaybackTransportControlGlueSample(getActivity(), 160 new MediaPlayerAdapter(getActivity())); 161 162 // If the glue is switched, re-register the media session 163 mMediaPlayerGlue.connectToMediaSession(mMediaSessionCompat); 164 165 mMediaPlayerGlue.setMode(PlaybackControlsRow.RepeatAction.INDEX_ONE); 166 mMediaPlayerGlue.setSubtitle("A Googler"); 167 mMediaPlayerGlue.setTitle("Swimming with the fishes"); 168 mMediaPlayerGlue.getPlayerAdapter().setDataSource( 169 Uri.parse("http://techslides.com/demos/sample-videos/small.mp4")); 170 mMediaPlayerGlue.setHost(mHost); 171 loadSeekData(mMediaPlayerGlue); 172 playWhenReady(mMediaPlayerGlue); 173 } 174 } 175