有个测试视频可以直接下载:
https://www.w3schools.com/html/mov_bbb.mp4
下面是项目代码,原样抄出来:
/**
* A TextureView that adapts its scale type based on the screen's aspect ratio.
* - On tall screens (> 16:9), it behaves like ImageView's "centerCrop".
* - On wide screens (<= 16:9), it behaves like ImageView's "fitCenter".
*/
class ScalableTextureView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : TextureView(context, attrs, defStyleAttr) {
companion object {
private const val TAG = "ScalableTextureView"
}
sealed class Mode {
abstract fun getViewportRect(
videoWidth: Int,
videoHeight: Int,
viewWidth: Int,
viewHeight: Int
): RectF
data object CenterCrop : Mode() {
override fun getViewportRect(
videoWidth: Int,
videoHeight: Int,
viewWidth: Int,
viewHeight: Int
): RectF {
val hRatio = viewHeight.toFloat() / videoHeight.toFloat()
val wRatio = viewWidth.toFloat() / videoWidth.toFloat()
val finalRatio = max(hRatio, wRatio)
val finalViewWidth = videoWidth.toFloat() * finalRatio
val finalViewHeight = videoHeight.toFloat() * finalRatio
val centerX = viewWidth / 2F
val centerY = viewHeight / 2F
val dstRect = RectF(
centerX - finalViewWidth / 2F,
centerY - finalViewHeight / 2F,
centerX + finalViewWidth / 2F,
centerY + finalViewHeight / 2F
)
return dstRect
}
}
data object FitCenter : Mode() {
override fun getViewportRect(
videoWidth: Int,
videoHeight: Int,
viewWidth: Int,
viewHeight: Int
): RectF {
val hRatio = viewHeight.toFloat() / videoHeight.toFloat()
val wRatio = viewWidth.toFloat() / videoWidth.toFloat()
val finalRatio = min(hRatio, wRatio)
val finalViewWidth = videoWidth.toFloat() * finalRatio
val finalViewHeight = videoHeight.toFloat() * finalRatio
val centerX = viewWidth / 2F
val centerY = viewHeight / 2F
val dstRect = RectF(
centerX - finalViewWidth / 2F,
centerY - finalViewHeight / 2F,
centerX + finalViewWidth / 2F,
centerY + finalViewHeight / 2F
)
return dstRect
}
}
}
private var mVideoWidth = 0
private var mVideoHeight = 0
@Volatile
var mode: Mode = Mode.CenterCrop
init {
this.mode = if (screenHeight.toFloat() / screenWidth.toFloat() > 16F / 9F) Mode.CenterCrop else Mode.FitCenter
}
fun setVideoSize(videoWidth: Int, videoHeight: Int) {
if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) {
this.mVideoWidth = videoWidth
this.mVideoHeight = videoHeight
updateTransform()
}
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
updateTransform()
}
private fun updateTransform() {
if (mVideoWidth == 0 || mVideoHeight == 0) {
setTransform(null)
return
}
if (width == 0 || height == 0) {
return
}
val dstRect = mode.getViewportRect(mVideoWidth, mVideoHeight, width, height)
val srcRect = RectF(0f, 0f, width.toFloat(), height.toFloat())
Log.i(TAG, "transform $srcRect -> $dstRect")
val matrix = Matrix()
matrix.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.FILL)
setTransform(matrix)
}
}

8万+

被折叠的 条评论
为什么被折叠?



