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