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 import org.jspecify.annotations.NonNull; 30 31 /** 32 * Fragment demonstrating the use of {@link androidx.leanback.app.VideoSupportFragment} to 33 * render video with playback controls. And demonstrates video seeking with thumbnails. 34 * 35 * Generate 1 frame per second thumbnail bitmaps and put on sdcard: 36 * <pre> 37 * sudo apt-get install libav-tools 38 * avconv -i input.mp4 -s 240x135 -vsync 1 -r 1 -an -y -qscale 8 frame_%04d.jpg 39 * adb shell mkdir /sdcard/seek 40 * adb push frame_*.jpg /sdcard/seek/ 41 * </pre> 42 * Change to 1 frame per minute: use "-r 1/60". 43 * For more options, see https://wiki.libav.org/Snippets/avconv 44 * 45 * <p> 46 * Showcase: 47 * </p> 48 * <li>Auto play when ready</li> 49 * <li>Set seek provider</li> 50 * <li>switch MediaSource</li> 51 * <li>switch PlaybackGlue</li> 52 */ 53 public class SampleVideoSupportFragment extends androidx.leanback.app.VideoSupportFragment { 54 55 // Media Session Token 56 private static final String MEDIA_SESSION_COMPAT_TOKEN = "media session support video"; 57 58 private PlaybackTransportControlGlueSample<MediaPlayerAdapter> mMediaPlayerGlue; 59 60 private MediaSessionCompat mMediaSessionCompat; 61 62 final VideoSupportFragmentGlueHost mHost = new VideoSupportFragmentGlueHost(SampleVideoSupportFragment.this); 63 playWhenReady(PlaybackGlue glue)64 static void playWhenReady(PlaybackGlue glue) { 65 if (glue.isPrepared()) { 66 glue.play(); 67 } else { 68 glue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 69 @Override 70 public void onPreparedStateChanged(@NonNull PlaybackGlue glue) { 71 if (glue.isPrepared()) { 72 glue.removePlayerCallback(this); 73 glue.play(); 74 } 75 } 76 }); 77 } 78 } 79 loadSeekData(final PlaybackTransportControlGlue glue)80 static void loadSeekData(final PlaybackTransportControlGlue glue) { 81 if (glue.isPrepared()) { 82 glue.setSeekProvider(new PlaybackSeekDiskDataProvider( 83 glue.getDuration(), 84 1000, 85 "/sdcard/seek/frame_%04d.jpg")); 86 } else { 87 glue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 88 @Override 89 public void onPreparedStateChanged(@NonNull PlaybackGlue glue) { 90 if (glue.isPrepared()) { 91 glue.removePlayerCallback(this); 92 PlaybackTransportControlGlue transportControlGlue = 93 (PlaybackTransportControlGlue) glue; 94 transportControlGlue.setSeekProvider(new PlaybackSeekDiskDataProvider( 95 transportControlGlue.getDuration(), 96 1000, 97 "/sdcard/seek/frame_%04d.jpg")); 98 } 99 } 100 }); 101 } 102 } 103 104 @Override onCreate(Bundle savedInstanceState)105 public void onCreate(Bundle savedInstanceState) { 106 super.onCreate(savedInstanceState); 107 mMediaPlayerGlue = new PlaybackTransportControlGlueSample(getActivity(), 108 new MediaPlayerAdapter(getActivity())); 109 110 // create a media session inside of a fragment, and app developer can determine if connect 111 // this media session to glue or not 112 // as requested in b/64935838 113 mMediaSessionCompat = new MediaSessionCompat(getActivity(), MEDIA_SESSION_COMPAT_TOKEN); 114 mMediaPlayerGlue.connectToMediaSession(mMediaSessionCompat); 115 116 mMediaPlayerGlue.setHost(mHost); 117 mMediaPlayerGlue.setMode(PlaybackControlsRow.RepeatAction.INDEX_NONE); 118 mMediaPlayerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { 119 boolean mSecondCompleted = false; 120 @Override 121 public void onPlayCompleted(@NonNull PlaybackGlue glue) { 122 if (!mSecondCompleted) { 123 mSecondCompleted = true; 124 mMediaPlayerGlue.setSubtitle("Leanback artist Changed!"); 125 mMediaPlayerGlue.setTitle("Leanback team at work"); 126 String uriPath = "https://storage.googleapis.com/android-tv/Sample videos/" 127 + "April Fool's 2013/Explore Treasure Mode with Google Maps.mp4"; 128 mMediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); 129 loadSeekData(mMediaPlayerGlue); 130 playWhenReady(mMediaPlayerGlue); 131 } else { 132 mMediaPlayerGlue.removePlayerCallback(this); 133 switchAnotherGlue(); 134 } 135 } 136 }); 137 mMediaPlayerGlue.setSubtitle("Leanback artist"); 138 mMediaPlayerGlue.setTitle("Leanback team at work"); 139 String uriPath = "https://storage.googleapis.com/android-tv/Sample videos/" 140 + "April Fool's 2013/Explore Treasure Mode with Google Maps.mp4"; 141 mMediaPlayerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); 142 loadSeekData(mMediaPlayerGlue); 143 playWhenReady(mMediaPlayerGlue); 144 } 145 146 @Override onPause()147 public void onPause() { 148 if (mMediaPlayerGlue != null) { 149 mMediaPlayerGlue.pause(); 150 } 151 super.onPause(); 152 } 153 154 @Override onDestroy()155 public void onDestroy() { 156 super.onDestroy(); 157 mMediaPlayerGlue.disconnectToMediaSession(); 158 } 159 switchAnotherGlue()160 void switchAnotherGlue() { 161 mMediaPlayerGlue = new PlaybackTransportControlGlueSample(getActivity(), 162 new MediaPlayerAdapter(getActivity())); 163 164 // If the glue is switched, re-register the media session 165 mMediaPlayerGlue.connectToMediaSession(mMediaSessionCompat); 166 167 mMediaPlayerGlue.setMode(PlaybackControlsRow.RepeatAction.INDEX_ONE); 168 mMediaPlayerGlue.setSubtitle("A Googler"); 169 mMediaPlayerGlue.setTitle("Swimming with the fishes"); 170 mMediaPlayerGlue.getPlayerAdapter().setDataSource( 171 Uri.parse("http://techslides.com/demos/sample-videos/small.mp4")); 172 mMediaPlayerGlue.setHost(mHost); 173 loadSeekData(mMediaPlayerGlue); 174 playWhenReady(mMediaPlayerGlue); 175 } 176 } 177