summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Rayhawk <jrayhawk@fairlystable.org>2022-11-23 22:31:01 -0800
committerJoe Rayhawk <jrayhawk@fairlystable.org>2022-11-23 22:31:01 -0800
commitf2abe19b4200741377611aa0e6ad717768cc0336 (patch)
treed62d49276936378eadfc666d28fa6a9403748482
parent8120b1079b821db37c0d763c2537c51b1f4df0d9 (diff)
downloadcrystal-obs-websocket-f2abe19b4200741377611aa0e6ad717768cc0336.tar.gz
crystal-obs-websocket-f2abe19b4200741377611aa0e6ad717768cc0336.zip
Separate out websocket async send() and blocking send_sync()
-rw-r--r--src/obswebsocket.cr133
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 )