Skip to content

Commit

Permalink
core-old
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Dec 15, 2024
1 parent fcf9536 commit a15eac1
Show file tree
Hide file tree
Showing 45 changed files with 604 additions and 604 deletions.
File renamed without changes.
File renamed without changes.
60 changes: 60 additions & 0 deletions packages/core-old/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "@sceneify/core-old",
"version": "1.0.0-beta.0",
"description": "",
"main": "./cjs/index.cjs",
"browser": "./lib/index.js",
"module": "./esm/index.js",
"types": "./dts/index.d.ts",
"author": "",
"license": "ISC",
"scripts": {
"test": "jest -i"
},
"dependencies": {
"next-tick": "^1.1.0",
"obs-websocket-js": "5.0.1"
},
"devDependencies": {
"@types/jest": "^27.0.3",
"@types/next-tick": "^1.0.0",
"@types/node": "^16.9.3",
"@types/ws": "^7.4.6",
"jest": "^27.4.5"
},
"files": [
"cjs/**/*.{cjs,map}",
"dist",
"dts",
"esm/**/*.{js,map}",
"lib",
"lib/**/*.{js,map}",
"src/**/*.{ts,tsx,json}"
],
"packemon": [
{
"format": "cjs",
"platform": "node"
},
{
"format": [
"lib",
"esm"
],
"platform": "browser"
}
],
"engines": {
"node": ">=12.17.0",
"npm": ">=6.13.0"
},
"jest": {
"preset": "ts-jest",
"globals": {
"ts-jest": {
"tsconfig": "<rootDir>/tests/tsconfig.json"
}
}
},
"type": "commonjs"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
211 changes: 211 additions & 0 deletions packages/core-old/src/OBS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
import ObsWebSocket, { EventSubscription } from "obs-websocket-js";

import {
OBSEventTypes,
OBSRequestTypes,
OBSResponseTypes,
Settings,
} from "./types";
import { Scene } from "./Scene";
import { Input } from "./Input";
import { SourceRefs } from "./Source";

export class OBS {
/**
* The OBS websocket connection used internally
*/
socket = new ObsWebSocket();

/**
* All of the sources that this OBS instance has access to, excluding scenes
*/
inputs = new Map<string, Input>();

/**
* All of the scenes that this OBS instance has access to
*/
scenes = new Map<string, Scene>();

/** @internal */
rpcVersion!: number;

/**
* Connect this OBS instance to a websocket
*/
async connect(url: string, password?: string) {
const data = await this.socket.connect(url, password, {
eventSubscriptions:
EventSubscription.Scenes |
EventSubscription.Inputs |
EventSubscription.Filters |
EventSubscription.SceneItems |
EventSubscription.MediaInputs,
});

this.rpcVersion = data.negotiatedRpcVersion;

this.inputs.clear();
this.scenes.clear();
}

/**
* Goes though each source in OBS and removes it if Sceneify owns it,
* and there are no references to the source in code.
*/
async clean() {
const { scenes } = await this.call("GetSceneList");
const { inputs } = await this.call("GetInputList");

const sourcesSettings = await Promise.all(
[
...scenes.map((s) => s.sceneName),
...inputs.map((i) => i.inputName),
].map(async (sourceName) => {
const { sourceSettings } = await this.call("GetSourcePrivateSettings", {
sourceName,
}).catch(() => ({
sourceName,
sourceSettings: {} as Settings,
}));

return {
sourceName,
sourceSettings,
};
})
);

const sourcesRefs = sourcesSettings.reduce(
(acc, data) => ({
...acc,
...(data.sourceSettings.SCENEIFY_LINKED === false &&
data.sourceSettings.SCENEIFY_REFS
? { [data.sourceName]: data.sourceSettings.SCENEIFY_REFS }
: {}),
}),
{} as Record<string, SourceRefs>
);

// Delete refs that are actually in use
for (let [_, scene] of this.scenes) {
for (let item of scene.items) {
delete sourcesRefs[item.source.name]?.[scene.name]?.[item.ref];

if (
Object.keys(sourcesRefs[item.source.name]?.[scene.name] ?? {})
.length === 0
) {
delete sourcesRefs[item.source.name]?.[scene.name];
}

if (Object.keys(sourcesRefs[item.source.name] ?? {}).length === 0) {
delete sourcesRefs[item.source.name];
}
}
}

const danglingItems = Object.values(sourcesRefs)
.filter((r) => r !== undefined)
.reduce(
(acc, sourceRefs) => {
let danglingInputItems = [];

for (let [sceneName, refs] of Object.entries(sourceRefs)) {
for (let sceneItemId of Object.values(refs)) {
if (sourceRefs[sceneName] !== undefined)
danglingInputItems.push({
sceneName,
sceneItemId,
});
}
}

return [...acc, ...danglingInputItems];
},
[] as {
sceneName: string;
sceneItemId: number;
}[]
);

await Promise.all(
danglingItems.map((data) =>
this.call("RemoveSceneItem", data).catch(() => {})
)
);

const danglingOBSScenes = scenes.filter(
({ sceneName }) =>
!this.scenes.has(sceneName) && sourcesRefs[sceneName] !== undefined
);

await Promise.all(
danglingOBSScenes.map(({ sceneName }) =>
this.call("RemoveScene", { sceneName }).catch(() => {})
)
);

for (let danglingCodeScene of this.scenes.keys()) {
if (scenes.every(({ sceneName }) => sceneName !== danglingCodeScene))
this.scenes.delete(danglingCodeScene);
}

for (let danglingCodeInputs of this.inputs.keys()) {
if (inputs.every(({ inputName }) => inputName !== danglingCodeInputs))
this.inputs.delete(danglingCodeInputs);
}

// TODO: Clean filters
await Promise.all(
[...[...this.inputs.values()], ...[...this.scenes.values()]].map(
(input) => input.refreshRefs().catch(() => {})
)
);
}

call<T extends keyof OBSRequestTypes>(
requestType: T,
requestData?: OBSRequestTypes[T]
): Promise<OBSResponseTypes[T]> {
return this.socket.call(requestType as any, requestData as any);
}

on<T extends keyof OBSEventTypes>(
event: T,
callback: (data: OBSEventTypes[T]) => void
) {
this.socket.on(event, callback as any);
return this;
}

off<T extends keyof OBSEventTypes>(
event: T,
callback: (data: OBSEventTypes[T]) => void
) {
this.socket.off(event, callback as any);
}

/**
* Streaming state
*/

streaming = false;

async startStreaming() {
await this.call("StartStream");

this.streaming = true;
}

async stopStreaming() {
await this.call("StopStream");

this.streaming = false;
}

async toggleStreaming() {
const { outputActive } = await this.call("ToggleStream");

this.streaming = outputActive;
}
}
File renamed without changes.
Loading

0 comments on commit a15eac1

Please sign in to comment.