首页 > 编程知识 正文

可以缩放视频的播放器,potplayer压缩视频大小

时间:2023-05-05 03:45:12 阅读:48211 作者:2024

前言本文的博文主要分析播放视频宽度和高度设置的源代码,为了便于说明,事先简要介绍一下EXOPlayer的使用。

使用ExoPlayer播放视频1 .首先,必须在布局管理器中添加以下xml代码:

com.Google.Android.ex oplayer2. ui.simpleexoplayerviewandroid : id=' @ id/play _ view ' Android : layout _ www

创建SimpleExoPlayer对象。 将SimpleExoPlayer与SimpleExoPlayerView相关联。 代码如下。

bandwidthmeterbandwidthmeter=newdefaultbandwidthmeter (; 跟踪选择. factorytrackfactory=newadaptivetrackselection.factory (bandwidth meter ); 跟踪选择器=newdefaulttrackselector (跟踪工厂; player=exoplayerfactory.newsimpleinstance (this,跟踪选择器); simpleexoplayerview.setplayer (player; 3 .最后创建MediaSource对象并准备播放。

privatevoidprepareplay ((defaultbandwidthmeterdefaultbandwidthmeter=newdefaultbandwidthmeter ); data source.factorydatasourcefactory=newdefaultdatasourcefactory (主活动. this,util.getuser agent (主活动) extractorsfactoryextractorsfactory=newdefaultextractorsfactory (; uri uri=uri.parse (http://mv视频11.meitu data.com/59fd 64 EAC 92 FB 5968 _ h264 _3. MP4? k=b 953933 b a73 a 3271 c9c 7d 926 a0c 54 FB 4t=5a 0a 97 c9' ); mediasourcemediasource=newextractormediasource (uri,数据源工厂,结构工厂,空,空); //player.addlistener () this; player.prepare(mediasource; }这里的视频Uri是我在网上找到的mp4格式视频,正如EXOplayer开发人员文档中所知,多媒体格式与MediaSource实现类的对应关系如下:

dash(dashmediasource )、

smoothstreaming(ssmediasource )、

高清媒体(HLS )、

其他格式使用“ExtractorMediaSource”。

在EXOPLAYER Support Formats文章中,我们知道MP4格式必须使用ExtractorMediaSource。

现在您可以运行程序了(请不要忘记添加网络权限)。 执行效果如下。

控制器是SimpleExoPlayerView附带的默认控制器。 看了这个发现了问题。 安静的牛排。 将SimpleExoPlayerView控件添加到布局管理器时,将宽度和高度设置为match_parent。 为什么那个宽度没有填满父母的布局?

填满屏幕的代码很简单,有两种方法。 可以在代码中实现以下内容:

simpleexoplayerview.setresizemode (aspectratioframelayout.resize _ mode _ fill ); 或者,在xml文件的属性中设置。

设置app:resize_mode='fill '后,让我们看看效果。

说得通

过gif图我们看到,确实,变成了全屏。那我们现在就来分析一下为什么会这样。

源码分析

我们看关键语句:

simpleExoPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);

看看setResizeMode的内部实现:

public void setResizeMode(@ResizeMode int resizeMode) { Assertions.checkState(contentFrame != null); contentFrame.setResizeMode(resizeMode); }

这里调用了contentFrame的setResizeMode方法,contentFrame是AspectRatioFrameLayout对象。我们来看看AspectRatioFrameLayout里面的setResizeMode方法。

public void setResizeMode(@ResizeMode int resizeMode) { if (this.resizeMode != resizeMode) { this.resizeMode = resizeMode; requestLayout(); } }

这里是把resizeMode的值传了进来,我们看一下resizeMode值在AspectRatioFrameLayout类中到底起着什么作用吧。

public AspectRatioFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); resizeMode = RESIZE_MODE_FIT; if (attrs != null) { TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.AspectRatioFrameLayout, 0, 0); try { resizeMode = a.getInt(R.styleable.AspectRatioFrameLayout_resize_mode, RESIZE_MODE_FIT); } finally { a.recycle(); } } }

在AspectRatioFrameLayou的构造方法中,我们看到,resizeMode的默认值是RESIZE_MODE_FIT。这里提到了RESIZE_MODE_FIT,我们就谈谈AspectRatioFrameLayou类中的几种计算视频宽高的模式。

RESIZE_MODE_FIT 表示通过减少视频的宽度或者高度,来达到想要的视频宽高比。 RESIZE_MODE_FIXED_WIDTH 表示宽度是固定的,通过减少或者增加高度的值来实现想要的宽高比。RESIZE_MODE_FIXED_HEIGHT 表示高度是固定的,通过减少或者增加宽度的值来实现想要的宽高比。RESIZE_MODE_FILL 表示不考虑指定的宽高比。RESIZE_MODE_拉长的板凳 表示通过增加宽度或者高度,来达到想要的视频宽高比。

上面呢我演示了设置模式为setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FILL);
的效果,其余的四种效果大家可以自己设置演示,会存在变形的情况哦,所以这玩意还得合理运用。

接下来我们看看resizeMode在哪里使用的,我们看如下代码:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (resizeMode == RESIZE_MODE_FILL || videoAspectRatio <= 0) { // Aspect ratio not set. return; } int width = getMeasuredWidth(); int height = getMeasuredHeight(); float viewAspectRatio = (float) width / height; float aspectDeformation = videoAspectRatio / viewAspectRatio - 1; if (Math.abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) { // We're within the allowed tolerance. return; } switch (resizeMode) { case RESIZE_MODE_FIXED_WIDTH: height = (int) (width / videoAspectRatio); break; case RESIZE_MODE_FIXED_HEIGHT: width = (int) (height * videoAspectRatio); break; case RESIZE_MODE_拉长的板凳: if (aspectDeformation > 0) { width = (int) (height * videoAspectRatio); } else { height = (int) (width / videoAspectRatio); } break; default: if (aspectDeformation > 0) { height = (int) (width / videoAspectRatio); } else { width = (int) (height * videoAspectRatio); } break; } super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); }

这是AspectRatioFrameLayout的onMeasure方法,我们来分析下。
通过代码,我们看到当resizeMode的值为RESIZE_MODE_FILL或者videoAspectRatio<=0时,就return,也就表示它会执行,外面所设置宽高。videoAspectRatio表示想要的视频宽高比。我们接着看,注意到一个if的判断语句。这里的意思是如果想要的宽高比和视频的宽高比的差值如果小于这个临界值MAX_ASPECT_RATIO_DEFORMATION_FRACTION的话,那AspectRatioFrameLayout不需要从新计算他的宽高。这里MAX_ASPECT_RATIO_DEFORMATION_FRACTION=0.01f。
接着我们看switch语句中,对于不同的resizeMode,宽高做了对应的计算。最后把计算的值通过:

super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));

设置进去。
那最后我们再看下videoAspectRatio这个想要的宽高比是在哪里设置的呢,我们发现在SimpleExoPlayerView中有设置:

@Override public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { if (contentFrame != null) { float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height; contentFrame.setAspectRatio(aspectRatio); } }

onVideoSizeChanged方法是在视频渲染期间视频的size值变化的时候会回调,pixelWidthHeightRatio这个参数表示每一个像素的宽高比。

总结

这里对播放视频的宽高设置源码分析到此结束了,后需还有对EXOPlayer的其他分析。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。