YouTubePlayerSupportFragment is stopped with black screen in Picture-in-Picture
Asked Answered
C

0

7

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?

  1. YouTube Video should continue to play without stopping/pausing on entering PIP mode
  2. newInstance() loses the buffers + causes delay on reload, need continuous play
  3. API must allow to choose playbackQuality ("small", "large", etc).. so IFRAME API is not an option
  4. Should not break YouTube's TOS, so other external Video Players supporting DASH urls, etc. don't look like an option either
  5. 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:

  1. Tried bounded and unbounded service without using PIP, still continuous playback is an issue.
  2. Francesco's android youtube player API (videos plays seamlessly, but cannot change playback quality due to YouTube's API limitation)
  3. with YoutTubePlayerSupportFragment manually called play() on onPictureInPictureModeChanged(), onPause() and onStopped() events of Activity and Player (video will not play, remains at black screen)
  4. removed views/layouts and tried YouTubePlayer.setFullscreen(true) on PIP
  5. Tried with just one empty FrameLayout on the layout to check if overlays are causing issue, NO
  6. 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.

Cotyledon answered 25/7, 2019 at 9:40 Comment(2)
Do you see any logs related to youtube player? An error or perhaps a warning.Micahmicawber
@Cotyledon if you have solved this issue, please share a solution ! If you have solved this issue and can help me please email me @ [email protected] Thank youScutt

© 2022 - 2024 — McMap. All rights reserved.