android播放有旋转角度的视频

       最近公司在APP内部嵌了视频交友功能,由于之前没怎么接触过视频功能,自然就想到了用第三方sdk,结果用了云信的sdk全家桶,包括直播,音视频播放,上传等,但是用下来发现有巨坑.....

      在视频播放时他们的播放器sdk并没有兼容带有旋转信息的视频,原本想着用github上的开源库,试了很多start很高的播放器,无奈兼容都有问题,毕竟源视频是云信自己处理的,用他们播放器sdk兼容肯定会好点,所以,只能自己改代码解决这个问题了!


第一步,怎么把视频旋转回正常的角度:

        查看代码发现他们是用SurfaceView作为容器播放视频,便想着能不能把SurfaceView旋转一定角度来解决这个问题,便尝试设置

SurfaceView。setRotation(90)发现然并卵,后通过查资料发现可以从
Canvas 里面着手,便用
Canvas  canvas = SurfaceHolder.lockCanvas();// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作
canvas.rotate(90)发现视频变形了,变的不居中了,变的.....最重要的是视频还是没被纠正旋转角度!
发现SurfaceView不好旋转后便想着能不能换一种视频容器,一查资料,还真有,这时TextureView映入眼帘,我眼前一亮,赶忙试了试,
由原先的
mMediaPlayer.setDisplay(mSurfaceHolder);改成了
TextureView.setRotation(90);
mMediaPlayer.setSurface(new Surface(surfaceTexture));
沃德天,居然有效,我仿佛看到了希望!

第二步,怎么获取视频的旋转角度:
    百度了各种资料,各个论坛,貌似都没有好的解决方案,看来要使出终极武器了(哒哒哒,能冒蓝火的那种),随即我拿出了谷歌大法,最后终于找到了解决方案:

    
    
   public int getVideoRoration(String mUri) {
            int roration = 0;
            android.media.MediaMetadataRetriever mmr = new android.media.MediaMetadataRetriever();
            try {
                if (mUri != null) {
                    HashMap
        
        
         
          headers = null;
                    if (headers == null) {
                        headers = new HashMap
         
         
          
          ();
                        headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");
                    }
                    if (mUri.startsWith("http")) {
                        mmr.setDataSource(mUri, headers);
                    } else {
                        mmr.setDataSource(mUri);
                    }
                }

                String duration = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_DURATION);//时长(毫秒)
                String width = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽
                String height = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高
                String rotationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); // 视频旋转方向
                if (!StringUtil.isEmpty(rotationStr)) {
                    return Integer.parseInt(rotationStr);
                }
                Log.e("TAG", "rotation" + rotationStr);
            } catch (Exception ex) {
                Log.e("TAG", "MediaMetadataRetriever exception " + ex);
                ex.printStackTrace();
            } finally {
                mmr.release();
            }
            return roration;
        }
         
         
        
        
但是官方说明这种方法最低支持api10,不过在我们的项目的支付版本内;(API 10 之前有 不对外开放 -不过可以反射获取
运行,测试,no perfect,视频能正常播放了奋斗;但是发现视频的宽高比不正常,这个嘛,小意思,根据视频的旋转角度重置下视频的宽高就是了直接上代码:
    
    
 @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     
            int videoWidth = getDefaultSize(mVideoWidth, widthMeasureSpec);
            int videoHeight = getDefaultSize(mVideoHeight, heightMeasureSpec);
            int width = getDefaultSize(videoWidth, widthMeasureSpec);
            int height = getDefaultSize(videoHeight, heightMeasureSpec);
            int widthS = getDefaultSize(videoWidth, widthMeasureSpec);
            int heightS = getDefaultSize(videoHeight, heightMeasureSpec);
            if (originW == 0 || originH == 0) {
                originW = widthS;
                originH = heightS;
            }
            if (videoWidth > 0 && videoHeight > 0) {

                int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
                int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
                int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
                int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

                if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                    width = widthSpecSize;
                    height = heightSpecSize;

                    if (videoWidth * height < width * videoHeight) {
                        width = height * videoWidth / videoHeight;
                    } else if (videoWidth * height > width * videoHeight) {
                        height = width * videoHeight / videoWidth;
                    }
                } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                    width = widthSpecSize;
                    height = width * videoHeight / videoWidth;
                    if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                        height = heightSpecSize;
                    }
                } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                    height = heightSpecSize;
                    width = height * videoWidth / videoHeight;
                    if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                        width = widthSpecSize;
                    }
                } else {
                    width = videoWidth;
                    height = videoHeight;
                    if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                        height = heightSpecSize;
                        width = height * videoWidth / videoHeight;
                    }
                    if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                        width = widthSpecSize;
                        height = width * videoHeight / videoWidth;
                    }
                }
            } else {
                // no size yet, just adopt the given spec sizes
            }
            boolean rotate = (getRotation() != 0 && getRotation() % 90 == 0 && Math.abs(getRotation()) != 180);
            if (rotate) {
                if (widthS < heightS) {
                    if (width > height) {
                        width = (int) (width * (float) widthS / height);
                        height = widthS;
                    } else {
                        height = (int) (height * (float) width / widthS);
                        width = widthS;
                    }
                } else {
                    if (width > height) {
                        height = (int) (height * (float) width / widthS);
                        width = widthS;
                    } else {
                        width = (int) (width * (float) widthS / height);
                        height = widthS;
                    }
                }
            }
    //全屏
            if (rotate && getRotation() != 0) {
                if (width > height) {
                    if (height < originW) {
                        width = (int) (width * ((float) originW / height));
                        height = originW;
                    } else if (width < originH) {
                        height = (int) (height * ((float) originH / width));
                        width = originH;
                    }
                } else {
                    if (width < originH) {
                        height = (int) (height * ((float) originH / width));
                        width = originH;
                    } else if (height < originW) {
                        width = (int) (width * ((float) originW / height));
                        height = originW;
                    }
                }
            } else {
                if (height > width) {
                    if (width < widthS) {
                        height = (int) (height * ((float) widthS / width));
                        width = widthS;
                    } else {
                        width = (int) (width * ((float) heightS / height));
                        height = heightS;
                    }
                } else {
                    if (height < heightS) {
                        width = (int) (width * ((float) heightS / height));
                        height = heightS;
                    } else {
                        height = (int) (height * ((float) widthS / width));
                        width = widthS;
                    }
                }
            }
            setMeasuredDimension(width, height);
        }
运行,测试,perfect,总算告一段落了。
后来整理资料发现有一个第三方库可以获取更完善的视频信息,并且可以兼容到api7,大家有兴趣的可以试试:https://github.com/wseemann/FFmpegMediaMetadataRetriever;
再回头看看,我去,我TM都写了些什么啊,上张福利图给大家,别打我脸!







评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值