fix: wait for video metadata before playing and set onEnd before play

- Reorder onEnd callback before play() in Engine.goToScene to prevent
  missed ended event if video ends synchronously
- Wait for loadedmetadata event in VideoManager.play() before seeking
  to ensure currentTime reset works correctly on new video sources
This commit is contained in:
2026-06-07 14:34:15 +08:00
parent fb93782331
commit 192ecbbce2
2 changed files with 18 additions and 5 deletions

View File

@@ -46,13 +46,13 @@ export class Engine {
this.stateManager.apply(scene.onEnter) this.stateManager.apply(scene.onEnter)
} }
this.videoManager.play(scene.videoUrl)
this.emit('sceneChange', scene)
this.videoManager.onEnd(() => { this.videoManager.onEnd(() => {
this.emit('videoEnd', scene) this.emit('videoEnd', scene)
this.onVideoEnd(scene) this.onVideoEnd(scene)
}) })
this.videoManager.play(scene.videoUrl)
this.emit('sceneChange', scene)
} }
private onVideoEnd(scene: SceneNode) { private onVideoEnd(scene: SceneNode) {

View File

@@ -25,9 +25,22 @@ export class VideoManager {
if (this.lastSrc !== src) { if (this.lastSrc !== src) {
this.videoEl.src = src this.videoEl.src = src
this.lastSrc = src this.lastSrc = src
if (this.videoEl.readyState >= 1) {
this.videoEl.currentTime = 0
this.videoEl.play().catch(() => {})
} else {
const onReady = () => {
if (this.videoEl) {
this.videoEl.currentTime = 0
this.videoEl.play().catch(() => {})
}
}
this.videoEl.addEventListener('loadedmetadata', onReady, { once: true })
}
} else {
this.videoEl.currentTime = 0
this.videoEl.play().catch(() => {})
} }
this.videoEl.currentTime = 0
this.videoEl.play().catch(() => {})
} }
pause() { pause() {