tuxcast 0.1.0__tar.gz
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.
- tuxcast-0.1.0/.gitignore +21 -0
- tuxcast-0.1.0/CHANGELOG.md +36 -0
- tuxcast-0.1.0/LICENSE +21 -0
- tuxcast-0.1.0/PKG-INFO +163 -0
- tuxcast-0.1.0/README.md +136 -0
- tuxcast-0.1.0/contrib/README.md +11 -0
- tuxcast-0.1.0/contrib/patches/twitch-oauth-port.toml +18 -0
- tuxcast-0.1.0/contrib/udev/70-streamdeck.rules +6 -0
- tuxcast-0.1.0/pyproject.toml +66 -0
- tuxcast-0.1.0/src/tuxcast/__init__.py +3 -0
- tuxcast-0.1.0/src/tuxcast/__main__.py +3 -0
- tuxcast-0.1.0/src/tuxcast/audio.py +211 -0
- tuxcast-0.1.0/src/tuxcast/bridge.py +186 -0
- tuxcast-0.1.0/src/tuxcast/cli.py +456 -0
- tuxcast-0.1.0/src/tuxcast/convert/__init__.py +286 -0
- tuxcast-0.1.0/src/tuxcast/convert/actions.py +284 -0
- tuxcast-0.1.0/src/tuxcast/convert/elgato.py +326 -0
- tuxcast-0.1.0/src/tuxcast/convert/keymap.py +66 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/__init__.py +464 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/app.css +275 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/app.js +508 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/Barlow-Bold.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/Barlow-Medium.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/Barlow-Regular.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/Barlow-SemiBold.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/BarlowCondensed-Bold.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/BarlowCondensed-SemiBold.woff2 +0 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/fonts/OFL.txt +93 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/index.html +48 -0
- tuxcast-0.1.0/src/tuxcast/dashboard/static/logo.svg +21 -0
- tuxcast-0.1.0/src/tuxcast/deck.py +110 -0
- tuxcast-0.1.0/src/tuxcast/doctor/__init__.py +111 -0
- tuxcast-0.1.0/src/tuxcast/doctor/audio.py +45 -0
- tuxcast-0.1.0/src/tuxcast/doctor/discord.py +67 -0
- tuxcast-0.1.0/src/tuxcast/doctor/display.py +41 -0
- tuxcast-0.1.0/src/tuxcast/doctor/encoders.py +77 -0
- tuxcast-0.1.0/src/tuxcast/doctor/network.py +62 -0
- tuxcast-0.1.0/src/tuxcast/doctor/obs.py +69 -0
- tuxcast-0.1.0/src/tuxcast/doctor/spotify.py +62 -0
- tuxcast-0.1.0/src/tuxcast/doctor/streamdeck.py +46 -0
- tuxcast-0.1.0/src/tuxcast/patch.py +145 -0
- tuxcast-0.1.0/src/tuxcast/paths.py +40 -0
- tuxcast-0.1.0/src/tuxcast/streamcontroller.py +68 -0
- tuxcast-0.1.0/src/tuxcast/system.py +105 -0
- tuxcast-0.1.0/src/tuxcast/systemd.py +65 -0
- tuxcast-0.1.0/src/tuxcast/ui.py +77 -0
- tuxcast-0.1.0/tests/__init__.py +0 -0
- tuxcast-0.1.0/tests/conftest.py +113 -0
- tuxcast-0.1.0/tests/test_audio.py +58 -0
- tuxcast-0.1.0/tests/test_bridge.py +54 -0
- tuxcast-0.1.0/tests/test_cli.py +80 -0
- tuxcast-0.1.0/tests/test_convert.py +309 -0
- tuxcast-0.1.0/tests/test_dashboard.py +161 -0
- tuxcast-0.1.0/tests/test_doctor.py +114 -0
- tuxcast-0.1.0/tests/test_keymap.py +32 -0
- tuxcast-0.1.0/tests/test_patch.py +97 -0
tuxcast-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to tuxcast are listed here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and tuxcast uses
|
|
5
|
+
[semantic versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-10-08
|
|
10
|
+
|
|
11
|
+
The first release: the problems every Linux streamer hits, each solved by one command.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `tuxcast ui` opens a control desk for everything below: a go-live tally, the Stream Deck with
|
|
16
|
+
StreamController's real pages and a key-by-key preview of dropped Elgato profiles, the doctor's
|
|
17
|
+
checks with one-click fixes, an audio mixer with faders, mute and drag-and-drop app routing, the
|
|
18
|
+
Discord bridge and patches. It listens on 127.0.0.1 only and requires the token it prints. The
|
|
19
|
+
website has a live demo of it.
|
|
20
|
+
- `tuxcast doctor` checks a streaming setup in eight areas (display server, audio, GPU
|
|
21
|
+
encoding, OBS, Stream Deck, Discord, Spotify, network) and prints the fix for each
|
|
22
|
+
problem. `--json` for scripts, `--only` to focus on some areas.
|
|
23
|
+
- `tuxcast convert` turns Elgato Stream Deck profiles (`.streamDeckProfile`, backups and
|
|
24
|
+
`.sdProfile` folders, versions 1 and 2) into StreamController pages: images, titles,
|
|
25
|
+
folders, multi actions, hotkeys translated for AZERTY and QWERTZ keyboards, OBS,
|
|
26
|
+
Discord and Twitch actions. A report lists the keys to redo by hand.
|
|
27
|
+
- `tuxcast bridge discord` exposes Discord's IPC socket installed as a snap, Vesktop or a
|
|
28
|
+
native package to Flatpak clients such as StreamController, with an optional login service.
|
|
29
|
+
- `tuxcast audio` creates separate PipeWire sinks (game, music, voice, alerts) and routes
|
|
30
|
+
apps to them, so each part of the mix is its own OBS source.
|
|
31
|
+
- `tuxcast deck` lists Stream Decks, prints the udev rule they need, and resets a deck stuck
|
|
32
|
+
after a crash without unplugging it.
|
|
33
|
+
- `tuxcast patch` re-applies local edits that app updates wipe, through a systemd path unit.
|
|
34
|
+
|
|
35
|
+
[Unreleased]: https://github.com/achedon12/tuxcast/compare/v0.1.0...HEAD
|
|
36
|
+
[0.1.0]: https://github.com/achedon12/tuxcast/releases/tag/v0.1.0
|
tuxcast-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 achedon12
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
tuxcast-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tuxcast
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The toolkit for streaming on Linux: diagnose your setup, convert Elgato Stream Deck profiles, bridge sandboxed apps and split your audio.
|
|
5
|
+
Project-URL: Homepage, https://achedon12.github.io/tuxcast/
|
|
6
|
+
Project-URL: Documentation, https://achedon12.github.io/tuxcast/
|
|
7
|
+
Project-URL: Repository, https://github.com/achedon12/tuxcast
|
|
8
|
+
Project-URL: Issues, https://github.com/achedon12/tuxcast/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/achedon12/tuxcast/blob/main/CHANGELOG.md
|
|
10
|
+
Author: achedon12
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: discord,flatpak,linux,obs,pipewire,stream-deck,streamcontroller,streaming,twitch
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Multimedia :: Video :: Capture
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
<p align="center">
|
|
29
|
+
<img src=".github/assets/banner.svg" alt="tuxcast: the toolkit for streaming on Linux" width="100%">
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<a href="https://github.com/achedon12/tuxcast/actions/workflows/ci.yml"><img src="https://github.com/achedon12/tuxcast/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
34
|
+
<a href="https://github.com/achedon12/tuxcast/releases"><img src="https://img.shields.io/github/v/release/achedon12/tuxcast?color=8b5cf6&label=release" alt="Latest release"></a>
|
|
35
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-3776ab" alt="Python 3.11+">
|
|
36
|
+
<img src="https://img.shields.io/badge/dependencies-0-22c55e" alt="Zero dependencies">
|
|
37
|
+
<img src="https://img.shields.io/badge/root-not%20needed-22c55e" alt="No root needed">
|
|
38
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/achedon12/tuxcast?color=blue" alt="MIT license"></a>
|
|
39
|
+
<a href="https://achedon12.github.io/tuxcast/"><img src="https://img.shields.io/badge/docs-website-8b5cf6" alt="Documentation"></a>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<p align="center">
|
|
43
|
+
<b>English</b> · <a href="README.fr.md">Français</a>
|
|
44
|
+
</p>
|
|
45
|
+
|
|
46
|
+
**tuxcast** finds what will break your stream before you go live, then fixes it. It converts
|
|
47
|
+
your Elgato Stream Deck profiles, connects the apps Flatpak and snap keep apart, and splits
|
|
48
|
+
your audio so every source gets its own fader. One command each, no root, no dependencies.
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
pipx install git+https://github.com/achedon12/tuxcast.git
|
|
52
|
+
tuxcast doctor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<a href="https://achedon12.github.io/tuxcast/#intro">
|
|
57
|
+
<img src=".github/assets/intro-poster.jpg" alt="Watch tuxcast in 22 seconds" width="720"><br>
|
|
58
|
+
<sub>▶ Watch tuxcast in 22 seconds</sub>
|
|
59
|
+
</a>
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<p align="center">
|
|
63
|
+
<img src=".github/assets/terminal-doctor.svg" alt="tuxcast doctor checking a Stream Deck, Discord, Spotify and the network" width="820">
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
## Why
|
|
67
|
+
|
|
68
|
+
Streaming on Linux works well, until it doesn't, and it always breaks in the same places:
|
|
69
|
+
|
|
70
|
+
- 🎛️ **Your Stream Deck.** Elgato's app does not exist for Linux, and your 8 pages of keys need rebuilding by hand.
|
|
71
|
+
- 🔇 **Discord keys that do nothing.** Your Stream Deck app is a Flatpak, Discord is a snap, and neither can see the other.
|
|
72
|
+
- ⏯️ **Media buttons that do nothing either.** The Spotify snap ignores remote control.
|
|
73
|
+
- 🎚️ **One audio mix.** You can't keep the music out of your VODs or lower Discord alone.
|
|
74
|
+
- 📶 **"Unstable bitrate."** Twitch blames your connection and your speed test says it's fine (it's the Wi-Fi).
|
|
75
|
+
|
|
76
|
+
Each of these has a fix buried in a forum thread. tuxcast checks for all of them and applies the fixes.
|
|
77
|
+
|
|
78
|
+
## What it does
|
|
79
|
+
|
|
80
|
+
| Command | |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| [`tuxcast ui`](https://achedon12.github.io/tuxcast/commands/ui/) | Opens a control desk for everything below: a go-live tally, your Stream Deck and its pages, a mixer with faders, one-click fixes ([live demo](https://achedon12.github.io/tuxcast/demo/index.html)) |
|
|
83
|
+
| [`tuxcast doctor`](https://achedon12.github.io/tuxcast/commands/doctor/) | Checks display server, audio, GPU encoder, OBS, Stream Deck, Discord, Spotify and network. Each problem comes with its fix |
|
|
84
|
+
| [`tuxcast convert`](https://achedon12.github.io/tuxcast/commands/convert/) | Turns Elgato `.streamDeckProfile` exports into [StreamController](https://streamcontroller.core447.com/) pages: images, folders, multi actions, hotkeys (AZERTY and QWERTZ aware), OBS, Discord and Twitch keys |
|
|
85
|
+
| [`tuxcast bridge discord`](https://achedon12.github.io/tuxcast/commands/bridge/) | Exposes Discord's socket (snap, Vesktop, native) to Flatpak clients, and recreates the bridge at every login |
|
|
86
|
+
| [`tuxcast audio`](https://achedon12.github.io/tuxcast/commands/audio/) | Separate PipeWire sinks for game, music, voice and alerts, and routes apps to them |
|
|
87
|
+
| [`tuxcast deck`](https://achedon12.github.io/tuxcast/commands/deck/) | Lists Stream Decks, prints the udev rule they need, and resets one that froze after a crash, without unplugging it |
|
|
88
|
+
| [`tuxcast patch`](https://achedon12.github.io/tuxcast/commands/patch/) | Re-applies the fixes you made to app files every time an update wipes them |
|
|
89
|
+
|
|
90
|
+
### Or run it from a control desk
|
|
91
|
+
|
|
92
|
+
`tuxcast ui` opens a dashboard on your machine: a tally that tells you whether you can go live, your
|
|
93
|
+
Stream Deck with its real pages, a mixer with a fader per audio channel, and a button for every fix.
|
|
94
|
+
[Try the live demo](https://achedon12.github.io/tuxcast/demo/index.html), no install needed.
|
|
95
|
+
|
|
96
|
+
<p align="center">
|
|
97
|
+
<a href="https://achedon12.github.io/tuxcast/demo/index.html">
|
|
98
|
+
<img src="docs/assets/ui-desk.png" alt="The tuxcast dashboard: the tally, a Stream Deck with its pages, the checks and the audio mixer" width="900">
|
|
99
|
+
</a>
|
|
100
|
+
</p>
|
|
101
|
+
|
|
102
|
+
### Bring your Stream Deck profiles from Windows
|
|
103
|
+
|
|
104
|
+
<p align="center">
|
|
105
|
+
<img src=".github/assets/terminal-convert.svg" alt="tuxcast convert turning an Elgato profile into StreamController pages" width="760">
|
|
106
|
+
</p>
|
|
107
|
+
|
|
108
|
+
## Install
|
|
109
|
+
|
|
110
|
+
You need Python 3.11 or newer, which every current distribution ships.
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
pipx install git+https://github.com/achedon12/tuxcast.git
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
or `uv tool install git+https://github.com/achedon12/tuxcast.git`, or the
|
|
117
|
+
[installer script](install.sh) (`curl -fsSL https://raw.githubusercontent.com/achedon12/tuxcast/main/install.sh | sh`).
|
|
118
|
+
Then start with `tuxcast doctor`.
|
|
119
|
+
|
|
120
|
+
## Guides
|
|
121
|
+
|
|
122
|
+
The [website](https://achedon12.github.io/tuxcast/) (also in the [wiki](https://github.com/achedon12/tuxcast/wiki))
|
|
123
|
+
has a guide for each part of a Linux streaming setup, with the manual steps for people who
|
|
124
|
+
prefer to do it by hand:
|
|
125
|
+
|
|
126
|
+
[Streaming on Linux in 2026](https://achedon12.github.io/tuxcast/guides/streaming-on-linux/) ·
|
|
127
|
+
[OBS on Linux](https://achedon12.github.io/tuxcast/guides/obs/) ·
|
|
128
|
+
[Stream Deck on Linux](https://achedon12.github.io/tuxcast/guides/stream-deck/) ·
|
|
129
|
+
[Audio routing](https://achedon12.github.io/tuxcast/guides/audio/) ·
|
|
130
|
+
[Discord and Spotify in sandboxes](https://achedon12.github.io/tuxcast/guides/sandboxes/) ·
|
|
131
|
+
[Music without claims](https://achedon12.github.io/tuxcast/guides/music/) ·
|
|
132
|
+
[Network](https://achedon12.github.io/tuxcast/guides/network/)
|
|
133
|
+
|
|
134
|
+
## Principles
|
|
135
|
+
|
|
136
|
+
- **Reads before it writes.** `doctor` never changes anything. Other commands say what they wrote, and most take `--dry-run`.
|
|
137
|
+
- **Never needs root.** Everything happens in your user session. The one privileged step (the udev rule) is printed for you to run.
|
|
138
|
+
- **Zero dependencies.** Python's standard library only, so it installs in seconds and keeps working.
|
|
139
|
+
- **Explains itself.** Every warning says why it matters on stream and how to fix it.
|
|
140
|
+
|
|
141
|
+
## Roadmap
|
|
142
|
+
|
|
143
|
+
- [x] Doctor, converter, Discord bridge, audio sinks, deck tools, patch keeper
|
|
144
|
+
- [ ] `tuxcast obs`: apply encoder presets and multistream outputs to an OBS profile
|
|
145
|
+
- [ ] More Elgato plugins in `convert` (soundboard, Spotify, Voicemeeter equivalents)
|
|
146
|
+
- [ ] A `doctor --watch` mode to keep in an OBS dock while live
|
|
147
|
+
- [ ] Packages on PyPI and the AUR
|
|
148
|
+
|
|
149
|
+
Ideas and votes go to [Discussions](https://github.com/achedon12/tuxcast/discussions).
|
|
150
|
+
|
|
151
|
+
## Contributing
|
|
152
|
+
|
|
153
|
+
Every Linux setup is a little different, so your reports matter as much as code: a doctor
|
|
154
|
+
check that got your machine wrong, an Elgato action that didn't convert, a guide missing your
|
|
155
|
+
desktop. See [CONTRIBUTING.md](CONTRIBUTING.md). Issues labelled
|
|
156
|
+
[good first issue](https://github.com/achedon12/tuxcast/labels/good%20first%20issue) are a
|
|
157
|
+
good start; most Elgato mappings are one line.
|
|
158
|
+
|
|
159
|
+
If tuxcast saved your stream, a ⭐ helps other Linux streamers find it.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
[MIT](LICENSE). tuxcast is not affiliated with Elgato, OBS, Discord, Spotify or Twitch.
|
tuxcast-0.1.0/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/assets/banner.svg" alt="tuxcast: the toolkit for streaming on Linux" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/achedon12/tuxcast/actions/workflows/ci.yml"><img src="https://github.com/achedon12/tuxcast/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
7
|
+
<a href="https://github.com/achedon12/tuxcast/releases"><img src="https://img.shields.io/github/v/release/achedon12/tuxcast?color=8b5cf6&label=release" alt="Latest release"></a>
|
|
8
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-3776ab" alt="Python 3.11+">
|
|
9
|
+
<img src="https://img.shields.io/badge/dependencies-0-22c55e" alt="Zero dependencies">
|
|
10
|
+
<img src="https://img.shields.io/badge/root-not%20needed-22c55e" alt="No root needed">
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/achedon12/tuxcast?color=blue" alt="MIT license"></a>
|
|
12
|
+
<a href="https://achedon12.github.io/tuxcast/"><img src="https://img.shields.io/badge/docs-website-8b5cf6" alt="Documentation"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<b>English</b> · <a href="README.fr.md">Français</a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
**tuxcast** finds what will break your stream before you go live, then fixes it. It converts
|
|
20
|
+
your Elgato Stream Deck profiles, connects the apps Flatpak and snap keep apart, and splits
|
|
21
|
+
your audio so every source gets its own fader. One command each, no root, no dependencies.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pipx install git+https://github.com/achedon12/tuxcast.git
|
|
25
|
+
tuxcast doctor
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
<p align="center">
|
|
29
|
+
<a href="https://achedon12.github.io/tuxcast/#intro">
|
|
30
|
+
<img src=".github/assets/intro-poster.jpg" alt="Watch tuxcast in 22 seconds" width="720"><br>
|
|
31
|
+
<sub>▶ Watch tuxcast in 22 seconds</sub>
|
|
32
|
+
</a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src=".github/assets/terminal-doctor.svg" alt="tuxcast doctor checking a Stream Deck, Discord, Spotify and the network" width="820">
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
## Why
|
|
40
|
+
|
|
41
|
+
Streaming on Linux works well, until it doesn't, and it always breaks in the same places:
|
|
42
|
+
|
|
43
|
+
- 🎛️ **Your Stream Deck.** Elgato's app does not exist for Linux, and your 8 pages of keys need rebuilding by hand.
|
|
44
|
+
- 🔇 **Discord keys that do nothing.** Your Stream Deck app is a Flatpak, Discord is a snap, and neither can see the other.
|
|
45
|
+
- ⏯️ **Media buttons that do nothing either.** The Spotify snap ignores remote control.
|
|
46
|
+
- 🎚️ **One audio mix.** You can't keep the music out of your VODs or lower Discord alone.
|
|
47
|
+
- 📶 **"Unstable bitrate."** Twitch blames your connection and your speed test says it's fine (it's the Wi-Fi).
|
|
48
|
+
|
|
49
|
+
Each of these has a fix buried in a forum thread. tuxcast checks for all of them and applies the fixes.
|
|
50
|
+
|
|
51
|
+
## What it does
|
|
52
|
+
|
|
53
|
+
| Command | |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| [`tuxcast ui`](https://achedon12.github.io/tuxcast/commands/ui/) | Opens a control desk for everything below: a go-live tally, your Stream Deck and its pages, a mixer with faders, one-click fixes ([live demo](https://achedon12.github.io/tuxcast/demo/index.html)) |
|
|
56
|
+
| [`tuxcast doctor`](https://achedon12.github.io/tuxcast/commands/doctor/) | Checks display server, audio, GPU encoder, OBS, Stream Deck, Discord, Spotify and network. Each problem comes with its fix |
|
|
57
|
+
| [`tuxcast convert`](https://achedon12.github.io/tuxcast/commands/convert/) | Turns Elgato `.streamDeckProfile` exports into [StreamController](https://streamcontroller.core447.com/) pages: images, folders, multi actions, hotkeys (AZERTY and QWERTZ aware), OBS, Discord and Twitch keys |
|
|
58
|
+
| [`tuxcast bridge discord`](https://achedon12.github.io/tuxcast/commands/bridge/) | Exposes Discord's socket (snap, Vesktop, native) to Flatpak clients, and recreates the bridge at every login |
|
|
59
|
+
| [`tuxcast audio`](https://achedon12.github.io/tuxcast/commands/audio/) | Separate PipeWire sinks for game, music, voice and alerts, and routes apps to them |
|
|
60
|
+
| [`tuxcast deck`](https://achedon12.github.io/tuxcast/commands/deck/) | Lists Stream Decks, prints the udev rule they need, and resets one that froze after a crash, without unplugging it |
|
|
61
|
+
| [`tuxcast patch`](https://achedon12.github.io/tuxcast/commands/patch/) | Re-applies the fixes you made to app files every time an update wipes them |
|
|
62
|
+
|
|
63
|
+
### Or run it from a control desk
|
|
64
|
+
|
|
65
|
+
`tuxcast ui` opens a dashboard on your machine: a tally that tells you whether you can go live, your
|
|
66
|
+
Stream Deck with its real pages, a mixer with a fader per audio channel, and a button for every fix.
|
|
67
|
+
[Try the live demo](https://achedon12.github.io/tuxcast/demo/index.html), no install needed.
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<a href="https://achedon12.github.io/tuxcast/demo/index.html">
|
|
71
|
+
<img src="docs/assets/ui-desk.png" alt="The tuxcast dashboard: the tally, a Stream Deck with its pages, the checks and the audio mixer" width="900">
|
|
72
|
+
</a>
|
|
73
|
+
</p>
|
|
74
|
+
|
|
75
|
+
### Bring your Stream Deck profiles from Windows
|
|
76
|
+
|
|
77
|
+
<p align="center">
|
|
78
|
+
<img src=".github/assets/terminal-convert.svg" alt="tuxcast convert turning an Elgato profile into StreamController pages" width="760">
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
## Install
|
|
82
|
+
|
|
83
|
+
You need Python 3.11 or newer, which every current distribution ships.
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
pipx install git+https://github.com/achedon12/tuxcast.git
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
or `uv tool install git+https://github.com/achedon12/tuxcast.git`, or the
|
|
90
|
+
[installer script](install.sh) (`curl -fsSL https://raw.githubusercontent.com/achedon12/tuxcast/main/install.sh | sh`).
|
|
91
|
+
Then start with `tuxcast doctor`.
|
|
92
|
+
|
|
93
|
+
## Guides
|
|
94
|
+
|
|
95
|
+
The [website](https://achedon12.github.io/tuxcast/) (also in the [wiki](https://github.com/achedon12/tuxcast/wiki))
|
|
96
|
+
has a guide for each part of a Linux streaming setup, with the manual steps for people who
|
|
97
|
+
prefer to do it by hand:
|
|
98
|
+
|
|
99
|
+
[Streaming on Linux in 2026](https://achedon12.github.io/tuxcast/guides/streaming-on-linux/) ·
|
|
100
|
+
[OBS on Linux](https://achedon12.github.io/tuxcast/guides/obs/) ·
|
|
101
|
+
[Stream Deck on Linux](https://achedon12.github.io/tuxcast/guides/stream-deck/) ·
|
|
102
|
+
[Audio routing](https://achedon12.github.io/tuxcast/guides/audio/) ·
|
|
103
|
+
[Discord and Spotify in sandboxes](https://achedon12.github.io/tuxcast/guides/sandboxes/) ·
|
|
104
|
+
[Music without claims](https://achedon12.github.io/tuxcast/guides/music/) ·
|
|
105
|
+
[Network](https://achedon12.github.io/tuxcast/guides/network/)
|
|
106
|
+
|
|
107
|
+
## Principles
|
|
108
|
+
|
|
109
|
+
- **Reads before it writes.** `doctor` never changes anything. Other commands say what they wrote, and most take `--dry-run`.
|
|
110
|
+
- **Never needs root.** Everything happens in your user session. The one privileged step (the udev rule) is printed for you to run.
|
|
111
|
+
- **Zero dependencies.** Python's standard library only, so it installs in seconds and keeps working.
|
|
112
|
+
- **Explains itself.** Every warning says why it matters on stream and how to fix it.
|
|
113
|
+
|
|
114
|
+
## Roadmap
|
|
115
|
+
|
|
116
|
+
- [x] Doctor, converter, Discord bridge, audio sinks, deck tools, patch keeper
|
|
117
|
+
- [ ] `tuxcast obs`: apply encoder presets and multistream outputs to an OBS profile
|
|
118
|
+
- [ ] More Elgato plugins in `convert` (soundboard, Spotify, Voicemeeter equivalents)
|
|
119
|
+
- [ ] A `doctor --watch` mode to keep in an OBS dock while live
|
|
120
|
+
- [ ] Packages on PyPI and the AUR
|
|
121
|
+
|
|
122
|
+
Ideas and votes go to [Discussions](https://github.com/achedon12/tuxcast/discussions).
|
|
123
|
+
|
|
124
|
+
## Contributing
|
|
125
|
+
|
|
126
|
+
Every Linux setup is a little different, so your reports matter as much as code: a doctor
|
|
127
|
+
check that got your machine wrong, an Elgato action that didn't convert, a guide missing your
|
|
128
|
+
desktop. See [CONTRIBUTING.md](CONTRIBUTING.md). Issues labelled
|
|
129
|
+
[good first issue](https://github.com/achedon12/tuxcast/labels/good%20first%20issue) are a
|
|
130
|
+
good start; most Elgato mappings are one line.
|
|
131
|
+
|
|
132
|
+
If tuxcast saved your stream, a ⭐ helps other Linux streamers find it.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
[MIT](LICENSE). tuxcast is not affiliated with Elgato, OBS, Discord, Spotify or Twitch.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# contrib
|
|
2
|
+
|
|
3
|
+
Ready-made files for tuxcast and for people who prefer to set things up by hand.
|
|
4
|
+
|
|
5
|
+
| File | What it is |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| [`patches/twitch-oauth-port.toml`](patches/twitch-oauth-port.toml) | A [`tuxcast patch`](https://achedon12.github.io/tuxcast/commands/patch/) moving StreamController's Twitch login off port 3000 |
|
|
8
|
+
| [`udev/70-streamdeck.rules`](udev/70-streamdeck.rules) | The udev rule giving your user access to Elgato devices |
|
|
9
|
+
|
|
10
|
+
Have a patch that fixes an app for everyone? Add it here with a comment explaining why, and
|
|
11
|
+
open a pull request.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# StreamController's Twitch plugin listens on port 3000 for its OAuth login, which clashes with
|
|
2
|
+
# local web dev servers (Next.js, Vite, Rails…). This moves it to 6948.
|
|
3
|
+
#
|
|
4
|
+
# Install: cp twitch-oauth-port.toml ~/.config/tuxcast/patches/ && tuxcast patch install
|
|
5
|
+
# The plugin's Twitch application must allow the new redirect URI: http://localhost:6948/auth
|
|
6
|
+
|
|
7
|
+
file = "~/.var/app/com.core447.StreamController/data/plugins/com_imdevinc_StreamControllerTwitchPlugin/constants.py"
|
|
8
|
+
|
|
9
|
+
# Plugin updates delete and recreate the plugin folder, so watch its parent.
|
|
10
|
+
watch = "~/.var/app/com.core447.StreamController/data/plugins"
|
|
11
|
+
|
|
12
|
+
[[replace]]
|
|
13
|
+
pattern = '^OAUTH_PORT = \d+$'
|
|
14
|
+
with = "OAUTH_PORT = 6948"
|
|
15
|
+
|
|
16
|
+
[[replace]]
|
|
17
|
+
pattern = '^OAUTH_REDIRECT_URI = "http://localhost:\d+/auth"$'
|
|
18
|
+
with = 'OAUTH_REDIRECT_URI = "http://localhost:6948/auth"'
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Elgato Stream Deck: let the logged-in user talk to the device.
|
|
2
|
+
# Same rule as `tuxcast deck udev`. Install:
|
|
3
|
+
# sudo cp 70-streamdeck.rules /etc/udev/rules.d/
|
|
4
|
+
# sudo udevadm control --reload && sudo udevadm trigger
|
|
5
|
+
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", TAG+="uaccess"
|
|
6
|
+
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", TAG+="uaccess"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.25"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tuxcast"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "The toolkit for streaming on Linux: diagnose your setup, convert Elgato Stream Deck profiles, bridge sandboxed apps and split your audio."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE"]
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
|
+
authors = [{ name = "achedon12" }]
|
|
14
|
+
keywords = ["linux", "streaming", "obs", "stream-deck", "streamcontroller", "twitch", "pipewire", "discord", "flatpak"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: End Users/Desktop",
|
|
19
|
+
"Operating System :: POSIX :: Linux",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
25
|
+
"Topic :: Multimedia :: Video :: Capture",
|
|
26
|
+
"Topic :: Utilities",
|
|
27
|
+
]
|
|
28
|
+
# No runtime dependencies on purpose: tuxcast must install anywhere with pipx in seconds.
|
|
29
|
+
dependencies = []
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://achedon12.github.io/tuxcast/"
|
|
33
|
+
Documentation = "https://achedon12.github.io/tuxcast/"
|
|
34
|
+
Repository = "https://github.com/achedon12/tuxcast"
|
|
35
|
+
Issues = "https://github.com/achedon12/tuxcast/issues"
|
|
36
|
+
Changelog = "https://github.com/achedon12/tuxcast/blob/main/CHANGELOG.md"
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
tuxcast = "tuxcast.cli:main"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.version]
|
|
42
|
+
path = "src/tuxcast/__init__.py"
|
|
43
|
+
|
|
44
|
+
[tool.hatch.build.targets.sdist]
|
|
45
|
+
include = ["src", "tests", "contrib", "README.md", "CHANGELOG.md", "LICENSE"]
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
testpaths = ["tests"]
|
|
49
|
+
addopts = "-ra"
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
line-length = 120
|
|
53
|
+
target-version = "py311"
|
|
54
|
+
src = ["src", "tests"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff.lint]
|
|
57
|
+
select = ["E", "F", "W", "I", "B", "UP", "SIM", "RUF", "PTH", "PL"]
|
|
58
|
+
ignore = [
|
|
59
|
+
"PLR0911", "PLR0912", "PLR0913", "PLR0915", "PLR0917", "PLR2004", "PLW0603",
|
|
60
|
+
"PLC0415", # lazy imports keep `tuxcast --help` fast and register doctor checks on demand
|
|
61
|
+
"RUF001", # the CLI prints symbols such as ✔ on purpose
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint.per-file-ignores]
|
|
65
|
+
"tests/**" = ["PLR2004", "PLC0415"]
|
|
66
|
+
".github/scripts/render-terminal.py" = ["E501"] # the SVG template reads best unwrapped
|