obs-scheduler 0.0.3 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/cli.js +1 -1
- package/config-schema.json +98 -64
- package/dist/config.js +41 -9
- package/dist/index.js +6 -1
- package/dist/obs.js +3 -1
- package/examples/config-example.json +9 -9
- package/package.json +2 -1
package/README.md
CHANGED
package/cli.js
CHANGED
package/config-schema.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "OBS Scheduler
|
|
3
|
+
"title": "OBS Scheduler Configuration",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"required": [
|
|
6
6
|
"events"
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"format": "tabs",
|
|
14
14
|
"items": {
|
|
15
15
|
"title": "Event",
|
|
16
|
+
"headerTemplate": "{{ self.name }}",
|
|
16
17
|
"description": "A scheduled event for triggering a set action in OBS.",
|
|
17
18
|
"type": "object",
|
|
18
19
|
"required": [
|
|
@@ -40,11 +41,23 @@
|
|
|
40
41
|
"$ref": "#/definitions/ScheduleType"
|
|
41
42
|
},
|
|
42
43
|
"date": {
|
|
43
|
-
"title": "Date",
|
|
44
|
-
"description": "A date/time for when the action should trigger.",
|
|
44
|
+
"title": "Date(s)",
|
|
45
|
+
"description": "A date/time (or a list of dates/times) for when the action should trigger.",
|
|
45
46
|
"propertyOrder": 4,
|
|
46
|
-
"
|
|
47
|
-
|
|
47
|
+
"anyOf": [
|
|
48
|
+
{
|
|
49
|
+
"title": "Single Date/Time",
|
|
50
|
+
"$ref": "#/definitions/DateString"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"title": "Multiple Dates/Times",
|
|
54
|
+
"type": "array",
|
|
55
|
+
"uniqueItems": true,
|
|
56
|
+
"items": {
|
|
57
|
+
"$ref": "#/definitions/DateString"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
48
61
|
"options": {
|
|
49
62
|
"dependencies": {
|
|
50
63
|
"schedule_type": "date"
|
|
@@ -52,10 +65,23 @@
|
|
|
52
65
|
}
|
|
53
66
|
},
|
|
54
67
|
"schedule": {
|
|
55
|
-
"title": "Schedule",
|
|
56
|
-
"description": "
|
|
68
|
+
"title": "Schedule(s)",
|
|
69
|
+
"description": "A schedule (or a list of schedules) for a recurring event in crontab format.",
|
|
57
70
|
"propertyOrder": 4,
|
|
58
|
-
"
|
|
71
|
+
"anyOf": [
|
|
72
|
+
{
|
|
73
|
+
"title": "Single Schedule",
|
|
74
|
+
"$ref": "#/definitions/CronTabString"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"title": "Multiple Schedules",
|
|
78
|
+
"type": "array",
|
|
79
|
+
"uniqueItems": true,
|
|
80
|
+
"items": {
|
|
81
|
+
"$ref": "#/definitions/CronTabString"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
],
|
|
59
85
|
"options": {
|
|
60
86
|
"dependencies": {
|
|
61
87
|
"schedule_type": "recurring"
|
|
@@ -79,69 +105,70 @@
|
|
|
79
105
|
},
|
|
80
106
|
"ws_request": {
|
|
81
107
|
"title": "OBS Websocket Message",
|
|
82
|
-
"$ref": "#/definitions/OBSWSRequest"
|
|
108
|
+
"$ref": "#/definitions/OBSWSRequest",
|
|
109
|
+
"options": {
|
|
110
|
+
"dependencies": {
|
|
111
|
+
"action": "obs_ws"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
83
114
|
}
|
|
84
115
|
},
|
|
85
116
|
"allOf": [
|
|
86
117
|
{
|
|
87
|
-
"
|
|
88
|
-
{
|
|
89
|
-
"
|
|
90
|
-
"date"
|
|
91
|
-
],
|
|
92
|
-
"properties": {
|
|
93
|
-
"schedule_type": {
|
|
94
|
-
"const": "date"
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
"required": [
|
|
100
|
-
"schedule"
|
|
101
|
-
],
|
|
102
|
-
"properties": {
|
|
103
|
-
"schedule_type": {
|
|
104
|
-
"const": "recurring"
|
|
105
|
-
}
|
|
118
|
+
"if": {
|
|
119
|
+
"properties": {
|
|
120
|
+
"schedule_type": {
|
|
121
|
+
"const": "date"
|
|
106
122
|
}
|
|
107
123
|
}
|
|
108
|
-
|
|
124
|
+
},
|
|
125
|
+
"then": {
|
|
126
|
+
"required": [
|
|
127
|
+
"date"
|
|
128
|
+
]
|
|
129
|
+
}
|
|
109
130
|
},
|
|
110
131
|
{
|
|
111
|
-
"
|
|
112
|
-
{
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
"action": {
|
|
116
|
-
"enum": [
|
|
117
|
-
"advanced_scene_switcher",
|
|
118
|
-
"obs_ws"
|
|
119
|
-
]
|
|
120
|
-
}
|
|
121
|
-
}
|
|
132
|
+
"if": {
|
|
133
|
+
"properties": {
|
|
134
|
+
"schedule_type": {
|
|
135
|
+
"const": "recurring"
|
|
122
136
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"then": {
|
|
140
|
+
"required": [
|
|
141
|
+
"schedule"
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"if": {
|
|
147
|
+
"properties": {
|
|
148
|
+
"action": {
|
|
149
|
+
"const": "advanced_scene_switcher"
|
|
132
150
|
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"then": {
|
|
154
|
+
"required": [
|
|
155
|
+
"switcher_message"
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"if": {
|
|
161
|
+
"properties": {
|
|
162
|
+
"action": {
|
|
163
|
+
"const": "obs_ws"
|
|
142
164
|
}
|
|
143
165
|
}
|
|
144
|
-
|
|
166
|
+
},
|
|
167
|
+
"then": {
|
|
168
|
+
"required": [
|
|
169
|
+
"ws_request"
|
|
170
|
+
]
|
|
171
|
+
}
|
|
145
172
|
}
|
|
146
173
|
],
|
|
147
174
|
"options": {
|
|
@@ -166,6 +193,15 @@
|
|
|
166
193
|
]
|
|
167
194
|
}
|
|
168
195
|
},
|
|
196
|
+
"DateString": {
|
|
197
|
+
"type": "string",
|
|
198
|
+
"format": "datetime-local"
|
|
199
|
+
},
|
|
200
|
+
"CronTabString": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"format": "crontab",
|
|
203
|
+
"pattern": "^((((\\d+,)+\\d+|(\\d+(\\/|-|#)\\d+)|\\d+L?|\\*(\\/\\d+)?|L(-\\d+)?|\\?|[A-Z]{3}(-[A-Z]{3})?) ?){5,7})|(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\\d+(ns|us|µs|ms|s|m|h))+)$"
|
|
204
|
+
},
|
|
169
205
|
"EventAction": {
|
|
170
206
|
"description": "An action to trigger in OBS.",
|
|
171
207
|
"type": "string",
|
|
@@ -199,17 +235,15 @@
|
|
|
199
235
|
],
|
|
200
236
|
"additionalProperties": false,
|
|
201
237
|
"properties": {
|
|
238
|
+
"id": {
|
|
239
|
+
"type": "string"
|
|
240
|
+
},
|
|
202
241
|
"type": {
|
|
203
242
|
"type": "string"
|
|
204
243
|
},
|
|
205
244
|
"data": {
|
|
206
245
|
"type": "object"
|
|
207
246
|
}
|
|
208
|
-
},
|
|
209
|
-
"options": {
|
|
210
|
-
"dependencies": {
|
|
211
|
-
"action": "obs_ws"
|
|
212
|
-
}
|
|
213
247
|
}
|
|
214
248
|
}
|
|
215
249
|
}
|
package/dist/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import CronExpressionParser from "cron-parser";
|
|
1
2
|
import { DateTime } from "luxon";
|
|
2
3
|
|
|
3
4
|
/** @typedef {'date'|'recurring'} ConfigEventType */
|
|
@@ -8,6 +9,7 @@ import { DateTime } from "luxon";
|
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @typedef {Object} OBSWSRequest
|
|
12
|
+
* @property {string} [id]
|
|
11
13
|
* @property {string} type
|
|
12
14
|
* @property {Object} data
|
|
13
15
|
*/
|
|
@@ -17,8 +19,8 @@ import { DateTime } from "luxon";
|
|
|
17
19
|
* @property {string} [name]
|
|
18
20
|
* @property {boolean} [enabled=true]
|
|
19
21
|
* @property {ConfigEventType} schedule_type
|
|
20
|
-
* @property {string} [date] Only present if `schedule_type` is `'date'`.
|
|
21
|
-
* @property {string} [schedule] Only present if `schedule_type` is `'recurring'`.
|
|
22
|
+
* @property {string|string[]} [date] Only present if `schedule_type` is `'date'`.
|
|
23
|
+
* @property {string|string[]} [schedule] Only present if `schedule_type` is `'recurring'`.
|
|
22
24
|
* @property {ConfigEventAction} action
|
|
23
25
|
* @property {string} [switcher_message] Only present if `action` is `'advanced_scene_switcher'`.
|
|
24
26
|
* @property {OBSWSRequest} [ws_request] Only present if `action` is `'obs_ws'`.
|
|
@@ -36,17 +38,47 @@ import { DateTime } from "luxon";
|
|
|
36
38
|
* @returns {boolean}
|
|
37
39
|
*/
|
|
38
40
|
export function checkEventSchedule(date, event) {
|
|
41
|
+
// Ignore a disabled event
|
|
39
42
|
if (event.enabled == false) {
|
|
40
43
|
return false;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
if (event.date) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
if (event.date) { // If event has the `date` field
|
|
47
|
+
/** @type {string[]} */
|
|
48
|
+
let datesToCompare = new Array();
|
|
49
|
+
if (typeof event.date == 'string') {
|
|
50
|
+
datesToCompare.push(event.date);
|
|
51
|
+
} else {
|
|
52
|
+
datesToCompare.push(...event.date);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return datesToCompare.some((eventDate) => {
|
|
56
|
+
// Parse event's date string to `DateTime`
|
|
57
|
+
const eventDateTime = DateTime.fromISO(eventDate);
|
|
58
|
+
// console.log(eventDate.getTime(), date.getTime())
|
|
59
|
+
// Compare parsed date (rounded to the previous second) to the current `date`
|
|
60
|
+
return eventDateTime.startOf('second').toMillis() == date.toMillis();
|
|
61
|
+
});
|
|
62
|
+
} else if (event.schedule) { // If event has the `schedule` field
|
|
63
|
+
/** @type {string[]} */
|
|
64
|
+
let schedulesToCompare = new Array();
|
|
65
|
+
if (typeof event.schedule == 'string') {
|
|
66
|
+
schedulesToCompare.push(event.schedule);
|
|
67
|
+
} else {
|
|
68
|
+
schedulesToCompare.push(...event.schedule);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return schedulesToCompare.some((eventSchedule) => {
|
|
72
|
+
try {
|
|
73
|
+
// Parse crontab string
|
|
74
|
+
const schedule = CronExpressionParser.parse(eventSchedule);
|
|
75
|
+
// Return if the parsed schedule includes the current `date`
|
|
76
|
+
return schedule.includesDate(date.toJSDate());
|
|
77
|
+
} catch (error) {
|
|
78
|
+
// If parse fails, return `false`
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
50
82
|
} else {
|
|
51
83
|
return false;
|
|
52
84
|
}
|
package/dist/index.js
CHANGED
|
@@ -33,12 +33,14 @@ export async function run() {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** @type {Config} */
|
|
36
|
-
let config
|
|
36
|
+
let config;
|
|
37
37
|
|
|
38
38
|
function updateConfigFromFile() {
|
|
39
39
|
const fileContents = fs.readFileSync(configPath, "utf8")
|
|
40
40
|
.replace(/^[ \t]*\/\/.+$\n/gm, '');
|
|
41
|
+
const firstRun = config == undefined;
|
|
41
42
|
config = JSON.parse(fileContents);
|
|
43
|
+
console.log((firstRun ? 'Read' : 'Updated') + ' configuration file.');
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
// Read config file for initial value
|
|
@@ -54,6 +56,9 @@ export async function run() {
|
|
|
54
56
|
const matchingEvents = config.events
|
|
55
57
|
.filter(e => checkEventSchedule(date, e));
|
|
56
58
|
|
|
59
|
+
// console.log(config.events);
|
|
60
|
+
console.log(matchingEvents);
|
|
61
|
+
|
|
57
62
|
const wsRequests = matchingEvents
|
|
58
63
|
.flatMap(convertEventToWebsocketRequest);
|
|
59
64
|
|
package/dist/obs.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* @returns {import("obs-websocket-js").RequestBatchRequest[]}
|
|
7
7
|
*/
|
|
8
8
|
export function convertEventToWebsocketRequest(event) {
|
|
9
|
-
const requestID =
|
|
9
|
+
const requestID = event.action == 'obs_ws' && event.ws_request?.id
|
|
10
|
+
? event.ws_request.id
|
|
11
|
+
: `${event.name ? event.name + '.' : ''}${event.action}`;
|
|
10
12
|
|
|
11
13
|
switch (event.action) {
|
|
12
14
|
case "start_stream":
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "/Users/edon/Documents/Developer Stuff/NPM Packages/obs-scheduler/config-schema.json",
|
|
3
3
|
"events": [
|
|
4
4
|
{
|
|
5
5
|
"name": "Example Event 1",
|
|
6
6
|
"schedule_type": "date",
|
|
7
|
-
"date": "2026-01-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
"
|
|
7
|
+
// "date": "2026-01-09T14:49:30",
|
|
8
|
+
"date": [
|
|
9
|
+
"2026-01-09T15:06:15",
|
|
10
|
+
"2026-01-09T15:06:45",
|
|
11
|
+
"2026-01-09T15:07"
|
|
12
|
+
],
|
|
13
|
+
"action": "advanced_scene_switcher",
|
|
14
|
+
"switcher_message": "test"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obs-scheduler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A CLI tool for scheduling OBS functionality.",
|
|
5
5
|
"author": "edonv",
|
|
6
6
|
"type": "module",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"homepage": "https://github.com/edonv/obs-scheduler#readme",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"commander": "^14.0.2",
|
|
22
|
+
"cron-parser": "^5.4.0",
|
|
22
23
|
"luxon": "^3.7.2",
|
|
23
24
|
"obs-websocket-js": "^5.0.7"
|
|
24
25
|
},
|