diff options
Diffstat (limited to 'src/obswebsocket.cr')
-rw-r--r-- | src/obswebsocket.cr | 133 |
1 files changed, 30 insertions, 103 deletions
diff --git a/src/obswebsocket.cr b/src/obswebsocket.cr index 95fe63a..5f6e995 100644 --- a/src/obswebsocket.cr +++ b/src/obswebsocket.cr @@ -40,7 +40,7 @@ module OBS ORMCritical = Scenes|Inputs| Filters|Outputs|SceneItems|SceneItemTransformChanged end - def req( type : String, id : String, data : ( String | Nil | JSON::Any ) = nil ) + def req( type : String, id : String = UUID.random.to_s, data : ( String | Nil | JSON::Any ) = nil ) request = JSON.build do |json| json.object do json.field "op", 6 @@ -125,11 +125,9 @@ module OBS return @stats end def transition! - reschan = Channel( JSON::Any ).new - send( reschan, OBS.req( "TriggerStudioModeTransition", UUID.random.to_s ) ) - return reschan.receive + self.send_sync( OBS.req( "TriggerStudioModeTransition" ) ) end - # request channel, response channel + # Asynchronous send def send( json : String ) unless @negotiated @negotiationdelayqueue += 1 @@ -142,53 +140,20 @@ module OBS STDERR.puts( "SENT: #{JSON.parse(json).pretty_inspect}" ) @websocket && @websocket.not_nil!.send( json ) end - def send( reschan : ( Channel( JSON::Any ) | Nil ), json : String ) + # Block until response + def send_sync( json : String ) unless @negotiated @negotiationdelayqueue += 1 negotiationresult = @negotiationdelay.receive if negotiationresult.is_a?( Exception ) raise negotiationresult end - @negotiated || return false # not sure why this condition would occur without an exception end + reschan = Channel( JSON::Any ).new STDERR.puts( "SENT: #{JSON.parse(json).pretty_inspect}" ) - @websocket && @websocket.not_nil!.send( json ) @openrequests[ JSON.parse( json )["d"]["requestId"].as_s ] = reschan - # maybe process reschan.receive here? - end - def request( type : String, id : String, data : ( String | Nil | JSON::Any ) = nil ) - request = JSON.build do |json| - json.object do - json.field "op", 6 - json.field "d" do - json.object do - json.field "requestType", type - json.field "requestId", id - if data - json.field "requestData", data - end - end - end - end - end - self.send( request.to_s ) - end - def request( reschan : ( Channel( JSON::Any ) | Nil ), type : String, id : String, data : ( String | Nil | JSON::Any ) = nil ) - request = JSON.build do |json| - json.object do - json.field "op", 6 - json.field "d" do - json.object do - json.field "requestType", type - json.field "requestId", id - if data - json.field "requestData", data - end - end - end - end - end - self.send( reschan, request.to_s ) + @websocket && @websocket.not_nil!.send( json ) + return reschan.receive end def initialize( uri : String, password : String | Nil = nil, retry : Bool = true, @eventmask : UInt32 = @eventmask ) @scenecollection.initialize( self ) @@ -442,9 +407,7 @@ module OBS def initialize( @obs : OBS::WebSocket ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetOutputList", UUID.random.to_s ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetOutputList" ) ) if ( rdata = d["responseData"]? ) STDERR.print( "OUTPUTS THREAD: " ) STDERR.print( rdata.pretty_inspect ) @@ -483,9 +446,7 @@ module OBS def initialize( @obs : OBS::WebSocket, @name : String ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetOutputStatus", UUID.random.to_s, JSON.parse( { "outputName" => @name }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetOutputStatus", data: JSON.parse( { "outputName" => @name }.to_json ) ) ) if ( rdata = d["responseData"]? ) @age = Time.utc.to_unix @status = Hash(String, String | Bool | Int64 | Float64 ).from_json(rdata.to_json) @@ -510,9 +471,7 @@ module OBS def initialize( @obs : OBS::WebSocket ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetVideoSettings", UUID.random.to_s ) ) - d = reschan.receive + d = @obs.send_sync( reschan, OBS.req( "GetVideoSettings" ) ) if ( rdata = d["responseData"]? ) @settings = Hash(String, String | Bool | Int64 | Float64 ).from_json(rdata.to_json) else @@ -539,9 +498,7 @@ module OBS def initialize( @obs : OBS::WebSocket ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetStats", UUID.random.to_s ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetStats" ) ) if ( rdata = d["responseData"]? ) @stats = Hash(String, String | Bool | Int64 | Float64 ).from_json(rdata.to_json) @age = Time.utc.to_unix @@ -568,9 +525,7 @@ module OBS @inputs = @obs.inputs end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetSceneCollectionList", UUID.random.to_s ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetSceneCollectionList" ) ) if ( rdata = d["responseData"]? ) @current = rdata["currentSceneCollectionName"].as_s rdata["sceneCollections"].as_a.each{ | scenecollection | @@ -608,9 +563,7 @@ module OBS def initialize( @obs : OBS::WebSocket ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetSceneList", UUID.random.to_s ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetSceneList" ) ) if ( rdata = d["responseData"]? ) @program = rdata["currentProgramSceneName"].as_s @preview = rdata["currentPreviewSceneName"].as_s @@ -687,9 +640,7 @@ module OBS @filters = OBS::SourceFilters.new( @obs, @name ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetSceneItemList", UUID.random.to_s, JSON.parse( { "sceneName" => @name }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetSceneItemList", data: JSON.parse( { "sceneName" => @name }.to_json ) ) ) if ( rdata = d["responseData"]? ) # handle "sourceType": "OBS_SOURCE_TYPE_SCENE" rdata["sceneItems"].as_a.each_with_index{ | item, i | @@ -781,14 +732,12 @@ module OBS program! end def program! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetCurrentProgramScene", UUID.random.to_s, JSON.parse( { "sceneName" => @name }.to_json ) ) ) - reschan.receive # we get weird behavior on transitions unless we block here + # we get weird behavior on transitions unless we block here + @obs.send_sync( OBS.req( "SetCurrentProgramScene", data: JSON.parse( { "sceneName" => @name }.to_json ) ) ) end def preview! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetCurrentPreviewScene", UUID.random.to_s, JSON.parse( { "sceneName" => @name }.to_json ) ) ) - reschan.receive # we get weird behavior on transitions unless we block here + # we get weird behavior on transitions unless we block here + @obs.send_sync( OBS.req( "SetCurrentPreviewScene", data: 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 ) reqdata = ( Hash( String, String | Bool | Int64 | Float64 | Hash( String, String | Bool | Int64 | Float64 ) ) ).new @@ -802,9 +751,7 @@ module OBS reqdata["sceneItemEnabled"] = false end - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "CreateInput", UUID.random.to_s, JSON.parse(reqdata.to_json) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "CreateInput", data: JSON.parse(reqdata.to_json) ) ) # maybe block until the event comes in? # will have to depend on the @eventsubscription state if d["requestStatus"]["result"].as_bool # success? @@ -865,23 +812,17 @@ module OBS end end def enable! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetSceneItemEnabled", UUID.random.to_s, JSON.parse( { "sceneName" => @scenename, "sceneItemId" => @id, "sceneItemEnabled" => true }.to_json ) ) ) - d = reschan.receive # block until response + @obs.send_sync( OBS.req( "SetSceneItemEnabled", data: JSON.parse( { "sceneName" => @scenename, "sceneItemId" => @id, "sceneItemEnabled" => true }.to_json ) ) ) end def disable! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetSceneItemEnabled", UUID.random.to_s, JSON.parse( { "sceneName" => @scenename, "sceneItemId" => @id, "sceneItemEnabled" => false }.to_json ) ) ) - d = reschan.receive # block until response + @obs.send_sync( OBS.req( "SetSceneItemEnabled", data: JSON.parse( { "sceneName" => @scenename, "sceneItemId" => @id, "sceneItemEnabled" => false }.to_json ) ) ) end def transform( newtransform : OBS::SceneItemTransform | Hash( String, String | Bool | Int64 | Float64 ) ) reqdata = ( Hash( String, String | Bool | Int64 | Float64 | Hash( String, String | Bool | Int64 | Float64 ) ) ).new reqdata["sceneItemId"] = @id.to_i64 reqdata["sceneName"] = @scenename reqdata["sceneItemTransform"] = Hash( String, String | Bool | Int64 | Float64).new.merge( newtransform.to_h ) - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetSceneItemTransform", UUID.random.to_s, JSON.parse(reqdata.to_json) ) ) - d = reschan.receive + @obs.send_sync( OBS.req( "SetSceneItemTransform", data: JSON.parse(reqdata.to_json) ) ) end end @@ -891,9 +832,7 @@ module OBS @sceneitemtransform = Hash(String, String | Bool | Int64 | Float64 ).from_json(json.to_json) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetSceneItemTransform", UUID.random.to_s, JSON.parse( { "sceneName" => @sceneitemname, "sceneItemId" => @sceneitemid }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetSceneItemTransform", data: JSON.parse( { "sceneName" => @sceneitemname, "sceneItemId" => @sceneitemid }.to_json ) ) ) if ( rdata = d["responseData"]? ) @sceneitemtransform = Hash(String, String | Bool | Int64 | Float64 ).from_json(rdata["sceneItemTransform"].to_json) else @@ -945,9 +884,7 @@ module OBS def initialize( @obs : OBS::WebSocket ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetInputList", UUID.random.to_s) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetInputList") ) if ( rdata = d["responseData"]? ) rdata["inputs"].as_a.each{ | input | @inputs[input["inputName"].as_s] = OBS::Input.new( @obs, input ) @@ -996,9 +933,7 @@ module OBS @filters = OBS::SourceFilters.new( @obs, @name ) end def delete!( ) - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "RemoveInput", UUID.random.to_s, JSON.parse({ "inputName" => @name }.to_json) ) ) - d = reschan.receive + @obs.send_sync( OBS.req( "RemoveInput", data: JSON.parse({ "inputName" => @name }.to_json) ) ) end def namecache( name : String ) @name = name @@ -1019,9 +954,7 @@ module OBS def initialize( @obs : OBS::WebSocket, @name : String, @inputkind : String, @inputsettings : Hash( String, String | Bool | Int64 | Float64 ) ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetInputSettings", UUID.random.to_s, JSON.parse( { "inputName" => @name }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetInputSettings", data: JSON.parse( { "inputName" => @name }.to_json ) ) ) if ( rdata = d["responseData"]? ) @inputsettings = Hash(String, String | Bool | Int64 | Float64 ).from_json(rdata["inputSettings"].to_json) @inputkind = rdata["inputKind"].as_s @@ -1053,9 +986,7 @@ module OBS def initialize( @obs : OBS::WebSocket, @sourcename : String ) end def populate - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "GetSourceFilterList", UUID.random.to_s, JSON.parse( { "sourceName" => @sourcename }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "GetSourceFilterList", data: JSON.parse( { "sourceName" => @sourcename }.to_json ) ) ) if ( rdata = d["responseData"]? ) rdata["filters"].as_a.each do | filter | name = filter["filterName"].as_s @@ -1105,15 +1036,11 @@ module OBS end end def enable! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetSourceFilterEnabled", UUID.random.to_s, JSON.parse( { "sourceName" => @sourcename, "filterName" => @name, "filterEnabled" => true }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "SetSourceFilterEnabled", data: JSON.parse( { "sourceName" => @sourcename, "filterName" => @name, "filterEnabled" => true }.to_json ) ) ) return d["requestStatus"]["result"].as_bool end def disable! - reschan = Channel( JSON::Any ).new - @obs.send( reschan, OBS.req( "SetSourceFilterEnabled", UUID.random.to_s, JSON.parse( { "sourceName" => @sourcename, "filterName" => @name, "filterEnabled" => false }.to_json ) ) ) - d = reschan.receive + d = @obs.send_sync( OBS.req( "SetSourceFilterEnabled", data: JSON.parse( { "sourceName" => @sourcename, "filterName" => @name, "filterEnabled" => false }.to_json ) ) ) return d["requestStatus"]["result"].as_bool end def enabledcache( bool : Bool ) |