Advanced Scene Switcher

Advanced Scene Switcher 1.28.1

AaronD

Active Member
I'm also thinking about moving the different audio mixes in the Master for each of my "types" of scene, out of the scenes and into the global settings so that the scenes themselves *only* have to include the visuals, and then automating the audio fade-ins and -outs using a similar bit of logic as what I'm presently trying to have in the Slave. If I do *that*, then the regex on the scene name (or whatever method I end up using) would have to be in the *Master* macros, and since the audio fade actions need constant values anyway, I'll be in a perfect position to send a constant-string WebSocket message to the Slave.

I'm not at the machine at the moment to see if I can have a regex on the local current scene name. If so, then I *might* be home free with what exists already.
I finally got to try it, and no, I can't have a regex on the local current scene name. Not with with version 1.19.2 anyway.

There's a drop-down for the current scene, which of course doesn't do regex.
The Variables do support regex, but they don't have environment stuff yet.
 

AaronD

Active Member
(if I can also get a WS message from one instance to another on the same machine, when they insist on using the same server settings)
That one DOES work, using Adv. SS on both ends. At first, I just set up some hotkeys in the Master to brute-force it, and the Slave did change scenes. So that part is good.

And I eventually got a complete system to work. It's a bit hokey, but it does work. Turns out that only the first instance of OBS gets connected to the WebSocket server, so I can't talk directly to the second one, but a later instance of Adv. SS can still connect to the first one and see its Events. So:
  1. A reworked Python script (using a different module because OBS 28 uses an updated, incompatible protocol) connects to both Events and Requests, both of which can only see the Master, and registers itself for the "CurrentProgramSceneChanged" event.
  2. OBS Master changes scenes.
  3. The Python callback function for the "CurrentProgramSceneChanged" event does the regexes on the scene name and sends a "CallVendorRequest" with the appropriate message for Adv. SS to pick up.
  4. Master Adv. SS has a macro for each Request (no regex required at this point) that:
    • Sends a matching Event.
    • Fades the global audio sources.
  5. Slave Adv. SS has a macro for each Event, that switches to the corresponding scene.
Whew! It'd sure be nice to clean up the Rube Goldberg a bit, but it does at least WORK now!



The reworked python script is:
Python:
#!/usr/bin/env python

import re
import sys
import subprocess

import obsws_python as obs

try:
    OBS_Event = obs.EventClient(host="localhost", port=4455, password="NotTheRealPassword!")
except:
    print("Error: Could not connect to OBS Event")
    sys.exit(-1)

try:
    OBS_Request = obs.ReqClient(host="localhost", port=4455, password="NotTheRealPassword!")
except:
    print("Error: Could not connect to OBS Request")
    sys.exit(-2)



def on_current_program_scene_changed(data):
    name = data.scene_name
    message = ""
    if re.match("^Camera.*$", name):
        message = "Camera"
    if re.match("^Feature.*$", name):
        message = "Feature"
    if re.match("^Voiceover.*$", name):
        message = "Voiceover"
    if (message != ""):
        OBS_Request.call_vendor_request(vendor_name="AdvancedSceneSwitcher", request_type="AdvancedSceneSwitcherMessage", request_data={"message": message})

OBS_Event.callback.register(on_current_program_scene_changed)



# Expect a dialog command and message, to be passed as arguments to this script
# Closing the dialog is taken as a shutdown command, so this doesn't return until then
if (len(sys.argv) > 1):
    subprocess.run(sys.argv[1:])
else:
    subprocess.run(["zenity", "--info", "--width=350", "--title=Testing", "--text=Click OK to disconnect."])

sys.exit(0)

And the macros:

Master:
1669517837119.png

Slave:
1669517905775.png
 

ukie

Member
After updating to OBS 28 and ASS 1.19.2 on Mac (10.15.7), I can't run any applescripts with "Run".

Screen Shot 2022-11-28 at 1.44.12 PM.png



They worked on prior version of OBS and ASS, but now, I keep getting the error:
The action "run applescript" encountered an error not authorized to send apple events to...
Screen Shot 2022-11-28 at 1.45.23 PM.png


The applescript application does run on its own, but not through ASS anymore.
Tried all levels of permissions under Security&Pravacy, to no avail.
Screen Shot 2022-11-28 at 1.48.28 PM.png

Screen Shot 2022-11-28 at 1.48.18 PM.png

