EasyPlayer RTSP 安卓Android播放器显示模式设置方法
一般对于一个播放器,应该支持如下几种显示模式:
- 等比例,最大化区域显示,不裁剪
- 等比例,最大区域显示,裁剪
- 拉伸显示,铺满全屏
要实现这几种显示模式,其实只要对播放控件的布局进行些许调整即可.那EasyPlayer是怎么实现的呢?
EasyPlayer使用一个PlayFragment进行视频播放.该类实现了一个setScaleType的方法来进行显示模式设定(或切换).
public void setScaleType(@IntRange(from = ASPACT_RATIO_INSIDE, to = FILL_WINDOW) int type){
mRatioType = type;
if (mWidth != 0 && mHeight != 0){
onVideoSizeChange();
}
}
这里的逻辑很简单,首先保存一下type的状态,并判断视频的宽高是否已经获取到了,如果是,则立马对view的尺寸进行计算,否则等获取到了后再计算.
其参数支持如下几种:
/**
* 等比例,最大化区域显示,不裁剪
*/
public static final int ASPACT_RATIO_INSIDE = 1;
/**
* 等比例,裁剪,裁剪区域可以通过拖拽展示\隐藏
*/
public static final int ASPACT_RATIO_CROPE_MATRIX = 2;
/**
* 等比例,最大区域显示,裁剪
*/
public static final int ASPACT_RATIO_CENTER_CROPE = 3;
/**
* 拉伸显示,铺满全屏
*/
public static final int FILL_WINDOW = 4;
我们结合代码与注释,看看onVideoSizeChange()函数主要做了什么:
private void onVideoSizeChange() {
// 视频尺寸未获取成功,直接返回.
if (mWidth == 0 || mHeight == 0) return;
if (mAttacher != null){ // 如果之前的模式是ASPACT_RATIO_CROPE_MATRIX,先释放attacher.
mAttacher.cleanup();
mAttacher = null;
}
if (mRatioType == ASPACT_RATIO_CROPE_MATRIX) {
// ...
// 这种情况下,需要将显示区域铺满父窗口.并使用matrix和手势进行显示控制.
// 具体的控制方法,参考文章:http://blog.csdn.net/jyt0551/article/details/56063869
mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
// 初始化新的Attacher进行显示控制.
// ...
// 使用一个角度控件来显示当前的拖动角度.
mAngleView.setVisibility(View.VISIBLE);
}else {
// 重置matrix为默认(不做显示形变)
mSurfaceView.setTransform(new Matrix());
mAngleView.setVisibility(View.GONE);
// 分别计算出显示控件的宽高比和视频的宽高比
float ratioView = getView().getWidth() * 1.0f/getView().getHeight();
float ratio = mWidth * 1.0f/mHeight;
switch (mRatioType){
case ASPACT_RATIO_INSIDE: {
if (ratioView - ratio < 0){ // 屏幕宽高比相比视频的宽高比更小.表示视频是过于宽了.
// 那就以宽为基准.宽最大化
mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
// 高进行等比例缩放
mSurfaceView.getLayoutParams().height = (int) (getView().getWidth() / ratio + 0.5f);
}else{ // 视频是竖屏了.
// 以高为基准,高最大化
mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
// 宽进行等比例缩放
mSurfaceView.getLayoutParams().width = (int) (getView().getHeight() * ratio + 0.5f);
}
}
break;
case ASPACT_RATIO_CENTER_CROPE: {
// 以更短的为基准
if (ratioView - ratio < 0){ // 屏幕宽高比相比视频的宽高比更小.表示视频是过于宽了.横向裁剪
// 以高为基准.高铺满全屏
mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
// 等比例计算出横向区域..多出父控件的范围将被裁剪
mSurfaceView.getLayoutParams().width = (int) (getView().getHeight() * ratio+ 0.5f);
}else{ // 视频是竖屏了.
// 那就以宽为基准.宽铺满屏幕
mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
// 等比例计算出纵向区域,超出父控件的范围将被裁剪
mSurfaceView.getLayoutParams().height = (int) (getView().getWidth() / ratio+ 0.5f);
}
}
break;
case FILL_WINDOW:{
// 铺满父控件即可...
mSurfaceView.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
mSurfaceView.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
}
break;
}
}
// 布局更改,刷新下.
mSurfaceView.requestLayout();
}
onVideoSizeChange函数,除了在手动设置显示模式的时候调用外,在成功获取到了视频宽高,或者视频宽高更改之后,也会调用.如下:
if (resultCode == EasyRTSPClient.RESULT_VIDEO_DISPLAYED) {
// 视频开始显示了.
onVideoDisplayed();
} else if (resultCode == EasyRTSPClient.RESULT_VIDEO_SIZE) {
// 视频分辨率获取到,或者更改了
mWidth = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_WIDTH);
mHeight = resultData.getInt(EasyRTSPClient.EXTRA_VIDEO_HEIGHT);
onVideoSizeChange();
}
在EasyPlayer工程的demo事例里面,调用方法如下:
public void onToggleAspectRatio(View view) {
PlayFragment f =mRenderFragment;
if (f == null) return;
f.setScaleType(++i);
switch (i){
case PlayFragment.ASPACT_RATIO_INSIDE: {
Toast.makeText(this,"等比例居中",Toast.LENGTH_SHORT).show();
}
break;
case PlayFragment.ASPACT_RATIO_CENTER_CROPE: {
Toast.makeText(this,"等比例居中裁剪视频",Toast.LENGTH_SHORT).show();
}
break;
case PlayFragment.FILL_WINDOW:{
Toast.makeText(this,"拉伸视频,铺满区域",Toast.LENGTH_SHORT).show();
}
break;
case PlayFragment.ASPACT_RATIO_CROPE_MATRIX:{
Toast.makeText(this,"等比例显示视频,可拖拽显示隐藏区域.",Toast.LENGTH_SHORT).show();
}
break;
}
if (i == PlayFragment.FILL_WINDOW){
i = 0;
}
}
让我们看看展示效果:
关于EasyPlayer流媒体播放器
An elegant, simple, fast android RTSP/RTMP/HLS/HTTP Player.EasyPlayer support RTSP(RTP over TCP/UDP)version & Pro version,cover all kinds of streaming media!EasyPlayer是一款精炼、高效、稳定的流媒体播放器,分为RTSP版、RTMP版和Pro版三个版本,支持各种各样的流媒体音视频协议和文件的播放,在安防、互联网、教育、录播、IPTV等多个领域大放异彩,广泛应用!
EasyPlayer:https://github.com/EasyDSS/EasyPlayer
点击链接加入群【EasyPlayer】:544917793
获取更多信息
EasyDarwin开源流媒体服务器:www.EasyDarwin.org
EasyDSS商用流媒体解决方案:www.EasyDSS.com
EasyNVR无插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2017

