Keep video gesture callbacks current and forbid reads during cleanup
This commit is contained in:
1 parent
fdecfe1b78
commit
7ec46278af
3 files changed
+11
-8
No files matched your search
@@ -20,11 +20,13 @@ internal class VideoFileMetadata : AutoCloseable {
|
||||
private val main = Handler(Looper.getMainLooper())
|
||||
private var delay = 250L
|
||||
private var scheduled = false
|
||||
private var closing = false
|
||||
private val retry = Runnable {
|
||||
synchronized(this) { scheduled = false }
|
||||
try { close() } catch (e: Exception) { LogManager.addLog("WARN", "VideoPlayer", "Metadata cleanup pending: $e") }
|
||||
}
|
||||
@Synchronized fun read(path: String): VideoInfo {
|
||||
check(!closing) { "Metadata reader closing" }
|
||||
val current = checkNotNull(retriever) { "Metadata reader closed" }
|
||||
current.setDataSource(path)
|
||||
val width = current.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toIntOrNull() ?: 0
|
||||
@@ -34,6 +36,7 @@ internal class VideoFileMetadata : AutoCloseable {
|
||||
return VideoInfo(width, height, rotation)
|
||||
}
|
||||
@Synchronized override fun close() {
|
||||
closing = true
|
||||
val current = retriever ?: return
|
||||
try {
|
||||
current.release(); retriever = null
|
||||
|
||||
@@ -68,7 +68,7 @@ internal class VideoFilePlayer(onCompleted: () -> Unit) : AutoCloseable {
|
||||
fun attach(texture: SurfaceTexture) {
|
||||
check(Looper.myLooper() == Looper.getMainLooper())
|
||||
if (uiTargets.containsKey(texture)) return
|
||||
val target = StreamPreviewTarget(texture)
|
||||
val target = try { StreamPreviewTarget(texture) } catch (e: Exception) { fail("create Surface", e); return }
|
||||
uiTargets[texture] = target
|
||||
if (disposed) { target.release(); return }
|
||||
if (retiring) return // UI сохраняет собственную texture до destroy/close даже после ошибки player.
|
||||
|
||||
+7
-7
@@ -259,13 +259,13 @@ fun VideoPlayerScreen(filePath: String, onClose: () -> Unit) {
|
||||
if (error == null) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
.pointerInput(Unit) {
|
||||
.pointerInput(player) {
|
||||
detectTapGestures {
|
||||
hideTick++
|
||||
if (isPlaying) controlsVisible = !controlsVisible
|
||||
if (player.state.value.playing) controlsVisible = !controlsVisible
|
||||
}
|
||||
}
|
||||
.pointerInput(screenW, screenH, videoW, videoH) {
|
||||
.pointerInput(player, screenW, screenH, videoW, videoH) {
|
||||
detectTransformGestures { centroid, pan, factor, _ ->
|
||||
onInteraction()
|
||||
zoom.transform(centroid, pan, factor, Size(videoW, videoH), Size(screenW, screenH))
|
||||
@@ -377,7 +377,7 @@ fun VideoPlayerScreen(filePath: String, onClose: () -> Unit) {
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(32.dp)
|
||||
.pointerInput(durationMs, playback.prepared, error) {
|
||||
.pointerInput(player, durationMs, playback.prepared, error) {
|
||||
detectTapGestures { offset ->
|
||||
if (!playback.prepared || error != null) return@detectTapGestures
|
||||
onInteraction()
|
||||
@@ -385,11 +385,11 @@ fun VideoPlayerScreen(filePath: String, onClose: () -> Unit) {
|
||||
player.seek(pos)
|
||||
}
|
||||
}
|
||||
.pointerInput(durationMs, playback.prepared, error) {
|
||||
.pointerInput(player, durationMs, playback.prepared, error) {
|
||||
detectDragGestures(
|
||||
onDragStart = { offset ->
|
||||
wasPlayingBeforeDrag = isPlaying
|
||||
if (playback.prepared && error == null && (!isPlaying || player.pause())) {
|
||||
wasPlayingBeforeDrag = player.state.value.playing
|
||||
if (playback.prepared && error == null && (!wasPlayingBeforeDrag || player.pause())) {
|
||||
dragging = true
|
||||
dragPosition = (offset.x / size.width * durationMs).toInt().coerceIn(0, durationMs)
|
||||
player.seek(dragPosition)
|
||||
|
||||
Reference in new issue
Block a user