0
# Event Subscriptions
1
2
The Subs enum provides fine-grained control over which OBS events to receive, allowing you to optimize network traffic and callback processing load. Different events have different frequencies and use cases.
3
4
## Subscription System
5
6
### Subs Enum
7
8
```python { .api }
9
from enum import IntFlag
10
11
class Subs(IntFlag):
12
# Low-volume event categories (individual flags)
13
GENERAL = 1 << 0 # General events
14
CONFIG = 1 << 1 # Configuration changes
15
SCENES = 1 << 2 # Scene events
16
INPUTS = 1 << 3 # Input events
17
TRANSITIONS = 1 << 4 # Transition events
18
FILTERS = 1 << 5 # Filter events
19
OUTPUTS = 1 << 6 # Output events
20
SCENEITEMS = 1 << 7 # Scene item events
21
MEDIAINPUTS = 1 << 8 # Media input events
22
VENDORS = 1 << 9 # Vendor events
23
UI = 1 << 10 # UI events
24
25
# High-volume event categories (individual flags)
26
INPUTVOLUMEMETERS = 1 << 16 # Volume meter updates (very frequent)
27
INPUTACTIVESTATECHANGED = 1 << 17 # Input active state changes
28
INPUTSHOWSTATECHANGED = 1 << 18 # Input show state changes
29
SCENEITEMTRANSFORMCHANGED = 1 << 19 # Scene item transform changes (frequent)
30
31
# Composite subscription flags
32
LOW_VOLUME = (GENERAL | CONFIG | SCENES | INPUTS | TRANSITIONS |
33
FILTERS | OUTPUTS | SCENEITEMS | MEDIAINPUTS | VENDORS | UI)
34
HIGH_VOLUME = (INPUTVOLUMEMETERS | INPUTACTIVESTATECHANGED |
35
INPUTSHOWSTATECHANGED | SCENEITEMTRANSFORMCHANGED)
36
ALL = LOW_VOLUME | HIGH_VOLUME
37
```
38
39
## Event Categories
40
41
### Low-Volume Events
42
43
These events occur occasionally and are suitable for most applications:
44
45
#### GENERAL (Subs.GENERAL)
46
- General OBS events
47
- ExitStarted
48
- VendorEvent
49
- CustomEvent
50
51
#### CONFIG (Subs.CONFIG)
52
- Configuration changes
53
- CurrentSceneCollectionChanging
54
- CurrentSceneCollectionChanged
55
- SceneCollectionListChanged
56
- CurrentProfileChanging
57
- CurrentProfileChanged
58
- ProfileListChanged
59
60
#### SCENES (Subs.SCENES)
61
- Scene management events
62
- SceneCreated
63
- SceneRemoved
64
- SceneNameChanged
65
- CurrentProgramSceneChanged
66
- CurrentPreviewSceneChanged
67
- SceneListChanged
68
69
#### INPUTS (Subs.INPUTS)
70
- Input management events
71
- InputCreated
72
- InputRemoved
73
- InputNameChanged
74
- InputSettingsChanged
75
- InputMuteStateChanged
76
- InputVolumeChanged
77
78
#### TRANSITIONS (Subs.TRANSITIONS)
79
- Scene transition events
80
- CurrentSceneTransitionChanged
81
- CurrentSceneTransitionDurationChanged
82
- SceneTransitionStarted
83
- SceneTransitionEnded
84
- SceneTransitionVideoEnded
85
86
#### FILTERS (Subs.FILTERS)
87
- Source filter events
88
- SourceFilterCreated
89
- SourceFilterRemoved
90
- SourceFilterNameChanged
91
- SourceFilterSettingsChanged
92
- SourceFilterEnableStateChanged
93
94
#### OUTPUTS (Subs.OUTPUTS)
95
- Output events (streaming, recording)
96
- StreamStateChanged
97
- RecordStateChanged
98
- ReplayBufferStateChanged
99
- VirtualcamStateChanged
100
- ReplayBufferSaved
101
102
#### SCENEITEMS (Subs.SCENEITEMS)
103
- Scene item management events
104
- SceneItemCreated
105
- SceneItemRemoved
106
- SceneItemListReindexed
107
- SceneItemEnableStateChanged
108
- SceneItemLockStateChanged
109
110
#### MEDIAINPUTS (Subs.MEDIAINPUTS)
111
- Media input events
112
- MediaInputPlaybackStarted
113
- MediaInputPlaybackEnded
114
- MediaInputActionTriggered
115
116
#### VENDORS (Subs.VENDORS)
117
- Third-party vendor events
118
- VendorEvent (vendor-specific events)
119
120
#### UI (Subs.UI)
121
- UI-related events
122
- StudioModeStateChanged
123
- ScreenshotSaved
124
125
### High-Volume Events
126
127
These events occur frequently and should be used with caution:
128
129
#### INPUTVOLUMEMETERS (Subs.INPUTVOLUMEMETERS)
130
- Real-time volume level updates for all inputs
131
- InputVolumeMeters event (fires continuously while audio is active)
132
- **Warning**: Very high frequency, can generate hundreds of events per second
133
134
#### INPUTACTIVESTATECHANGED (Subs.INPUTACTIVESTATECHANGED)
135
- Input active state changes
136
- InputActiveStateChanged event
137
- Fires when inputs become active/inactive (e.g., when sources start/stop producing content)
138
139
#### INPUTSHOWSTATECHANGED (Subs.INPUTSHOWSTATECHANGED)
140
- Input show state changes
141
- InputShowStateChanged event
142
- Fires when inputs become visible/hidden in scenes
143
144
#### SCENEITEMTRANSFORMCHANGED (Subs.SCENEITEMTRANSFORMCHANGED)
145
- Scene item transform changes
146
- SceneItemTransformChanged event
147
- Fires frequently when dragging or animating scene items
148
149
## Usage Patterns
150
151
### Recommended Subscription Levels
152
153
```python
154
import obsws_python as obs
155
156
# Most applications - low-volume events only
157
client = obs.EventClient(subs=obs.Subs.LOW_VOLUME)
158
159
# Specific categories only
160
client = obs.EventClient(subs=obs.Subs.SCENES | obs.Subs.INPUTS)
161
162
# All events (use carefully)
163
client = obs.EventClient(subs=obs.Subs.ALL)
164
165
# No events (request-only mode)
166
client = obs.EventClient(subs=0)
167
```
168
169
### Custom Subscription Combinations
170
171
```python
172
import obsws_python as obs
173
174
# Scene and input events only
175
scene_input_subs = obs.Subs.SCENES | obs.Subs.INPUTS
176
client = obs.EventClient(subs=scene_input_subs)
177
178
# Low-volume events plus transform changes
179
interactive_subs = obs.Subs.LOW_VOLUME | obs.Subs.SCENEITEMTRANSFORMCHANGED
180
client = obs.EventClient(subs=interactive_subs)
181
182
# Streaming application - outputs and scenes
183
streaming_subs = obs.Subs.OUTPUTS | obs.Subs.SCENES | obs.Subs.GENERAL
184
client = obs.EventClient(subs=streaming_subs)
185
186
# Audio monitoring - inputs and volume meters
187
audio_subs = obs.Subs.INPUTS | obs.Subs.INPUTVOLUMEMETERS
188
client = obs.EventClient(subs=audio_subs)
189
```
190
191
## Performance Considerations
192
193
### Event Frequency Guide
194
195
| Subscription | Frequency | Use Cases |
196
|-------------|-----------|-----------|
197
| `LOW_VOLUME` | Occasional | General applications, automation |
198
| `SCENES` | Low | Scene switching apps |
199
| `INPUTS` | Low-Medium | Audio/video control apps |
200
| `OUTPUTS` | Low | Streaming/recording monitors |
201
| `SCENEITEMTRANSFORMCHANGED` | High | Interactive scene editors |
202
| `INPUTACTIVESTATECHANGED` | Medium | Source monitoring |
203
| `INPUTVOLUMEMETERS` | Very High | Real-time audio visualizers |
204
205
### Best Practices
206
207
1. **Start with LOW_VOLUME**: Most applications don't need high-frequency events
208
2. **Add specific categories**: Only subscribe to events you actually handle
209
3. **Avoid ALL subscription**: Unless building comprehensive OBS control software
210
4. **Monitor performance**: High-volume events can impact application performance
211
5. **Use filtering**: Handle events efficiently in your callbacks
212
213
## Event Handling Examples
214
215
### Minimal Event Monitoring
216
217
```python
218
import obsws_python as obs
219
220
# Only scene changes - very lightweight
221
client = obs.EventClient(subs=obs.Subs.SCENES)
222
223
def on_current_program_scene_changed(data):
224
print(f"Scene changed to: {data.scene_name}")
225
226
client.callback.register(on_current_program_scene_changed)
227
228
input("Monitoring scene changes only...\n")
229
client.disconnect()
230
```
231
232
### Audio Application
233
234
```python
235
import obsws_python as obs
236
237
# Audio-focused events
238
audio_subs = obs.Subs.INPUTS | obs.Subs.INPUTVOLUMEMETERS
239
client = obs.EventClient(subs=audio_subs)
240
241
volume_count = 0
242
243
def on_input_mute_state_changed(data):
244
print(f"Mute changed: {data.input_name} = {data.input_muted}")
245
246
def on_input_volume_changed(data):
247
print(f"Volume changed: {data.input_name} = {data.input_volume_db}dB")
248
249
def on_input_volume_meters(data):
250
global volume_count
251
volume_count += 1
252
253
# Only log every 50 volume updates to avoid spam
254
if volume_count % 50 == 0:
255
inputs_with_audio = [name for name, levels in data.inputs.items()
256
if any(level > -60 for level in levels)]
257
if inputs_with_audio:
258
print(f"Audio detected in: {', '.join(inputs_with_audio)}")
259
260
client.callback.register([
261
on_input_mute_state_changed,
262
on_input_volume_changed,
263
on_input_volume_meters
264
])
265
266
print("Audio monitoring active (includes volume meters)")
267
input("Press Enter to stop...\n")
268
client.disconnect()
269
```
270
271
### Streaming Dashboard
272
273
```python
274
import obsws_python as obs
275
from datetime import datetime
276
277
# Events relevant for streaming dashboard
278
dashboard_subs = (obs.Subs.SCENES | obs.Subs.OUTPUTS |
279
obs.Subs.INPUTS | obs.Subs.GENERAL)
280
client = obs.EventClient(subs=dashboard_subs)
281
282
def log_with_time(message):
283
timestamp = datetime.now().strftime("%H:%M:%S")
284
print(f"[{timestamp}] {message}")
285
286
def on_current_program_scene_changed(data):
287
log_with_time(f"π¬ Scene: {data.scene_name}")
288
289
def on_stream_state_changed(data):
290
if data.output_active:
291
log_with_time("π΄ Stream STARTED")
292
else:
293
log_with_time("β« Stream STOPPED")
294
295
def on_record_state_changed(data):
296
if data.output_active:
297
log_with_time("πΉ Recording STARTED")
298
else:
299
log_with_time("βΉοΈ Recording STOPPED")
300
301
def on_input_mute_state_changed(data):
302
emoji = "π" if data.input_muted else "π"
303
log_with_time(f"{emoji} {data.input_name}")
304
305
client.callback.register([
306
on_current_program_scene_changed,
307
on_stream_state_changed,
308
on_record_state_changed,
309
on_input_mute_state_changed
310
])
311
312
log_with_time("Streaming dashboard monitoring started")
313
input("Press Enter to stop...\n")
314
client.disconnect()
315
```
316
317
### Scene Editor Events
318
319
```python
320
import obsws_python as obs
321
322
# Scene editing with high-frequency transform events
323
editor_subs = (obs.Subs.SCENES | obs.Subs.SCENEITEMS |
324
obs.Subs.SCENEITEMTRANSFORMCHANGED)
325
client = obs.EventClient(subs=editor_subs)
326
327
transform_updates = {}
328
329
def on_scene_item_created(data):
330
print(f"β Item created: {data.source_name} in {data.scene_name}")
331
332
def on_scene_item_removed(data):
333
print(f"β Item removed: {data.source_name} from {data.scene_name}")
334
335
def on_scene_item_transform_changed(data):
336
# Track transform updates per item
337
item_key = f"{data.scene_name}:{data.scene_item_id}"
338
transform_updates[item_key] = transform_updates.get(item_key, 0) + 1
339
340
# Log every 10 updates per item
341
if transform_updates[item_key] % 10 == 0:
342
print(f"π Transform updates for item {data.scene_item_id}: {transform_updates[item_key]}")
343
344
def on_scene_item_enable_state_changed(data):
345
state = "enabled" if data.scene_item_enabled else "disabled"
346
print(f"ποΈ Item {data.scene_item_id} {state}")
347
348
client.callback.register([
349
on_scene_item_created,
350
on_scene_item_removed,
351
on_scene_item_transform_changed,
352
on_scene_item_enable_state_changed
353
])
354
355
print("Scene editor monitoring active (includes transform changes)")
356
print("Move scene items around to see transform events...")
357
input("Press Enter to stop...\n")
358
client.disconnect()
359
360
# Show final transform update counts
361
if transform_updates:
362
print("\nFinal transform update counts:")
363
for item, count in transform_updates.items():
364
print(f" {item}: {count} updates")
365
```