android 实现播放视频画中画功能遇到的问题点

画中画功能

Android 8.0 Oreo(API Level 26)允许活动启动画中画 Picture-in-picture(PIP)模式,我就是采用官方api模式实现,还有一种实现方案采用的是window方式,我项目里采用的是第三方播放器感觉用window方式实现困难了些不好衔接。

具体实现很简单就几点 就是参照的官方文档

1在你的manifest配置文件配置你的播放类acitvity

复制代码
 <activity android:name="VideoActivity"
  android:supportsPictureInPicture="true"
  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  android:launchMode="singleTask"

2在播放器控制栏添加的一个小窗播放按钮(参考爱奇艺) 点击按钮进入画中画模式

复制代码
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        PictureInPictureParams.Builder pictureInPictureParamsBuilder = new PictureInPictureParams.Builder();
        mVideoWith = Player.getVideoWidth();
        mVideoHeight = Player.getVideoHeight();
        if (mVideoWith != 0 && mVideoHeight != 0) {
            Rational aspectRatio = new Rational(mVideoWith, mVideoHeight);
            pictureInPictureParamsBuilder.setAspectRatio(aspectRatio);
        }
        //进入pip
        enterPictureInPictureMode(mPictureInPictureParamsBuilder.build());
    }

3监听进入退出画中画

复制代码
@Override
    public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) {
        if (isInPictureInPictureMode) {
            // 进入画中画 这里隐藏全屏播放的ui
        } else {
            // 退出画中画 这里显示ui
        }
    }

    @Override
    public void onUserLeaveHint() {
	/ /当点击home键会触发这个方法,这里也可以调用进入画中画 看需求,我这里没有些写任何代码
    }

官方文档写的大概也是这些

总结下完成功能后遇到的几个问题

1 切换画中画 小屏会白一小会 才显示继续播放的视频我用的小米手机测试的,查看官方文档有写到

Android 12 对全屏窗口和画中画窗口之间的动画过渡效果进行了重大改进

从 Android 12 开始,PictureInPictureParams.Builder.setAutoEnterEnabled(true) 标志可提供更流畅的动画,用于在画中画模式下使用手势导航过渡到视频内容(例如,从全屏向上滑动到主屏幕时)。如果您的应用属于 ENTERTAINMENT、COMMUNICATION 或 VIDEO_PLAYER 应用类别,我们建议您采用此方式。

我是基于Android11做的没有setAutoEnterEnabled这个方法,但文档中还提供另一个方法

在 Android 8.0 中引入画中画功能时,sourceRectHint 用于指明在转换为画中画之后可见的 activity 区域,例如视频播放器中的视频视图边界。从 Android 12 开始,操作系统使用 sourceRectHint 在进入和退出画中画模式时实现更流畅的动画。

如果您的应用未提供适当的 sourceRectHint,画中画过渡仍正常运行,但动画不够精美

所以设置sourceRectHint 这个方法解决了这个问题

复制代码
  Rect rect = new Rect();
  PlayerView.getGlobalVisibleRect(rect);
  pictureInPictureParamsBuilder.setSourceRectHint(rect);

2 切换画中画模式变成小屏后 页面会自动回到上一个页面,但是这个页面的布局会乱,页面控件变大了,一开始我以为是我引用的AndroidAutoSize 适配框架的原因 ,他们有冲突毕竟这个框架是全局适配的,后来发现不是 。

复制代码
  android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"

在切换画中画自动回到的上个页面activity也都配置上面属性,解决了这个问题

3 在画中画模式下操作别的功能 进入别的页面 有的页面直接在画中画小窗里打开了,这个是因为你打开的页面activity启动模式android:launchMode="singleTask" 把他去掉就好

4 在画中画模式下 在点击别的视频进入播放页面,由于我的播放页面是上面视频下tablyout+viewpager+fragment 根据不同需求 视频下面的fragment数量不一样 有的两个tab 有的三个,当三个进两个时java.lang.IllegalStateException:ViewPager: Can't Change Tag of Fragment出现这个异常,当两个进三个时下面fragment没有更新 ,我明明已经clear掉集合里的fragment了,原来是因为viewpager在加载当前页的时候已经将pager页左右页的内容加载进内存里了,并没有真正的删除,出现异常应该应该是一个位置有两个相同tag的fragment。

解决方案

将FragmentPagerAdapter 替换成FragmentStatePagerAdapter,因为前者只要加载过,fragment中的视图就一直在内存中,在这个过程中无论你怎么刷新,清除都是无用的,直至程序退出; 后者可实现真正删除。

重写Adapter的方法--getItemPosition(),让其返回PagerAdapter.POSITION_NONE

复制代码
@Override
	public int getItemPosition(Object object) {
		return PagerAdapter.POSITION_NONE;
	}

进入新的播放页面会触发onNewIntent

复制代码
 @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
		//获取视频url
		//重置viewpager fragment 等大概逻辑,如果视频是进入画中画模式之前的视频 这里可以不做任何处理
    }

5 点击画中画小屏的关闭按钮要关闭activity,这个点击关闭按钮会除非 播放类activity的 onStop方法 利用这个加个变量判断

复制代码
   @Override
    protected void onStop() {
        super.onStop();
        closePip = true;
    }

   @Override
    public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
        if(isInPictureInPictureMode){
          
            }else {
                if(closePip){
                    finish();
                }
            }
    }
相关推荐
ha_lydms19 小时前
AnalyticDB分区、分布键性能优化
android·大数据·分布式·性能优化·分布式计算·分区·analyticdb
星辰19 小时前
Ijkplayer重新编译支持h264裸流
android
测试开发-学习笔记20 小时前
Android studio安装
android·ide·android studio
宋拾壹20 小时前
同时添加多个类目
android·开发语言·javascript
●VON21 小时前
AtomGit Flutter鸿蒙客户端:数据模型
android·服务器·安全·flutter·harmonyos·鸿蒙
火柴就是我21 小时前
记录一个文本随手指缩放的功能
android
Zender Han1 天前
Android APK 签名 v1、v2、v3、v4 有什么区别?
android
神仙别闹1 天前
基于 PHP + MySQL学生信息管理系统
android·mysql·php
墨狂之逸才1 天前
Android 保活机制详解 —— 从概念到实践
android
故渊at1 天前
第二板块:Android 四大组件标准化学理 | 第十二篇:四大组件全景总结与系统服务(System Server)架构
android·架构·wpf·四大组件·system service