Screen Shot 2022-11-28 at 1.48.06 PM.png


This is the case for all applescript apps, not just the Moom example above.
 

ukie

Member
After updating to OBS 28 and ASS 1.19.2 on Mac (10.15.7), I can't run any applescripts with "Run".

View attachment 89232


They worked on prior version of OBS and ASS, but now, I keep getting the error:
The action "run applescript" encountered an error not authorized to send apple events to...
View attachment 89228

The applescript application does run on its own, but not through ASS anymore.
Tried all levels of permissions under Security&Pravacy, to no avail.
View attachment 89229
View attachment 89230
View attachment 89231

This is the case for all applescript apps, not just the Moom example above.
Just saw @Kenshin9977 issue. Looks like this is the same issue just on a Mac. @Warmuptill is there a hidden app that runs to initiate the RUN sequence that needs additional permission?
 

Dustin D

New Member
If you make the ad into its own scene or source, yes. No different from anything else at that point.

Typing in chat might require a third party app or script, that is triggered using the Run action in a macro. That takes a single command line, that is passed to your operating system as if you typed it in a terminal, except that it necessarily inherits its environment from OBS, which is a little bit different than if you used the terminal to do it. Absolute paths, or some trickery in a script that is called directly and then does the thing you want, are needed to break out of that...but some things work just fine regardless of their environment, so you may not have to break out. Try it and see.
Well, I got a stream deck and it allows me to just push a button to run an ad. It would be nice if someone developed something for this.
 

Warmuptill

Active Member
Just saw @Kenshin9977 issue. Looks like this is the same issue just on a Mac. @Warmuptill is there a hidden app that runs to initiate the RUN sequence that needs additional permission?
The problem mentioned in this post was Windows specific and relating to the current working directory of the process.
So I don't believe the problems are related.

After updating to OBS 28 and ASS 1.19.2 on Mac (10.15.7), I can't run any applescripts with "Run".

View attachment 89232


They worked on prior version of OBS and ASS, but now, I keep getting the error:
The action "run applescript" encountered an error not authorized to send apple events to...
View attachment 89228

The applescript application does run on its own, but not through ASS anymore.
Tried all levels of permissions under Security&Pravacy, to no avail.
View attachment 89229
View attachment 89230
View attachment 89231

This is the case for all applescript apps, not just the Moom example above.
Seems like a special set of permissions is required since macOS 10.14+.
I will try to look into how those could be granted.
 

KiraRedpaw

New Member
So I know its been awhile since I posted here with my issues with the new version of OBS 28 and advanced scene switcher 1.91 but I've been using this time to try some things out. Good news I got my macro to work for changing the scene once the audio ends. Bad news is I can only get one macro to work at a time. If I enable more then one then they try to all run at the same time and sometimes they just outright dont work. Like at soon as I open OBS they will try to all play instantly even though none of the conditions have been met like Run when I start streaming which you cant do unless you are streaming...its weird. Maybe there is a simple checkbox that I haven't checked. Anyone want to help me out. Attached are pics of my current settings.

Remember I can get one to run but not more then one.

I have End and Stop turned off because of the issues I described above.
 

Attachments

  • 4.PNG
    4.PNG
    35.9 KB · Views: 23
  • 3.PNG
    3.PNG
    40.5 KB · Views: 22
  • 2.PNG
    2.PNG
    40.1 KB · Views: 22
  • 1.PNG
    1.PNG
    40.9 KB · Views: 21

AaronD

Active Member
If I enable more then one then they try to all run at the same time and sometimes they just outright dont work. Like at soon as I open OBS they will try to all play instantly even though none of the conditions have been met like Run when I start streaming which you cant do unless you are streaming...its weird. Maybe there is a simple checkbox that I haven't checked. Anyone want to help me out. Attached are pics of my current settings.
Have you tried "Perform actions only on condition change"? I wonder if without that, the logic is "at least 30 seconds" instead of "exactly 30 seconds". So all of them are trying to run all the time and cancelling each other. I pretty much always have that checked because it matches the way I think of things.

Or it could be that you're set to not run the switcher at all on OBS startup. I'm guessing you did that on purpose though, to keep it from going nuts.
 

KiraRedpaw

New Member
Have you tried "Perform actions only on condition change"? I wonder if without that, the logic is "at least 30 seconds" instead of "exactly 30 seconds". So all of them are trying to run all the time and cancelling each other. I pretty much always have that checked because it matches the way I think of things.

