-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauto-monitor-switch.py
143 lines (123 loc) · 4.64 KB
/
auto-monitor-switch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import obspython as obs
import subprocess
# GLOBAL VARIABLES #############################################################
active_monitor = 0
left_width = 1920
check_freq = 300
scene_names = ["", ""]
monitor_left_list = None
monitor_right_list = None
is_active = False
# GLOBAL SCRIPTS ###############################################################
def script_defaults(settings):
obs.obs_data_set_default_bool(settings, "is_active", is_active)
obs.obs_data_set_default_int(settings, "left_width", left_width)
obs.obs_data_set_default_int(settings, "check_freq", check_freq)
obs.obs_data_set_default_string(settings, "scene_for_left_mon", "")
obs.obs_data_set_default_string(settings, "scene_for_right_mon", "")
def script_description():
return ("Automatically switches between 2 scenes based on the monitor "
"containing the active window in a Linux environment. Specific "
"to installations with a dual-monitor setup."
"\n\n Dependencies: xdotool")
def script_properties():
global monitor_left_list, monitor_right_list
props = obs.obs_properties_create()
active = obs.obs_properties_add_bool(props, "is_active", "Active")
refresh_lists = obs.obs_properties_add_button(
props,
"refresh_lists",
"Refresh scene lists",
refresh_lists_callback
)
monitor_left_list = obs.obs_properties_add_list(
props,
"scene_for_left_mon",
"Scene for left monitor",
obs.OBS_COMBO_TYPE_EDITABLE,
obs.OBS_COMBO_FORMAT_STRING
)
monitor_right_list = obs.obs_properties_add_list(
props,
"scene_for_right_mon",
"Scene for right monitor",
obs.OBS_COMBO_TYPE_EDITABLE,
obs.OBS_COMBO_FORMAT_STRING
)
check_freq_prop = obs.obs_properties_add_int(
props,
"check_freq",
"Check for active monitor every (ms)",
2,
30000,
50
)
left_width_prop = obs.obs_properties_add_int(
props,
"left_width",
"Left monitor width (px)",
144,
3840,
10
)
return props
def script_load(settings):
obs.timer_add(switch_scenes, check_freq)
def script_update(settings):
global is_active, scene_names, left_width, check_freq
is_active = obs.obs_data_get_bool(settings, "is_active")
scene_names[0] = obs.obs_data_get_string(settings, "scene_for_left_mon")
scene_names[1] = obs.obs_data_get_string(settings, "scene_for_right_mon")
left_width = obs.obs_data_get_int(settings, "left_width")
check_freq = obs.obs_data_get_int(settings, "check_freq")
obs.timer_remove(switch_scenes)
if is_active:
obs.timer_add(switch_scenes, check_freq)
#-------------------------------------------------------------------------------
def refresh_lists_callback(props, prop):
if populate_scene_lists([monitor_left_list, monitor_right_list]):
return True
return True
def populate_scene_lists(lists):
scene_names = obs.obs_frontend_get_scene_names()
for l in lists:
obs.obs_property_list_clear(l)
obs.obs_property_list_add_string(l, "", "")
for name in scene_names:
obs.obs_property_list_add_string(l, name, name)
# SCENE SWITCHING ##############################################################
def get_active_monitor():
global active_monitor
bash_command = ("xdotool getactivewindow getwindowgeometry "
"| grep -m 1 Position "
"| grep -Eo [[:digit:]]+ "
"| head -n 1")
x = subprocess.run(
bash_command,
shell=True,
capture_output=True,
).stdout.decode()
if x == "":
return active_monitor
elif int(x) < left_width:
active_monitor = 0
else:
active_monitor = 1
return active_monitor
def should_switch_scenes():
current = obs.obs_frontend_get_current_scene()
name = obs.obs_source_get_name(current)
obs.obs_source_release(current)
if name in scene_names and name != scene_names[get_active_monitor()]:
return True
return False
def switch_scenes():
if is_active and should_switch_scenes():
sources = obs.obs_enum_sources()
scenes = obs.obs_frontend_get_scenes(sources)
obs.source_list_release(sources)
current = obs.obs_frontend_get_current_scene()
for s in scenes:
if s != current and obs.obs_source_get_name(s) in scene_names:
obs.obs_frontend_set_current_scene(s)
obs.obs_source_release(current)