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 ...
随机推荐
- 关于对现阶段vue项目的一些总结和感想
一.前言 现阶段手上vue的项目差不多快完了,空闲之余回反复对整个项目的代码结构.实现细节以及框架上的做了一些思考和优化.下面打算把想到的和重点实现的方法记录一下. 二.回顾 对于常规操作,这里不做过 ...
- jdk 动态代理和 cglib 动态代理
原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载 ...
- map和unordered_map使用小结
map和unordered_map unordered_map简介: #include <cstdio> #include <iostream> #include <un ...
- slot 的简单用法
注:默认在父组件调用子组件时<SlotChild></SlotChild>中文字不会显示.但是在子组件加入<slot></slot>后,<Slot ...
- Centos7.5安装mysql 8.0.11
一.安装前准备 安装采用二进制包方式,软件包8.0.11版本下载地址: https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-linux-gl ...
- beautifulsoup的使用
解析库 解析器 使用方法 优势 劣势 Python标准库 BeautifulSoup(markup, "html.parser") Python的内置标准库.执行速度适中 .文档容 ...
- linux 平台安装JDK环境
1.检查一下系统中的jdk版本 [root@localhost software]# java -version 2.检测jdk安装包 [root@localhost software]# rpm - ...
- Interesting HDU - 5785 回文树
题意: 找出所有[i,j]为回文串[j+1,k]也为回文串的i*k乘积之和. 题解: 设sum1[i] 为正着插入,到 i 的所有回文串的起始位置的前缀和,sum2[i] 表示反正插入的前缀和 ans ...
- c++智能指针(unique_ptr 、shared_ptr、weak_ptr、auto_ptr)
一.前序 什么是智能指针? ——是一个类,用来存储指针(指向动态分配对象也就是堆中对象的的指针). c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写 ...
- VBA提取HTML文件信息
Sub test() Dim html As Object, D As Object, W As Object, arr() Set html = CreateObject("m ...