【android学习笔记】播放器中一些细节处理

工作中开发视频播放器的项目结束后,总结下之前开发过程中所遇到的一些坑。

1.播放网络视频,onError报错所遇到的what -38;

细节总结:

(1)正因为播放的是网络视频,所以mediaPlayer采用的是 prepareAsync();就会遇到上述问题

而且大部分同一个视频有时候会出错,有时候又不会出现这个错误,也有极少数视频一直出这个错

@Override
    public boolean onError(MediaPlayer mp, int what, int extra){
        switch (what) {
            case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                mp.release();
                return true;
            case -38:
                start();
                break;
            default:
                mp.reset();
                break;
        }
        return false;
    }

上网找了很多资料,都是没有具体的解决办法,因为这个问题偶尔出现,所以我想既然有时候不出错的话,那干脆获取这个错误后,再反复去执行播放的操作,结果发现问题可以得以解决。

我个人理解的意思是,异步操作的视频,在用prepareAsnc的时候,出现了获取视频元素失败或者其他错误,反复执行,经测试,一般大概3-5次就可以正常播放。

(2) 还是上个问题,使用prepare()就不会出现错误,但是在视频准备前期,UI层会出现巨卡现象,这显然更不符合要求,本来还想自己尝试去封装这个,用另一个线程执行,不过还是觉得官方的更靠谱点。所以才会花心思去研究和推论第一点的尝试。

2.MediaPlayer   error (1, -2147483648)

      偶尔播放视频,会发现报上述错误信息,尤其是杂牌子的低端手机,查阅资料1其实代表MEDIA_ERROR_UNKNOWN,不过文档对-2147483648(0x80000000)没有做什么说明,实际上它也是代表unknown error的意思。

      真正的原因在于,MP4有多种编码格式,例如H.264,H.263等,而Android版本较低的机器只支持部分编码。

可以参考官方的视频编码支持的说明:


后来把不能播放的视频下载到本地,用mediaInfo工具查看编码信息,发现不能播放的是AVC High@L4.1的编码方式,再用格式工厂采取其他方式编码,测试可以播放


3.视频缩放

如果只是简单的视频缩放就不值得拿出来,但是如果牵涉到视频的旋转,再缩放,就有点工作量,我之前的那个项目,有3套旋转和缩放的逻辑处理。这里只拿出最关键的处理代码

水平方向的视频缩放

private void horizontalResize(){
        float ra1,ra2;
        if (videoHeight > 0 && videoWidth > 0) {
            ra1 = (float) videoWidth / videoHeight;
            ra2 = (float) surfaceWidth / surfaceHeight;
            //宽屏
            if(ra1>ra2){
                realVideoWidth = surfaceWidth;
                realVideoHeight =(int) (realVideoWidth/ra1);
            }else{
                realVideoHeight = surfaceHeight;
                realVideoWidth  = (int)(realVideoHeight*ra1);
            }
        }
        mTextureView.setScaleX((float)realVideoWidth/surfaceWidth);
        mTextureView.setScaleY((float)realVideoHeight /surfaceHeight);
    }

竖直方向的视频缩放

private void verticalResize(){
        float ra1,ra2;
        if (videoHeight > 0 && videoWidth > 0) {
            ra1 = (float) videoHeight/videoWidth;
            ra2 = (float) surfaceWidth/surfaceHeight;
            //宽屏
            if(ra1>ra2){
                realVideoWidth = surfaceWidth;
                realVideoHeight =(int) (realVideoWidth/ra1);
            }else{
                realVideoHeight = surfaceHeight;
                realVideoWidth  = (int)(realVideoHeight*ra1);
            }
        }
        mTextureView.setScaleX((float)realVideoHeight/surfaceWidth);
        mTextureView.setScaleY((float)realVideoWidth/surfaceHeight);
    }

上述代码还可以优化,但是为了阅读方便,没有处理。

水平方向还好理解,竖直方向的缩放,因为牵涉到旋转,所以原来的视频宽高比也要互换位置,同时渲染的texture的缩放比列也要互换位置,我都用红色标注了。


4.播放器尺寸的修改

onSurfaceTextureSizeChanged

只要对视频的渲染皮肤事件侦听就可以了,然后修改后,再去判断当前的状态是全屏还是非全屏的,这些都还好弄。

就是碰到一些奇怪的现象,有时候播放器的设置,第一次设置后,坐标和尺寸不执行,加了一个延时执行才可以

new Handler().postDelayed(new Runnable() {
                public void run() {
                    //具体代码
            }, delayTime);
不知道是渲染机制的问题还是?这块没有深入研究

5.关闭播放器

大家都知道释放播放器的代码是:

this.mediaPlayer.release();
this.mediaPlayer = null;

但是在实际测试的过程中,有时候执行到这步的时候会报空指针错误,google了一些资料,说是清除机制里,这个变量值可能在一些特殊的时机里,会已经被null了,所以再执行就会报错,和系统底层所取的变量值不一致。

解决的方法是:类名.mediaPlayer这种访问方式去执行,可以避免。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值