Or it could be that you're set to not run the switcher at all on OBS startup. I'm guessing you did that on purpose though, to keep it from going nuts.
What would a condition change be? like the end of a song or the start of the stream? What is the condition?
 

AaronD

Active Member
What would a condition change be? like the end of a song or the start of the stream? What is the condition?
Each item in the list of things to watch for, is a condition.

Instead of executing continuously for the entire time that the condition is true, it would only execute once when the condition becomes true. When the condition goes false and then true again, it executes once again, etc.
 

AaronD

Active Member
It'd sure be nice to clean up the Rube Goldberg a bit, but it does at least WORK now!

Master:
View attachment 89153
Slave:
View attachment 89154

Arron,
I found a workaround for this, by managing the global.ini file and changing the port number before launching each instances of OBS.
Not ideal, but it works.

Thanks to Jay in a different thread, I did clean it up a *little* bit, at least as far as a user would see. My setup/teardown bash script handles the global.ini juggling, and the interconnection python script now commands both instances of OBS directly:

Python:
message="Feature"
OBS_Master_Request.call_vendor_request(vendor_name="AdvancedSceneSwitcher", request_type="AdvancedSceneSwitcherMessage", request_data={"message": message})
OBS_Slave_Request.set_current_program_scene(message)

The Slave instance no longer needs any macros at all, and the Master no longer sends the WS event. So it's also down to only the functions that it actually needs for itself.

Still a bit Rube-Goldbergy overall, if you include the global.ini juggling, but I do like this version a lot better. Now I just need to fix up the timing so that the local mics never get into the local speakers during the transitions. That's probably also done better in the python script because sometimes the Master needs to be first and sometimes the Slave needs to be first.
 

AaronD

Active Member
I know I've been back and forth across the fence on this, but having seen it this way for a while, I think I do want to get rid of the python script and the global.ini juggling. It does put more work onto the macros, which are slightly more user-accessible than the scripts are, but I don't think my users are going to get there anyway.

I think the only obstacle to that would be a regex on the Current Scene. Is there a release coming up that includes that? Thanks!
 

Warmuptill

Active Member
So I know its been awhile since I posted here with my issues with the new version of OBS 28 and advanced scene switcher 1.91 but I've been using this time to try some things out. Good news I got my macro to work for changing the scene once the audio ends. Bad news is I can only get one macro to work at a time. If I enable more then one then they try to all run at the same time and sometimes they just outright dont work. Like at soon as I open OBS they will try to all play instantly even though none of the conditions have been met like Run when I start streaming which you cant do unless you are streaming...its weird. Maybe there is a simple checkbox that I haven't checked. Anyone want to help me out. Attached are pics of my current settings.

Remember I can get one to run but not more then one.

I have End and Stop turned off because of the issues I described above.
The problem of the some of the macros immediately firing after starting to stream is caused by the fact that the scene switcher does not properly reset the duration modifiers you can add to condition when stopping the plugin.

So if the plugin is running, then stopped, and finally started up again the timers of the duration modifiers will compare the time between "stopped" and "finally started" instead of restarting from zero. (Hope that was worded somewhat coherent)

I have adjusted this behaviour in this build:
(Note you need to be logged into GitHub to be able to download it)


A few notes regarding your setup:
  • I think you can remove the "Stop" macro entirely and simply add the action to stop the stream to the "End" macro.
  • Your "Start" and "End" macro conditions could be true at the same time.
    I assume that you will not be playing either the "Starting music" or "Ending music" continuously, so you can run into the situation of both macros being executed at the same time.
  • The audio conditions checking if the volume of a particular source is below a certain threshold can and will be true even if the the audio source is not part of the currently active scene.
    So for example if you "Gaming" scene does not contain an instance of the "Ending music" source the "End" macro might still be executed.
    So you could add an additional condition checking if the audio source is currently showing on a particular scene.
Without really knowing your setup I would suggest to rework your "End" and "Start" macro to something similar to this:

Start.PNG

End.PNG


You can of course adjust the "is showing" source condition with something that fits better to your setup. (E.g. checking if the current scene is / is not "Scene XYZ")

Hope that helps!
Let me know if you have any questions! :)
 

Warmuptill

Active Member
I think the only obstacle to that would be a regex on the Current Scene. Is there a release coming up that includes that? Thanks!
Sure, that shouldn't be too difficult.

