pan lowest non-locked item
This commit is contained in:
@@ -2,6 +2,9 @@ package net.eksb.obsdc
|
||||
|
||||
import io.obswebsocket.community.client.OBSRemoteController
|
||||
import io.obswebsocket.community.client.message.event.ui.StudioModeStateChangedEvent
|
||||
import io.obswebsocket.community.client.message.request.RequestBatch
|
||||
import io.obswebsocket.community.client.message.request.sceneitems.GetSceneItemLockedRequest
|
||||
import io.obswebsocket.community.client.message.response.sceneitems.GetSceneItemLockedResponse
|
||||
import io.obswebsocket.community.client.model.Scene
|
||||
import io.obswebsocket.community.client.model.SceneItem.Transform
|
||||
import io.obswebsocket.community.client.model.SceneItem.Transform.TransformBuilder
|
||||
@@ -15,6 +18,8 @@ class Obs(private val q:BlockingQueue<Op>): AutoCloseable {
|
||||
|
||||
private val panAmount = 50F
|
||||
|
||||
private var alive = true
|
||||
|
||||
private val controller = OBSRemoteController.builder()
|
||||
.host("localhost")
|
||||
.port(4455)
|
||||
@@ -26,14 +31,16 @@ class Obs(private val q:BlockingQueue<Op>): AutoCloseable {
|
||||
.onClose { code -> log.error("closed:${code}")}
|
||||
.onControllerError { e -> log.error("controller error", e ) }
|
||||
.onCommunicatorError { e -> log.error("comm error", e ) }
|
||||
.onDisconnect { log.info("disconnected") }
|
||||
.onDisconnect {
|
||||
log.info("disconnected")
|
||||
if (alive) reconnect()
|
||||
}
|
||||
.and()
|
||||
.registerEventListener(StudioModeStateChangedEvent::class.java) {
|
||||
log.info("studio mode state change: ${it}")
|
||||
}
|
||||
.build()
|
||||
|
||||
private var alive = true
|
||||
|
||||
init {
|
||||
Runtime.getRuntime().addShutdownHook(thread(start=false) {
|
||||
@@ -43,6 +50,10 @@ class Obs(private val q:BlockingQueue<Op>): AutoCloseable {
|
||||
})
|
||||
}
|
||||
|
||||
private fun reconnect() {
|
||||
controller.connect()
|
||||
}
|
||||
|
||||
fun run() {
|
||||
controller.connect()
|
||||
}
|
||||
@@ -99,24 +110,53 @@ class Obs(private val q:BlockingQueue<Op>): AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
// Pan the bottom-most non-locked item.
|
||||
private fun pan(block:TransformBuilder.(Transform)->TransformBuilder) {
|
||||
controller.getCurrentProgramScene { response ->
|
||||
val sceneName = response.currentProgramSceneName
|
||||
log.info("scene name: ${sceneName}")
|
||||
controller.getSceneItemList(sceneName) { response ->
|
||||
val item = response.sceneItems.last()
|
||||
val itemId = item.sceneItemId
|
||||
log.info("last item id: ${itemId}")
|
||||
controller.getSceneItemTransform(sceneName, itemId) { response ->
|
||||
val transform = response.sceneItemTransform
|
||||
log.info("position: ${transform.positionX} x ${transform.positionY}")
|
||||
val newTransform = block(Transform.builder(), transform).build()
|
||||
controller.setSceneItemTransform(sceneName, itemId, newTransform) { response ->
|
||||
log.info("transform successful: ${response.isSuccessful}")
|
||||
// Have to set the current scene to take effect if in studio mode.
|
||||
controller.setCurrentProgramScene(sceneName) { response ->
|
||||
ready()
|
||||
val items = response.sceneItems
|
||||
// Even though locked status is in the response from OBS, the library does not parse it.
|
||||
// So we have to ask for it explicitly:
|
||||
controller.sendRequestBatch(
|
||||
RequestBatch.builder()
|
||||
.requests(
|
||||
response.sceneItems.map { item ->
|
||||
GetSceneItemLockedRequest.builder()
|
||||
.sceneName(sceneName)
|
||||
.sceneItemId(item.sceneItemId)
|
||||
.build()
|
||||
}
|
||||
)
|
||||
.build()
|
||||
) { response ->
|
||||
val item = response.data.results
|
||||
.map { result ->
|
||||
(result.responseData as GetSceneItemLockedResponse.SpecificData).sceneItemLocked
|
||||
}
|
||||
.zip(items)
|
||||
.asSequence()
|
||||
.filter { (locked,item) -> ! locked }
|
||||
.map { (locked,item) -> item }
|
||||
.sortedBy { item -> item.sceneItemIndex }
|
||||
.firstOrNull()
|
||||
log.info("item to pan: ${item?.sceneItemId}")
|
||||
if (item != null) {
|
||||
controller.getSceneItemTransform(sceneName, item.sceneItemId) { response ->
|
||||
val transform = response.sceneItemTransform
|
||||
log.info("position: ${transform.positionX} x ${transform.positionY}")
|
||||
val newTransform = block(Transform.builder(), transform).build()
|
||||
controller.setSceneItemTransform(sceneName, item.sceneItemId, newTransform) { response ->
|
||||
log.info("transform successful: ${response.isSuccessful}")
|
||||
// Have to set the current scene to take effect if in studio mode.
|
||||
controller.setCurrentProgramScene(sceneName) { response ->
|
||||
ready()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ready()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user