diff options
-rwxr-xr-x | crystal/bullshit.cr | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/crystal/bullshit.cr b/crystal/bullshit.cr new file mode 100755 index 0000000..9feb24d --- /dev/null +++ b/crystal/bullshit.cr @@ -0,0 +1,143 @@ +require "obswebsocket" +require "pretty_print" +require "math" + +STDOUT.sync = true +STDOUT.flush_on_newline = true + +struct Nil + def as_s? + self + end +end + +settings = Hash(String, String).new + +settings["configdir"] = Path.home./("/.config/bungmobott/").to_s +settings["statedir"] = Path.home./("/.local/state/bungmobott/").to_s + +if ENV["LOCALAPPDATA"]? + settings["configdir"] = Path.windows( ENV["LOCALAPPDATA"] + "\\bungmobott\\" ).to_s + settings["statedir"] = Path.windows( ENV["LOCALAPPDATA"] + "\\bungmobott\\state\\" ).to_s +end + +settings["tempdir"] = "/tmp/bungmobott/" +ENV["TEMP"]? && ( settings["tempdir"] = "#{ENV["TEMP"]}\\bungmobott\\" ) + +ENV["XDG_CONFIG_HOME"]? && ( settings["configdir"] = ENV["XDG_CONFIG_HOME"] + "/bungmobott/" ) +#ENV["XDG_DATA_HOME"]? && ( settings["datadir"] = ENV["XDG_DATA_HOME"] ) # unused? +ENV["XDG_STATE_HOME"]? && ( settings["statedir"] = ENV["XDG_STATE_HOME"] + "/bungmobott/" ) + +Dir.mkdir_p( settings["configdir"] ) +Dir.mkdir_p( settings["statedir"] ) +Dir.mkdir_p( settings["tempdir"] ) + +settings["home"] = Path.home.to_s +regextwitchuser = /^[0-9a-zA-Z_]+$/ + +obs = OBS::WebSocket.new( "ws://127.0.0.1:4455/" ) +directions = Hash( String, Float64 ).new + +# OBS event thread +spawn do + evchan = Channel( JSON::Any ).new + obs.eventsub_add( evchan ) + while json = evchan.receive + # A Fiber.yield occurs after this to make sure "json" doesn't get overwritten before we can use it. + spawn do + d = json # Copy *immediately* + case d["eventType"].as_s + when "SceneItemTransformChanged" + edata = d["eventData"] + puts "test 1" + scenelist = obs.scenes[edata["sceneName"].as_s] + puts "test 2" + sceneitem = scenelist[edata["sceneItemId"].as_i64] + puts "test 3" + t = edata["sceneItemTransform"] + if ( direction = directions[sceneitem.name]? ) + spx = t["positionX" ].as_f.to_i64 + spy = t["positionY" ].as_f.to_i64 + sdx = t["sourceHeight"].as_f.to_i64 + sdy = t["sourceWidth" ].as_f.to_i64 + bx = obs.video.to_h["baseWidth" ].as(Int64 | Float64).to_i64 + by = obs.video.to_h["baseHeight"].as(Int64 | Float64).to_i64 + abx = bx - sdx + aby = by - sdy + ratio = Math.tan(direction) + spxr = (aby/2 * ratio).abs + if spxr > abx/2 + spxr = abx/2 + spyr = abx/2 * ratio + elsif ratio > 0 + spyr = abx/2 + else # ratio < 0 + spyr = abx/2 * -1 + end + if ( direction >= 0 ) && ( direction <= Math::PI ) + nspx = spxr + else # ( direction >= Math::PI ) && ( direction <= 2*Math::PI ) + nspx = ( spxr * -1 ) + end + nspx = nspx - sdx + nspy = spyr - sdy + unless ( spx == nspx && spy == nspy ) + sceneitem.transform( { "positionX" => nspx, "positionY" => nspy } ) + end + end + end + end + Fiber.yield + end +end + +def obsrandommediaenable( obs : OBS::WebSocket, siname : String ) + if ( Random.rand(3) < 2 ) + obs.scenes.current.metascene[siname][0].enable! + else + randsiname = obs.scenes.current.metascene.keys.select( /^#{siname}/ ).sample( 1 )[0] + obs.scenes.current.metascene[randsiname][0].enable! + end +end + +name=ARGV[0].sub( /.+\//, "" ).sub( /\..+/, "" ) + +def obsmediacreate( obs : OBS::WebSocket, sname : String, iname, path : String ) + iname = "medialoop-bullshit-#{iname}" + isettings = Hash( String, String | Bool | Int64 | Float64 ){ + "advanced" => true, + "clear_on_media_end" => true, + "color_range" => 0.to_i64, + "is_local_file" => true, + "looping" => true, + "restart_on_activate" => true, + "local_file" => path, + } + response = obs.scenes[sname].createinput( iname, "ffmpeg_source", isettings ) + # Skip object model stuff and configure the SceneItem as fast as we possibly can + if ( rdata = response["responseData"]? ) && ( goodtransform = obs.sources.last_known_real_transform?( iname ) ) + siid = rdata["sceneItemId"].as_i64 + ENV["DISTANCE"] # percent + ENV["DIRECTION"] # degrees + ENV["SIZE"] # width\nheight + ENV["COLORMASK"] # color/RGB(A) html color code +# obs.send_sync( OBS.req( "SetSceneItemTransform", JSON.parse( { "sceneName" => sname, "sceneItemId" => siid, "sceneItemTransform" => { "positionX" => goodtransform.to_h["positionX"], "positionY" => goodtransform.to_h["positionY"] } }.to_json ) ) ) + end + if ( colormask = ENV["COLORMASK"].to_u32 ) + obs.send_sync( OBS.req( "CreateSourceFilter", JSON.parse( { "sourceName" => iname, "filterName" => "chromakey", "filterKind" => "chroma_key_filter_v2", "filterSettings" => { "key_color_type" => "custom", "key_color" => colormask, "smoothness" => 10, "similarity" => "1" } }.to_json ) ) ) + #obs.send_sync( OBS.req( "CreateSourceFilter", JSON.parse( { "sourceName" => iname, "filterName" => "colorkey", "filterKind" => "color_key_filter_v2", "filterSettings" => { "key_color_type" => "custom", "key_color" => colormask, "smoothness" => 1000 } }.to_json ) ) ) + end +end + +# white: 4294967296 + +if ( direction = ENV["DIRECTION"].to_u16 ) + directions[name] = Math::PI/180*direction +else + directions[name] = Math::PI/180*rand(360) +end + +obsmediacreate( obs, "meta-bullshit", name, ARGV[0] ) + +sleep 2 +Fiber.yield |