ScenePattern.PNG


A first version can be found here in a few minutes:
(As usual you need to be logged into GitHub to be able to download this build)

Let me know if that works for you! :)
 

AaronD

Active Member
Sure, that shouldn't be too difficult.

View attachment 89402

A first version can be found here in a few minutes:
(As usual you need to be logged into GitHub to be able to download this build)

Let me know if that works for you! :)
It does! Thank you!

I had a little bit of trouble with what looked like the WebSocket Event not getting from Master to Slave, but a quick reboot and check again was okay. So I'll have to see if that persists.



A couple more questions:

It's been discussed before, but it's been a while. Is there a better way to do a startup initialization that never runs again?
The idea here is to wait until the Slave is also started, and then trigger the normal automation to set things right. Or if the Slave isn't running for a particular configuration, that's fine too.

1670100777090.png


Does the extra "Scene Changed" condition here make any difference at all? I figured it might be a slight optimization so it's not running the regex all the time, but is it really?:
1670100662472.png

Don't know if it makes a difference in the answers, but I have both Master and Slave running as fast as they'll go - 50ms - to try and approximate "instant". That is, from a hotkey in the Master that switches scenes, to the Slave switching scenes:
1670101506191.png
 
Last edited:

Warmuptill

Active Member
It's been discussed before, but it's been a while. Is there a better way to do a startup initialization that never runs again?
Using the "plugin is running" with a duration modifier "for exactly 0 seconds" should do the trick.

Does the extra "Scene Changed" condition here make any difference at all? I figured it might be a slight optimization so it's not running the regex all the time, but is it really?:
The second condition is still checked regardless.

Is the scene switcher using a considerable amount of CPU time in your setup? (Can be checked by comparing OBS CPU usage with the plugin stopped / started).
 

AaronD

Active Member
Using the "plugin is running" with a duration modifier "for exactly 0 seconds" should do the trick.
Okay. What I posted seems to work too, probably because of the "edge-detect button" as I think of it. I was just wondering what the "best practice" was, if there is one.

Low priority, but how hard would it be to make an obvious "run once at startup" function? My first thought was a separate section that had all of the actions available but no conditions, and that's when it runs, but far more flexible might just be a dedicated condition that is true between startup and the first time its actions are executed, and never again. Then it could be combined with other conditions to delay the "init code" until it can actually work (init AND something else), or to repeat the "init code" without copying it (init OR something else).

It might even replace the "plugin running" condition, since it seems silly to me to have a condition that always returns true. In a loop, yes, I can see a boolean constant to run that loop forever, and I've also used "if(false)" to (temporarily!) disable a section of code (it's also easily searchable). But neither of those are relevant here, as there are no loops and there's already a dedicated disable button.

The second condition is still checked regardless.

Is the scene switcher using a considerable amount of CPU time in your setup? (Can be checked by comparing OBS CPU usage with the plugin stopped / started).
Good to know. So it's not doing the "short-circuit" logic that most other languages do, where only the first condition is always checked, and each one after that is only checked if it still makes a difference.

This entire system barely registers on my CPU meter, but my experience with 8-bit microcontrollers (lots of projects with a single core @ 20MHz, using 4 clocks per instruction, and 300-some bytes of RAM for the entire system) leaves me a bit paranoid. So it's become automatic for me to estimate the cost of each comparison (boolean is best, numbers are okay, and strings take forever), and then guard an expensive one to only run when it's actually needed. This often leads to logically redundant (but cheap) conditions being added to the front, and sometimes odd ordering, just to take advantage of the "short-circuit" logic.

But if the "short-circuit" logic just doesn't exist here, then the "guard conditions" only hurt. Their cost is tiny, but still there (I'll probably never stop thinking about optimization), and they clutter things up to read later. I'll take them out.

I guess the option to "highlight recently matched conditions" kinda forbids the "short-circuit" logic. And that's a very nice feature to have!
 

qwe1154323937

New Member
Hi,@Warmuptill
I updated Chinese simplified localization file.
A NEW BUG FOUND:
AdvSceneSwitcher.mediaTab.states.playlistEnd="Ended(Playlist)" This code ,Name not using
I added my video space homepage in the general settings, I hope you won't mind, if you don't want it to exist, you can restore it to the original Chinese text, thanks to the plugin, I have made it into a tutorial video and sent it to Bilibili.
 
Top