Android开发 MediaPlayer将视频播放时尺寸适配完美
前言
视频播放有一个较为蛋疼的问题,那就是尺寸适配.如果不做尺寸适配视频将会变形拉伸或者压缩.下面我就介绍个人实现的算法.
满足一边的算法
满足一边?你可能是疑问是什么意思.意思是就是始终将视频的高度或者宽度的其中一个铺满对应屏幕的高度或者宽度.然后在将另外一个高或宽按比例求出合适的尺寸,其实这跟与摄像头的求出合适的分辨率预览思想是类似的.
另外,在视频高大于宽且屏幕是竖屏情况下,铺满高度,但是会计算宽度,但是计算后多多少少视频宽度与屏幕宽度不一致,但是其实已经很接近比例了.我们可以接受视频的轻微拉伸,来满足视频铺满屏幕的情况,下面的算法就是做了这种优化.
代码部分:
/**
* 修改预览View的大小,以用来适配屏幕
*/
public void changeVideoSize() {
int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
int deviceWidth = getResources().getDisplayMetrics().widthPixels;
int deviceHeight = getResources().getDisplayMetrics().heightPixels;
Log.e(TAG, "changeVideoSize: deviceHeight="+deviceHeight+"deviceWidth="+deviceWidth);
float devicePercent = 0;
//下面进行求屏幕比例,因为横竖屏会改变屏幕宽度值,所以为了保持更小的值除更大的值.
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { //竖屏
devicePercent = (float) deviceWidth / (float) deviceHeight; //竖屏状态下宽度小与高度,求比
}else { //横屏
devicePercent = (float) deviceHeight / (float) deviceWidth; //横屏状态下高度小与宽度,求比
} if (videoWidth > videoHeight){ //判断视频的宽大于高,那么我们就优先满足视频的宽度铺满屏幕的宽度,然后在按比例求出合适比例的高度
videoWidth = deviceWidth;//将视频宽度等于设备宽度,让视频的宽铺满屏幕
videoHeight = (int)(deviceWidth*devicePercent);//设置了视频宽度后,在按比例算出视频高度 }else { //判断视频的高大于宽,那么我们就优先满足视频的高度铺满屏幕的高度,然后在按比例求出合适比例的宽度
if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {//竖屏
videoHeight = deviceHeight;
/**
* 接受在宽度的轻微拉伸来满足视频铺满屏幕的优化
*/
float videoPercent = (float) videoWidth / (float) videoHeight;//求视频比例 注意是宽除高 与 上面的devicePercent 保持一致
float differenceValue = Math.abs(videoPercent - devicePercent);//相减求绝对值
L.e("devicePercent="+devicePercent);
L.e("videoPercent="+videoPercent);
L.e("differenceValue="+differenceValue);
if (differenceValue < 0.3){ //如果小于0.3比例,那么就放弃按比例计算宽度直接使用屏幕宽度
videoWidth = deviceWidth;
}else {
videoWidth = (int)(videoWidth/devicePercent);//注意这里是用视频宽度来除
} }else { //横屏
videoHeight = deviceHeight;
videoWidth = (int)(deviceHeight*devicePercent); } } ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mVideoPlaySurfaceview.getLayoutParams();
layoutParams.width = videoWidth;
layoutParams.height = videoHeight;
layoutParams.verticalBias = 0.5f;
layoutParams.horizontalBias = 0.5f;
mVideoPlaySurfaceview.setLayoutParams(layoutParams); }
最后调用这个方法的地方
mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() { //尺寸变化回调
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.e(TAG, "onVideoSizeChanged: 触发 width=" + width + "height=" + height);
changeVideoSize();
}
});
求最正方形算法
其实这个算法不是我的,但是一开始看到的这个别人的算法的时候,突然发现这算法跟我相机预览求正方形有异曲同工之妙(基本原理就是高宽比除宽高,或者宽高比除高宽,两个不同的边相除或者相乘会得到近似正方形的尺寸).但是个人觉得,并不合适在视频播放的时候使用,因为在横屏情况下会将视频变得很小.但是搬过来也是一个参考:
public void changeVideoSize() {
int videoWidth = mediaPlayer.getVideoWidth();
int videoHeight = mediaPlayer.getVideoHeight();
//根据视频尺寸去计算->视频可以在sufaceView中放大的最大倍数。
float max;
if (getResources().getConfiguration().orientation==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
//竖屏模式下按视频宽度计算放大倍数值
max = Math.max((float) videoWidth / (float) surfaceWidth,(float) videoHeight / (float) surfaceHeight);
} else{
//横屏模式下按视频高度计算放大倍数值
max = Math.max(((float) videoWidth/(float) surfaceHeight),(float) videoHeight/(float) surfaceWidth);
}
//视频宽高分别/最大倍数值 计算出放大后的视频尺寸
videoWidth = (int) Math.ceil((float) videoWidth / max);
videoHeight = (int) Math.ceil((float) videoHeight / max);
//无法直接设置视频尺寸,将计算出的视频尺寸设置到surfaceView 让视频自动填充。
surfaceView.setLayoutParams(new RelativeLayout.LayoutParams(videoWidth, videoHeight));
}
@Override
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
changeVideoSize();
}
Android开发 MediaPlayer将视频播放时尺寸适配完美的更多相关文章
- Android开发 MediaPlayer入门_播放本地视频
前言 MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择Vi ...
- Android开发 海康威视 多路视频播放(同时播放视频)
原文地址:Android开发 海康视频 多路视频播放 | Stars-One的杂货小窝 最近公司有个项目需要对接到海康监控摄像头来实现对应的实时播放和回放,但这两个不是我们今天要讨论的重点,APP首页 ...
- Android开发 MediaPlayer播放本地视频完善的demo(只是代码记录)
xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.w ...
- Android开发中使用数据库时出现java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed.
最近在开发一个 App 的时候用到了数据库,可是在使用数据库的时候就出现了一些问题,在我查询表中的一些信息时出现了一下问题: Caused by: java.lang.IllegalStateExce ...
- Android开发学习—— 创建项目时,不是继承activity,而是继承ActionBarActivity
对于我们新建android项目时, 会 继承ActionBarActivity. 我们在新建项目时, 最小需求的sdk 选择 4.0以上版本.这样 新建的android项目就是继承activity了!
- Android开发 MediaPlayer播放raw资源MP3文件
代码 private MediaPlayer mRingPlayer; /** * 播放铃声 */ private void startRing(){ if (mRingPlayer != null) ...
- [安卓开发板]迅为IMX6 四核Android开发板
工业级核心板-Android开发板 10层高速PCB设计,充分保证电磁兼容 处理器:开发板默认是四核商业扩展级芯片,可根据用户需求更换单核.双核.工业级.汽车级处理器,批量更省成本. 扩展引脚:320 ...
- 双非本科Android开发,如何逆袭拿到大厂 Offer?
从2020年3月18日投出第一份暑期实习简历至今,已经过去400多天.我也尘埃落定,即将去CVTE做Android开发. 休息了很长时间,如今已经能够很平静地回首这段历程,写下这篇文,致敬曾经走过的漫 ...
- 【Android 多媒体开发】 MediaPlayer 网络视频播放器
作者 : 万境绝尘 (octopus_truth@163.com) 转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/3889514 ...
随机推荐
- Core Text 入门
本文所涉及的代码你可以在这里下载到 https://github.com/kejinlu/CTTest,包含两个项目,一个Mac的NSTextView的测试项目,一个iOS的Core Text的测试项 ...
- 利用zk客户端删除solr shard
进入zk客户端 ./bin/zkCli.sh -server ip:2181 显示所有的内容: ls / 删除数据: rmr /filename path
- python简介与安装
Python简介和环境搭建 于 20世纪80年代末,Guido van Rossum发明了Python,初衷据说是为了打发圣诞节的无趣.1991年首次发布,是ABC语言的继承,同时也是一种脚本语言.取 ...
- uoj33 【UR #2】树上GCD
题目 大致是长剖+\(\rm dsu\ on\ tree\)的思想 先做一个转化,改为对于\(i\in[1,n-1]\)求出有多少个\(f(u,v)\)满足\(i|f(u,v)\),这样我们最后再做一 ...
- codeforces round#524 C. Masha and two friends /// 矩形切割
题目大意: 给定n行m列的黑白棋盘如下 给定矩形的左下点x1 y1和右上点x2 y2将这个区域都涂成白色 再给定矩形的左下点x3 y3和右上点x4 y4将这个区域都涂成黑色 求最后棋盘内有分别多少个白 ...
- POJ 1946 Cow Cycling
Cow Cycling Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 2516 Accepted: 1396 Descr ...
- Spring MVC入门示例(1)
1.新建一个Java Web项目 2.导入jar包 3.在WEB-INF下面建一个hello.jsp页面. 1 <%@ page language="java" import ...
- jdbc_mysql----interset
- 在CentOS 7上安装常用的YUM源
参考地址:https://blog.csdn.net/u010048823/article/details/51298183 以epel源为例子,来讲解如何添加额外的YUM源. Extra Packa ...
- 可读性 vs 效率
哪个重要. 应用层代码来说,实际上说任意一个重要都不为过, 但是到了内核里面之后,哪个重要. 肯定是效率阿,内核跑得慢,上面还有得玩么.