@@ -122,6 +122,7 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener {
|
||||
private var surfaceContainer: FrameLayout? = null
|
||||
private var videoAspectContainer: AspectRatioFrameLayout? = null
|
||||
private var subtitleView: SubtitleView? = null
|
||||
private var videoZoomScale: Float = 1.0f
|
||||
private var assHandler: AssHandler? = null
|
||||
private var overlayLayoutListener: ViewTreeObserver.OnGlobalLayoutListener? = null
|
||||
private var lastVideoSize: VideoSize? = null
|
||||
@@ -1193,18 +1194,26 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener {
|
||||
val containerHeight = contentView.height
|
||||
if (containerWidth == 0 || containerHeight == 0) return
|
||||
|
||||
// In cover/stretch modes subtitles stay at container size so they never get
|
||||
// cropped or distorted. In letterbox mode they follow the video rect so they
|
||||
// anchor to the bottom of the video (matching MPV's default sub positioning).
|
||||
// In cover/stretch/zoomed-in modes subtitles stay at container size so they
|
||||
// never get cropped. In letterbox mode they follow the visible video rect.
|
||||
val isLetterbox = videoAspectContainer?.resizeMode == AspectRatioFrameLayout.RESIZE_MODE_FIT
|
||||
val (subWidth, subHeight) = if (isLetterbox) {
|
||||
val videoAspect = (videoWidth * pixelRatio) / videoHeight
|
||||
val containerAspect = containerWidth.toFloat() / containerHeight
|
||||
if (videoAspect > containerAspect) {
|
||||
val (baseWidth, baseHeight) = if (videoAspect > containerAspect) {
|
||||
containerWidth to (containerWidth / videoAspect).toInt()
|
||||
} else {
|
||||
(containerHeight * videoAspect).toInt() to containerHeight
|
||||
}
|
||||
if (videoZoomScale < 0.999f) {
|
||||
val zoomedWidth = ((baseWidth * videoZoomScale).toInt()).coerceAtLeast(1)
|
||||
val zoomedHeight = ((baseHeight * videoZoomScale).toInt()).coerceAtLeast(1)
|
||||
zoomedWidth to zoomedHeight
|
||||
} else if (videoZoomScale > 1.001f) {
|
||||
containerWidth to containerHeight
|
||||
} else {
|
||||
baseWidth to baseHeight
|
||||
}
|
||||
} else {
|
||||
containerWidth to containerHeight
|
||||
}
|
||||
@@ -1235,6 +1244,21 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener {
|
||||
}
|
||||
}
|
||||
|
||||
fun setVideoZoom(scale: Double) {
|
||||
if (disposing) return
|
||||
val clamped = scale.coerceIn(0.5, 2.0).toFloat()
|
||||
activity.runOnUiThread {
|
||||
videoZoomScale = clamped
|
||||
videoAspectContainer?.scaleX = clamped
|
||||
videoAspectContainer?.scaleY = clamped
|
||||
lastVideoSize?.let { vs ->
|
||||
if (vs.width > 0 && vs.height > 0) {
|
||||
updateSubtitleViewSize(vs.width, vs.height, vs.pixelWidthHeightRatio)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun emitTrackList() {
|
||||
val player = exoPlayer ?: return
|
||||
val tracks = player.currentTracks
|
||||
|
||||
@@ -148,6 +148,7 @@ class ExoPlayerPlugin :
|
||||
}
|
||||
"setSubtitleStyle" -> handleSetSubtitleStyle(call, result)
|
||||
"setBoxFitMode" -> handleSetBoxFitMode(call, result)
|
||||
"setVideoZoom" -> handleSetVideoZoom(call, result)
|
||||
"setDvConversionMode" -> handleSetDvConversionMode(call, result)
|
||||
"observeProperty" -> handleObserveProperty(call, result)
|
||||
"setMpvProperty" -> handleSetMpvProperty(call, result)
|
||||
@@ -550,6 +551,22 @@ class ExoPlayerPlugin :
|
||||
} ?: result.success(null)
|
||||
}
|
||||
|
||||
private fun handleSetVideoZoom(call: MethodCall, result: MethodChannel.Result) {
|
||||
val scale = call.argument<Number>("scale")?.toDouble()
|
||||
if (scale == null) {
|
||||
result.error("INVALID_ARGS", "Missing 'scale'", null)
|
||||
return
|
||||
}
|
||||
if (usingMpvFallback) {
|
||||
result.success(null)
|
||||
return
|
||||
}
|
||||
activity?.runOnUiThread {
|
||||
playerCore?.setVideoZoom(scale)
|
||||
result.success(null)
|
||||
} ?: result.success(null)
|
||||
}
|
||||
|
||||
private fun handleSetDvConversionMode(call: MethodCall, result: MethodChannel.Result) {
|
||||
val mode = call.argument<String>("mode")
|
||||
if (mode == null) {
|
||||
|
||||
Reference in New Issue
Block a user