Update KorVI with JS support

This commit is contained in:
soywiz
2020-06-12 21:34:46 +02:00
parent 76ada6e7b1
commit c0e2bc184c
4 changed files with 43 additions and 77 deletions

View File

@@ -106,7 +106,7 @@ class HelloScene : Scene() {
open class MyModule : Module() {
override val title: String = "KorGE - DragonBones"
override val mainScene: KClass<out Scene> = 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

View File

@@ -9,7 +9,7 @@ suspend fun main() = Korge(Korge.Config(module = MyModule))
object MyModule : Module() {
// define the opening scene
override val mainScene: KClass<out Scene> = MenuScene::class
override val mainScene = MenuScene::class
// define the game configs
override val title: String = "My Test Game"

View File

@@ -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")
}

View File

@@ -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<Unit>()
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()
}
}
}
}
}