From c0e2bc184c3099a182ae46e2dd6312167e005588 Mon Sep 17 00:00:00 2001 From: soywiz Date: Fri, 12 Jun 2020 21:34:46 +0200 Subject: [PATCH] Update KorVI with JS support --- .../src/commonMain/kotlin/main.kt | 2 +- sample-pong/src/commonMain/kotlin/main.kt | 2 +- ...{build.gradle.kts.old => build.gradle.kts} | 2 +- sample-video/src/commonMain/kotlin/main.kt | 114 ++++++------------ 4 files changed, 43 insertions(+), 77 deletions(-) rename sample-video/{build.gradle.kts.old => build.gradle.kts} (78%) diff --git a/sample-dragonbones/src/commonMain/kotlin/main.kt b/sample-dragonbones/src/commonMain/kotlin/main.kt index 55bee44..369da5a 100644 --- a/sample-dragonbones/src/commonMain/kotlin/main.kt +++ b/sample-dragonbones/src/commonMain/kotlin/main.kt @@ -106,7 +106,7 @@ class HelloScene : Scene() { open class MyModule : Module() { override val title: String = "KorGE - DragonBones" - override val mainScene: KClass = MyScene::class + override val mainScene = MyScene::class //override val quality: LightQuality = LightQuality.QUALITY //override val quality: LightQuality = LightQuality.PERFORMANCE //override val quality: LightQuality = LightQuality.AUTO diff --git a/sample-pong/src/commonMain/kotlin/main.kt b/sample-pong/src/commonMain/kotlin/main.kt index 7fefb81..7e1bf07 100644 --- a/sample-pong/src/commonMain/kotlin/main.kt +++ b/sample-pong/src/commonMain/kotlin/main.kt @@ -9,7 +9,7 @@ suspend fun main() = Korge(Korge.Config(module = MyModule)) object MyModule : Module() { // define the opening scene - override val mainScene: KClass = MenuScene::class + override val mainScene = MenuScene::class // define the game configs override val title: String = "My Test Game" diff --git a/sample-video/build.gradle.kts.old b/sample-video/build.gradle.kts similarity index 78% rename from sample-video/build.gradle.kts.old rename to sample-video/build.gradle.kts index f08fa99..250d3f9 100644 --- a/sample-video/build.gradle.kts.old +++ b/sample-video/build.gradle.kts @@ -10,5 +10,5 @@ korge { } dependencies { - add("commonMainApi", "com.soywiz.korlibs.korvi:korvi:0.1.2") + add("commonMainApi", "com.soywiz.korlibs.korvi:korvi:0.2.0") } diff --git a/sample-video/src/commonMain/kotlin/main.kt b/sample-video/src/commonMain/kotlin/main.kt index 207620f..620bd08 100644 --- a/sample-video/src/commonMain/kotlin/main.kt +++ b/sample-video/src/commonMain/kotlin/main.kt @@ -1,104 +1,70 @@ -import com.soywiz.kds.* import com.soywiz.klock.* -import com.soywiz.korau.sound.* -import com.soywiz.korev.* +import com.soywiz.klock.hr.* import com.soywiz.korge.* -import com.soywiz.korge.component.* import com.soywiz.korge.input.* -import com.soywiz.korge.input.mouse -import com.soywiz.korge.time.* -import com.soywiz.korge.tween.* import com.soywiz.korge.view.* import com.soywiz.korim.bitmap.* import com.soywiz.korim.color.* -import com.soywiz.korim.format.* import com.soywiz.korio.async.* import com.soywiz.korio.file.* import com.soywiz.korio.file.std.* -import com.soywiz.korio.lang.* -import com.soywiz.korio.stream.* -import com.soywiz.korma.geom.* -import com.soywiz.korma.interpolation.* +import com.soywiz.korio.util.* import com.soywiz.korvi.* -import kotlin.coroutines.* suspend fun main() = Korge(width = 1280, height = 720, bgcolor = Colors["#2b2b2b"]) { val view = korviView(views, resourcesVfs["video.mp4"]) + if (OS.isJs) { + val text = text("Click to start playing the video...") + mouse.click.once { + text.removeFromParent() + view.play() + } + } else { + view.play() + } } inline fun Container.korviView(views: Views, video: KorviVideo, callback: KorviView.() -> Unit = {}): KorviView = KorviView(views, video).also { addChild(it) }.also { callback(it) } -suspend inline fun Container.korviView(views: Views, video: VfsFile, callback: KorviView.() -> Unit = {}): KorviView = KorviView(views, video).also { addChild(it) }.also { callback(it) } -class KorviView(val views: Views, val video: KorviVideo, val stream: AsyncStream? = null) : Container(), AsyncCloseable, BaseKorviSeekable by video { +suspend inline fun Container.korviView(views: Views, video: VfsFile, autoPlay: Boolean = true, callback: KorviView.() -> Unit = {}): KorviView = KorviView(views, video, autoPlay).also { addChild(it) }.also { callback(it) } +class KorviView(val views: Views, val video: KorviVideo) : Image(Bitmaps.transparent), AsyncCloseable, BaseKorviSeekable by video { val onCompleted = Signal() var autoLoop = true companion object { - operator suspend fun invoke(views: Views, file: VfsFile): KorviView { - val stream = file.open() - return KorviView(views, KorviVideo(stream), stream) - } - } - - var running = true - val img = image(Bitmaps.transparent) - val audio = nativeSoundProvider.createAudioStream() - var elapsedTime: TimeSpan = 0.seconds - - private var videoLastFrame: KorviVideoFrame? = null - private val videoJob = views.launchImmediately { - while (true) { - delayFrame() - elapsedTime += 16.milliseconds - if (videoLastFrame == null) { - videoLastFrame = video.video.first().readFrame() - if (videoLastFrame == null) { - completed() - } - } - if (videoLastFrame != null && elapsedTime >= videoLastFrame!!.position) { - img.bitmap = videoLastFrame!!.data.slice() - videoLastFrame = null - } - } - } - private val audioJob = views.launchImmediately { - while (true) { - delayFrame() - for (n in 0 until 3) { - val frame = video.audio.first().readFrame() - if (frame != null) { - audio.add(frame!!.data) + suspend operator fun invoke(views: Views, file: VfsFile, autoPlay: Boolean = true): KorviView { + return KorviView(views, KorviVideo(file)).also { + if (autoPlay) { + it.video.play() } } } } - private suspend fun completed() { - running = false - onCompleted(Unit) - if (autoLoop) { - seek(0L) + val elapsedTime: TimeSpan get() = video.elapsedTime + val elapsedTimeHr: HRTimeSpan get() = video.elapsedTimeHr + + fun play() { + views.launchImmediately { + video.play() } } - override suspend fun seek(time: TimeSpan) { - video.seek(time) - elapsedTime = time - running = true - } - - override suspend fun seek(frame: Long) { - video.seek(frame) - running = true - //elapsedTime = null - } - - // @TODO: Autoclose - override suspend fun close() { - audio.stop() - video.close() - stream?.close() - videoJob.cancel() - audioJob.cancel() + init { + var n = 0 + video.onVideoFrame { + //println("VIDEO FRAME! : ${it.position.timeSpan}, ${it.duration.timeSpan}") + bitmap = it.data.slice() + n++ + //it.data.writeTo(tempVfs["image$n.png"], PNG) + //delayFrame() + } + video.onComplete { + views.launchImmediately { + if (autoLoop) { + seek(0L) + video.play() + } + } + } } }