summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/obswebsocket.cr84
1 files changed, 65 insertions, 19 deletions
diff --git a/src/obswebsocket.cr b/src/obswebsocket.cr
index dd00ec5..e4a1509 100644
--- a/src/obswebsocket.cr
+++ b/src/obswebsocket.cr
@@ -65,6 +65,9 @@ module OBS
class SourceMissingException < Exception
end
+ class StudioModeException < Exception
+ end
+
class ResponseDataMissingException < Exception
end
@@ -78,6 +81,7 @@ module OBS
@outputs : OBS::Outputs = OBS::Outputs.allocate
@video : OBS::VideoSettings = OBS::VideoSettings.allocate
@stats : OBS::Stats = OBS::Stats.allocate
+ @studiomode : Bool | Nil = nil
@eventsubs = Array( Tuple( Channel(JSON::Any), UInt32 ) ).new # convert this to Hash if anyone ever wants eventsub_remove()
@openrequests = Hash( String, Channel( JSON::Any ) ).new
@negotiated = false
@@ -90,6 +94,23 @@ module OBS
def closed?
return @closed
end
+ def studiomode : Bool
+ if @studiomode == nil
+ d = self.send_sync( OBS.req( "GetStudioModeEnabled" ) )
+ @studiomode = d["responseData"]["studioModeEnabled"].as_bool
+ end
+ @studiomode.not_nil!
+ end
+ def studiomode=( state : Bool ) : Bool
+ unless self.studiomode == state
+ d = self.send_sync( OBS.req( "SetStudioModeEnabled", JSON.parse( { "studioModeEnabled" => state }.to_json ) ) )
+ d["requestStatus"]["result"].as_bool && ( @studiomode = state )
+ end
+ return state
+ end
+ def studiomodecache=( state : Bool )
+ @studiomode = state
+ end
def eventsub_add( channel : Channel( JSON::Any ), mask : UInt32 = @eventmask )
unless @eventmask.bits_set?( mask )
@eventmask = @eventmask|( mask ) # bitwise OR
@@ -126,7 +147,11 @@ module OBS
return @stats
end
def transition!
- self.send_sync( OBS.req( "TriggerStudioModeTransition" ) )
+ if self.studiomode
+ self.send_sync( OBS.req( "TriggerStudioModeTransition" ) )
+ else
+ raise StudioModeException.new("Not currently in Studio Mode.")
+ end
end
def block_until_negotiated
unless @negotiated
@@ -246,18 +271,22 @@ module OBS
@scenecollection.currentcache( edata["sceneCollectionName"].as_s )
when "SceneCollectionListChanged"
@scenecollection.deletecache()
- # FIXME: Save requests by using the edata here
+ # We could probably save requests by using the edata here.
when "CurrentProfileChanging"
when "CurrentProfileChanged"
when "ProfileListChanged"
when "SceneListChanged"
- # FIXME
+ @scenes.deletecache
+ # We could probably save requests by using the edata here.
when "SceneCreated"
- # FIXME
+ @scenes.deletecache
+ # We could probably save requests by using the edata here.
when "SceneRemoved"
- # FIXME
+ @scenes.deletecache
+ # We could probably save requests by using the edata here.
when "SceneNameChanged"
- # FIXME
+ @scenes.deletecache
+ # We could probably save requests by using the edata here.
when "InputCreated"
edata = d["eventData"]
@inputs[edata["inputName"].to_s] = OBS::Input.new( self, edata )
@@ -282,12 +311,16 @@ module OBS
when "CurrentSceneTransitionChanged"
when "CurrentSceneTransitionDurationChanged"
when "StudioModeStateChanged"
+ edata = d["eventData"]
+ @studiomode = edata["studioModeEnabled"].as_bool
when "SceneTransitionStarted"
when "SceneTransitionEnded"
when "SceneTransitionVideoEnded"
when "SceneItemSelected"
when "SceneItemCreated"
- # FIXME
+ edata = d["eventData"]
+ @scenes[edata["sceneName"].to_s].deletecache()
+ # This could probably be made more efficient using the eventData
when "SceneItemRemoved"
edata = d["eventData"]
@scenes[edata["sceneName"].to_s].deletecache( edata["sceneItemId"].as_i64, edata["sourceName"].as_s )
@@ -295,7 +328,9 @@ module OBS
edata = d["eventData"]
@scenes[edata["sceneName"].as_s][edata["sceneItemId"].as_i64].enabledcache( edata["sceneItemEnabled"].as_bool )
when "SceneItemListReindexed"
- # FIXME
+ edata = d["eventData"]
+ @scenes[edata["sceneName"].to_s].deletecache()
+ # This could probably be made more efficient using the eventData
when "SceneItemLockStateChanged"
when "SceneItemTransformChanged"
edata = d["eventData"]
@@ -557,14 +592,18 @@ module OBS
@scenes_by_index = Array(String).new
@scenes = Hash(String, OBS::Scene).new
@program = String.new
- @preview = String.new
+ @preview : Nil | String = nil
def initialize( @obs : OBS::WebSocket )
end
def populate
d = @obs.send_sync( OBS.req( "GetSceneList" ) )
if ( rdata = d["responseData"]? )
@program = rdata["currentProgramSceneName"].as_s
- @preview = rdata["currentPreviewSceneName"].as_s
+ if @preview = rdata["currentPreviewSceneName"].as_s?
+ @obs.studiomodecache=true
+ else
+ @obs.studiomodecache=false
+ end
rdata["scenes"].as_a.each_with_index{ | scene, i |
name = scene["sceneName"].as_s
@scenes_by_index.push(name)
@@ -575,13 +614,6 @@ module OBS
end
return true
end
- def invalidate
- STDERR.puts( "SCENELIST THREAD: scenes invalidated" )
- @scenes_by_index = Array(String).new
- @scenes = Hash(String, OBS::Scene).new
- @program = String.new
- @preview = String.new
- end
def programcache( v : String )
@program = v
end
@@ -593,8 +625,12 @@ module OBS
@preview = v
end
def preview
- @preview.empty? && populate()
- @scenes[@preview]
+ @preview || populate()
+ if @preview
+ return @scenes[@preview]
+ else
+ return @preview
+ end
end
def current
@program.empty? && populate
@@ -735,6 +771,7 @@ module OBS
end
def preview!
# we get weird behavior on transitions unless we block here
+ @obs.studiomode || @obs.send_sync( OBS.req( "SetStudioModeEnabled", JSON.parse( { "studioModeEnabled" => true }.to_json ) ) )
@obs.send_sync( OBS.req( "SetCurrentPreviewScene", JSON.parse( { "sceneName" => @name }.to_json ) ) )
end
def createinput( iname : String, kind : String, settings : OBS::InputSettings | Hash( String, String | Bool | Int64 | Float64 ) | Nil = nil, enabled : Bool = true )
@@ -854,6 +891,15 @@ module OBS
@last_known_real_transform = Hash( String, OBS::SceneItemTransform ).new
def initialize( @obs : OBS::WebSocket )
end
+ def []( index : String ) : OBS::Scene | OBS::Input
+ if @obs.inputs[index]?
+ return @obs.inputs[index]
+ elsif @obs.scenes[index]?
+ return @obs.scenes[index]
+ else
+ raise IndexError.new("Source unknown.")
+ end
+ end
def []?( index : String ) : OBS::Scene | OBS::Input | Nil
if @obs.inputs[index]?
return @obs.inputs[index]