android播放有旋转角度的视频

来源:互联网 发布:js表单数据的验证 编辑:程序博客网 时间:2024/05/17 09:12

       最近公司在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都写了些什么啊,上张福利图给大家,别打我脸!




阅读全文
0 0
原创粉丝点击