I am trying to play YouTube videos Picture-in-Picture mode without stopping in PIP mode. But the video stops playing on entering PIP with black screen and it will not play even after manually calling the player.play() methods. Only way i see it working is to create a new Fragment instance and initialize() again. How do I get to play videos with below requirements?
- YouTube Video should continue to play without stopping/pausing on entering PIP mode
- newInstance() loses the buffers + causes delay on reload, need continuous play
- API must allow to choose playbackQuality ("small", "large", etc).. so IFRAME API is not an option
- Should not break YouTube's TOS, so other external Video Players supporting DASH urls, etc. don't look like an option either
- Preferable that the Activity should extend AppCompatActivity rather than YouTubeBaseActivity
NOTE: The video plays continuously when moving back from PIP to full mode without issues.
Tried the following:
- Tried bounded and unbounded service without using PIP, still continuous playback is an issue.
- Francesco's android youtube player API (videos plays seamlessly, but cannot change playback quality due to YouTube's API limitation)
- with YoutTubePlayerSupportFragment manually called play() on onPictureInPictureModeChanged(), onPause() and onStopped() events of Activity and Player (video will not play, remains at black screen)
- removed views/layouts and tried YouTubePlayer.setFullscreen(true) on PIP
- Tried with just one empty FrameLayout on the layout to check if overlays are causing issue, NO
- No errors of Overlays are reported on the Android Studio Debug log as well
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".VideoActivity"
android:layout_margin="0dp"
android:padding="0dp"
android:orientation="vertical"
android:background="#0F0"
android:id="@+id/mycontainer"
>
<FrameLayout
android:id="@+id/player_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0dp"
android:background="#00F"
android:minHeight="150dp"
android:minWidth="250dp">
</FrameLayout>
</LinearLayout>
The Activity Class
public class VideoActivity extends AppCompatActivity {
YouTubeFrameSupport YTFS;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
YTFS= new YouTubeFrameSupport().getNewInstance(VIDEO_ID);
getSupportFragmentManager().beginTransaction().replace(R.id.player_frame, YTFS).commit();
}
@Override
public void onBackPressed() {
PictureModeClickedHandler();
}
private void PictureModeClickedHandler()
{
PictureInPictureParams params = new PictureInPictureParams.Builder()
.setAspectRatio(
new Rational(450, 250))
.build();
enterPictureInPictureMode(params);
}
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
if(isInPictureInPictureMode) {
YTFS = YTFS.Regenerate();
getSupportFragmentManager().beginTransaction().replace(R.id.player_frame, YTFS).commit();
}
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
}
}
And the manifest setting
android:supportsPictureInPicture="true"
android:configChanges="screenLayout|orientation|smallestScreenSize|screenSize"
***Code Editor keeps complaining about the Code i pasted.. i will try to post this and update the code later
updated code:
public class YouTubeFrameSupport extends YouTubePlayerSupportFragment
{
private static YouTubePlayer activePlayer;
private static YouTubeFrameSupport playerYouTubeFrag;
private static String CurrentVideoId;
public static YouTubeFrameSupport getNewInstance(String videoId)
{
playerYouTubeFrag = new YouTubeFrameSupport();
CurrentVideoId = videoId;
playerYouTubeFrag.initialize(videoId, 0);
return playerYouTubeFrag;
}
public static YouTubeFrameSupport Regenerate()
{
playerYouTubeFrag = new YouTubeFrameSupport();
playerYouTubeFrag.initialize(CurrentVideoId, activePlayer.getCurrentTimeMillis());
return playerYouTubeFrag;
}
public void PauseVideo(){
activePlayer.pause();
}
public void PlayVideo(){
activePlayer.seekToMillis(activePlayer.getCurrentTimeMillis());
activePlayer.play();
}
public String getCurrentVideoId(){
return CurrentVideoId;
}
private void initialize(String videoId, int currentSeekMillis){
final int seekTo = currentSeekMillis;
this.initialize(DEVELOPER_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer, boolean b) {
activePlayer=youTubePlayer;
activePlayer.loadVideo(CurrentVideoId, seekTo);
activePlayer.addFullscreenControlFlag(
YouTubePlayer.FULLSCREEN_FLAG_CONTROL_ORIENTATION
| YouTubePlayer.FULLSCREEN_FLAG_CONTROL_SYSTEM_UI
| YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT
);
}
@Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
}
});
}
@Override
public void onDestroyView() {
activePlayer.release();
super.onDestroyView();
}
@Override
public void onDestroy() {
activePlayer.release();
super.onDestroy();
}
}
I expect video to play seamlessly on entering PIP, but instead it is blank. Moreover, we cannot control the player anymore by calling play(), stop(), pause() anymore. Perhaps, there are other ways of saving the current state and continuing onResume? passing additional params on PIP event?
Any solution that satisfies the above mentioned requirement will be accepted.