{"id":51828578,"url":"https://github.com/solomonneas/obsctl","last_synced_at":"2026-07-22T12:04:00.808Z","repository":{"id":368744866,"uuid":"1242487548","full_name":"solomonneas/obsctl","owner":"solomonneas","description":"kubectl-style multi-host wrapper around grigio/obs-cmd for managing OBS Studio over the LAN.","archived":false,"fork":false,"pushed_at":"2026-07-02T01:29:07.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T03:20:35.944Z","etag":null,"topics":["bash","cli","multi-host","obs-studio","obs-websocket","streaming"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/solomonneas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-18T13:22:59.000Z","updated_at":"2026-07-02T01:29:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/solomonneas/obsctl","commit_stats":null,"previous_names":["solomonneas/obsctl"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/solomonneas/obsctl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solomonneas%2Fobsctl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solomonneas%2Fobsctl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solomonneas%2Fobsctl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solomonneas%2Fobsctl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/solomonneas","download_url":"https://codeload.github.com/solomonneas/obsctl/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/solomonneas%2Fobsctl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35760583,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-22T02:00:06.236Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","multi-host","obs-studio","obs-websocket","streaming"],"created_at":"2026-07-22T12:03:59.671Z","updated_at":"2026-07-22T12:04:00.798Z","avatar_url":"https://github.com/solomonneas.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# obsctl\n\n`kubectl`-style multi-host wrapper around [grigio/obs-cmd](https://github.com/grigio/obs-cmd) for managing OBS Studio over the LAN.\n\nIf you've got OBS running on more than one machine (a streaming box + a recording box, your desktop + your laptop, whatever), you want one CLI that knows about all of them. Define your hosts once in a config file, then:\n\n```bash\nobsctl studio recording toggle\nobsctl laptop scene switch \"Camera\"\nobsctl studio info\n```\n\ninstead of typing out `obs-cmd -w obsws://host:port/password ...` every time.\n\n## What this is, what it isn't\n\nThis is a thin bash wrapper. The actual OBS WebSocket work is done by [grigio/obs-cmd](https://github.com/grigio/obs-cmd), which is a v5-protocol-native client written in Rust. `obsctl` just registers your hosts and shells out to `obs-cmd` with the right URL.\n\nIf you only have one OBS instance, `obs-cmd` alone is enough. `obsctl` earns its keep once you have two or more.\n\n## Requirements\n\n- bash 4+ (uses uppercase parameter expansion `${var^^}`)\n- [`obs-cmd`](https://github.com/grigio/obs-cmd/releases) on your `$PATH`\n- OBS Studio 28+ (built-in WebSocket 5.x) on each host, with **Tools → WebSocket Server Settings → Enable WebSocket server** turned on\n\n## Install\n\n```bash\ngit clone https://github.com/solomonneas/obsctl\ncd obsctl\n./install.sh        # installs to ~/.local/bin/obsctl\n```\n\nOr copy `obsctl` somewhere on your `$PATH` yourself:\n\n```bash\nsudo install -m 0755 obsctl /usr/local/bin/obsctl\n```\n\n## Quick start\n\nWrite a starter config:\n\n```bash\nobsctl init\n```\n\nThat creates `~/.config/obsctl/hosts.env` (mode 0600) with a single `local` host pointing at `127.0.0.1:4455`. Open it, paste the password from OBS's WebSocket Server Settings, save.\n\nTry it:\n\n```bash\nobsctl local info\nobsctl local scene list\n```\n\nAdd more hosts by extending the `HOSTS` array and the `\u003cALIAS\u003e_HOST/_PORT/_PASS` variables:\n\n```bash\nHOSTS=(local studio laptop)\n\nLOCAL_HOST=127.0.0.1\nLOCAL_PORT=4455\nLOCAL_PASS='xxxxxxxxxxxxx'\n\nSTUDIO_HOST=192.0.2.10\nSTUDIO_PORT=4455\nSTUDIO_PASS='yyyyyyyyyyyyy'\n\nLAPTOP_HOST=198.51.100.20\nLAPTOP_PORT=4455\nLAPTOP_PASS='zzzzzzzzzzzzz'\n```\n\nAliases are case-insensitive on the command line (`obsctl studio` resolves the same `STUDIO_*` vars).\n\n## All `obs-cmd` verbs are available\n\n`obsctl \u003chost\u003e \u003cwhatever\u003e` becomes `obs-cmd \u003cwhatever\u003e` with `OBS_WEBSOCKET_URL` set to the right `obsws://` URL (in the environment, not on the command line, so the password never shows up in `ps`). So anything `obs-cmd` understands works:\n\n```bash\nobsctl studio scene list\nobsctl studio scene switch \"Camera\"\nobsctl studio recording start\nobsctl studio recording stop\nobsctl studio streaming toggle\nobsctl studio replay save\nobsctl studio audio toggle \"Mic/Aux\"\nobsctl studio virtual-camera toggle\n```\n\nRun `obs-cmd help` for the full upstream list.\n\n## Setting up OBS WebSocket on each host\n\nInside OBS:\n\n1. `Tools → WebSocket Server Settings`\n2. Check **Enable WebSocket server**\n3. Set or read the **Server Password**\n4. Apply, OK\n\nOn the OBS host, allow inbound TCP `4455` from your LAN (or just the workstation running `obsctl`). On Linux + ufw:\n\n```bash\nsudo ufw allow from 192.0.2.0/24 to any port 4455 proto tcp\n```\n\nOn Windows, PowerShell as admin:\n\n```powershell\nNew-NetFirewallRule -DisplayName \"OBS WebSocket\" `\n    -Direction Inbound -Action Allow -Protocol TCP `\n    -LocalPort 4455 -Profile Private -Enabled True\n```\n\n## Config file format\n\n`~/.config/obsctl/hosts.env` (or whatever `$OBSCTL_CONFIG` points at) is plain shell. It's sourced by `obsctl` at run time. Two requirements:\n\n1. `HOSTS=(alias1 alias2 ...)`, a bash array of the aliases you want to register.\n2. For each alias, set three variables in uppercase: `\u003cALIAS\u003e_HOST`, `\u003cALIAS\u003e_PORT`, `\u003cALIAS\u003e_PASS`.\n\nAliases may only contain letters, digits, and underscores, and must not start with a digit, because they become shell variable names. Use `streaming_pc`, not `streaming-pc`.\n\nThat's the whole format. Keep it mode 0600 so other users on your box can't read the passwords.\n\n## Why bash, why not Python / Go / Rust?\n\nBecause the actual work, talking to OBS, is done by `obs-cmd`. All `obsctl` does is dispatch the right URL to it. If you want a richer client, write your `obs-cmd` calls in your language of choice; this script is one possible UX, not the only one.\n\n## Development\n\nLint and test (this is exactly what CI runs):\n\n```bash\nshellcheck obsctl install.sh hooks/pre-push test/smoke.sh\nbash test/smoke.sh\n```\n\nThis repo keeps its git hooks in the tracked `hooks/` directory. They are not active on a fresh clone; opt in with:\n\n```bash\ngit config core.hooksPath hooks\n```\n\nThe `pre-push` hook scans tracked files with [content-guard](https://github.com/solomonneas/content-guard) before anything leaves your machine. See [AGENTS.md](AGENTS.md) for the conventions it enforces.\n\n## See also\n\n- [grigio/obs-cmd](https://github.com/grigio/obs-cmd): the v5-protocol-native CLI we wrap\n- [obsproject/obs-websocket](https://github.com/obsproject/obs-websocket): the WebSocket plugin bundled in OBS 28+\n- [solomonneas/deckctl](https://github.com/solomonneas/deckctl): Stream Deck driver that wires OBS actions through these same hosts\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolomonneas%2Fobsctl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsolomonneas%2Fobsctl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsolomonneas%2Fobsctl/lists"}