7

我正在尝试在不停止 PIP 模式的情况下播放 YouTube 视频画中画模式。但是视频在黑屏进入画中画时停止播放,即使手动调用 player.play() 方法也不会播放。我看到它工作的唯一方法是创建一个新的 Fragment 实例并再次初始化()。如何播放具有以下要求的视频?

  1. YouTube 视频应继续播放而不会在进入 PIP 模式时停止/暂停
  2. newInstance() 丢失缓冲区 + 导致重新加载延迟,需要连续播放
  3. API 必须允许选择播放质量(“小”、“大”等).. 所以 IFRAME API 不是一个选项
  4. 不应该破坏 YouTube 的 TOS,因此其他支持 DASH url 等的外部视频播放器看起来也不像是一个选项
  5. 最好 Activity 应该扩展 AppCompatActivity 而不是 YouTubeBaseActivity

注意:当从 PIP 回到完整模式时,视频会连续播放而不会出现问题。

尝试了以下方法:

  1. 在不使用 PIP 的情况下尝试了有界和无界服务,仍然连续播放是一个问题。
  2. Francesco 的 android youtube player API(视频可以无缝播放,但由于 YouTube 的 API 限制无法改变播放质量)
  3. 使用 YoutTubePlayerSupportFragment 在 Activity 和 Player 的 onPictureInPictureModeChanged()、onPause() 和 onStopped() 事件上手动调用 play()(视频不会播放,保持黑屏)
  4. 删除了视图/布局并在 PIP 上尝试了 YouTubePlayer.setFullscreen(true)
  5. 尝试在布局上仅使用一个空 FrameLayout 来检查覆盖是否导致问题,否
  6. Android Studio 调试日志中也没有报告 Overlays 的错误
<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>

活动课

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);
    }
}

以及清单设置 android:supportsPictureInPicture="true"
android:configChanges="screenLayout|orientation|smallestScreenSize|screenSize"

***代码编辑器一直抱怨我粘贴的代码..我会尝试发布这个并稍后更新代码

更新代码:

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();
    }
}

我希望视频在输入 PIP 时无缝播放,但它是空白的。此外,我们不能再通过调用 play()、stop()、pause() 来控制播放器。也许,还有其他方法可以保存当前状态并继续 onResume?在 PIP 事件中传递额外的参数?

任何满足上述要求的解决方案都将被接受。

4

0 回答 0