EasyPlayer RTSP 安卓Android播放器显示模式设置方法的更多相关文章
- EasyPlayer RTSP安卓Android播放器架构简析
本文转自EasyDarwin开源团队成员John的博客:http://blog.csdn.net/jyt0551/article/details/73310641 EasyPlayer 是一款小而美的 ...
- RTSP Windows专用播放器EasyPlayer : 稳定、兼容、高效、超低延时
EasyPlayer RTSP Windows专用播放器 EasyPlayer RTSP Windows 播放器是由EasyDarwin团队开发和维护的一个完善的RTSP流媒体播放器项目,视频编码支持 ...
- github上十二款最著名的Android播放器开源项目
1.ijkplayer 项目地址: https://github.com/Bilibili/ijkplayer 介绍:Ijkplayer 是Bilibili发布的基于 FFplay 的轻量级 Andr ...
- GitHub上最著名的Android播放器开源项目大全
GitHub上最著名的Android播放器开源项目大全 ...
- EasyPlayer安卓Android流媒体播放器实现直播过程中客户端快照功能
本文转自:http://blog.csdn.net/jyt0551/article/details/56942795 对于一个裸的RTSP URL,存放在播放列表上略显单调与枯燥.大家可以看到Easy ...
- 【翻译】安卓新播放器EXOplayer介绍
http://developer.android.com/guide/topics/media/exoplayer.html 前言: Playing videos and music is a p ...
- Android——播放器和图片轮播
layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...
- 安卓MP3播放器开发实例(1)之音乐列表界面
学习安卓开发有一年了,想想这一年的努力,确实也收获了不少.也找到了比較如意的工作. 今天准备分享一个以前在初学阶段练习的一个项目.通过这个项目我真正的找到了开发安卓软件的感觉,从此逐渐步入安卓开发的正 ...
- Android播放器推荐:可以播放本地音乐、视频、在线播放音乐、视频、网络收音机等
下载链接:http://www.eoeandroid.com/forum.php?mod=attachment&aid=MTAxNTczfGMyNjNkMzFlfDEzNzY1MzkwNTR8 ...
随机推荐
- AC日记——最高奖励 51nod 1163
最高的奖励 思路: 排序: 时间为第一关键字,按总小到大排: 价值为第二关键字,按从大到小排: 然后,不难看出,如果两个时间不同: 那么,两个时间之间最少能做一件事: 因为他们的时间下限最少相差1: ...
- 解决dvajs使用BrowserHistory路由模式后仍然会出现hash(哈希)
在dvajs中,如果你在初始化dva对象的时候不作任何处理,那么你就会发现即使你是用了BrowserRouter来作为Router url中也是会出现#/.解决方法也很简单: 使用前先手动安装下 hi ...
- Codeforces Gym100735 D.Triangle Formation (KTU Programming Camp (Day 1) Lithuania, Birˇstonas, August 19, 2015)
日常训练题解 D.Triangle Formation You are given N wooden sticks. Your task is to determine how many triang ...
- Swift 基础部分(建议掌握OC字符串知识的翻阅)
更新说明: Swift 目前已经发布到4.0版本了,以前写的这整个Swift学习系列的文章,有很多的不足之处,我会重新整理整个系列文章,也是相当于重新复习一遍Swift,后面系列文章的改动之处全都会做 ...
- retain和copy还有assign的区别
1. 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给 (assign)了b.此时a和b指向同一块内存,请问当a不再需 ...
- Define Custom Data Filter Using Pre-Query Trigger In Oracle Forms
Oracle Forms is having its default records filter, which we can use through Enter Query mode to spec ...
- [置顶]
个人微信号发送zabbix告警信息
之前使用邮件和短信发送zabbix告警信息,但告警信息无法实时查看或者无法发送,故障无法及时通知运维人员. 后来使用第三方微信接口发送信息,愉快地用了一年多,突然收费了. zabbix告警一直是我的痛 ...
- mac 下bash命令
可以一行写一条命令 nginx uwsgi /Users/***/djangoprojects/bpmTest/uwsgi.ini 将上述命令保存成**.sh文件 这样,然后bash ***.sh 实 ...
- MFC中 获取新输入编辑框的内容
//得到原始内容的长度 int len = m_editPoemFileStr.GetLength(); UpdateData(true); //得到新增加的内容 CString sNewStrin ...
- 【转载】C++11的简单学习
首先在我们的开发机以及线上机器一般都安装了C++11,目录在: /opt/compiler/gcc-4.8.2/ 看了下面这篇文章<[C++11]30分钟了解C++11新特性> http: ...