MXVideo中使用自动以的TextureView来处理视频的显示
相关代码位置:
com.mx.video.views.MXTextureView
播放器可以设置两种缩放类型:
MXScale.FILL_PARENT // 视频缩放填充播放器
MXScale.CENTER_CROP // 视频按比例自适应宽/高
播放器可以设置TextureView的旋转角度:
MXOrientation.DEGREE_0 // 默认竖屏0度
MXOrientation.DEGREE_90 // 右横屏
MXOrientation.DEGREE_180 // 反向竖屏
MXOrientation.DEGREE_270 // 左横屏
播放器可以设置TextureView的水平镜像功能:
// 默认=false
mxVideoStd.getConfig().mirrorMode.set(true)
MXTextureView功能点
- 处理MXScale变化
- 处理MXOrientation变化
- 处理水平镜像功能
MXTextureView通过设置Matrix来改变画面的显示:
textureView.setTransform(mxMatrix)
Matrix相关原理:https://www.jianshu.com/p/d553ae5e5170 这里不做过多介绍,咱们只聊当前视频需要用到的相关功能
相关变换代码:
private val mxMatrix = Matrix()
private fun resetTransform() {
val config = config
// 当前View的 宽、高
val viewWidth = size.get().width.toFloat()
val viewHeight = size.get().height.toFloat()
//Martrix首先需要确定矩阵的变换中心点,中心点在TextureView的(宽/2f ,高/2f) 位置
val sx = viewWidth / 2f
val sy = viewHeight / 2f
// 过滤无效的条件
if (config == null || viewWidth <= 0 || viewHeight <= 0) {
setTransform(null)
return
}
// 当前旋转角度
val orientation = config.orientation.get()
// 当前缩放模式
val scale = config.scale.get()
// 是否镜像模式
val mirror = config.mirrorMode.get()
val videoSize = config.videoSize.get()
if (videoSize.width <= 0 || videoSize.height <= 0) {
// 数据校验
setTransform(null)
return
}
// 视频宽高比 宽度/高度
val videoRatio = videoSize.width.toFloat() / videoSize.height.toFloat()
// 重置
mxMatrix.reset()
// 第一步:处理旋转角度
mxMatrix.setRotate(orientation.degree.toFloat(), sx, sy)
if (orientation.isVertical()) { // 竖屏处理
// 计算缩放后的宽高
val target = getScaleCenterCrop(scale, videoRatio, viewWidth, viewHeight)
// 第二步:处理缩放
mxMatrix.postScale(
target.first / viewWidth,
target.second / viewHeight,
sx, sy
)
} else if (orientation.isHorizontal()) { // 横屏处理
val scaleX = viewHeight / viewWidth
val scaleY = viewWidth / viewHeight
if (scale == MXScale.CENTER_CROP) {
val target = getScaleCenterCrop(
scale,
1f / videoRatio,
viewWidth,
viewHeight
)
mxMatrix.postScale(
scaleY * target.first / viewWidth,
scaleX * target.second / viewHeight,
sx, sy
)
} else {
mxMatrix.postScale(scaleY, scaleX, sx, sy)
}
}
if (mirror) { // 水平镜像处理
mxMatrix.postScale(-1f, 1f, sx, sy)
}
setTransform(mxMatrix)
}
/**
* 计算缩放后的大小
*/
private fun getScaleCenterCrop(
scale: MXScale, videoRatio: Float,
w: Float, h: Float
): Pair<Float, Float> {
return when (scale) {
MXScale.FILL_PARENT -> {
Pair(w, h)
}
MXScale.CENTER_CROP -> {
if (videoRatio > w / h) {
Pair(w, w / videoRatio)
} else {
Pair(videoRatio * h, h)
}
}
}
}
网友评论