Skip to content

Commit 5a4cf52

Browse files
authored
Merge pull request #1 from sumitake/codex/generic-autoencoder-initial
[codex] Add generic YouTube AutoEncoder
2 parents 22302bb + 1bd2c67 commit 5a4cf52

9 files changed

Lines changed: 1449 additions & 2 deletions

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
__pycache__/
2+
*.py[cod]
3+
.DS_Store
4+
5+
# Local config and secrets
6+
.env
7+
*.env
8+
google-oauth-client.json
9+
youtube-token.json
10+
youtube-live-state.json
11+
.config/
12+
13+
# Runtime captures
14+
*.flv
15+
*.mkv
16+
*.mp4

README.md

Lines changed: 158 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,158 @@
1-
# YouTube-AutoEncoder
2-
Automated Headless Live Stream Encoder
1+
# YouTube AutoEncoder
2+
3+
YouTube AutoEncoder is a headless live-stream bridge for unattended cameras and other RTSP-style sources. It runs FFmpeg under systemd and can manage the YouTube Live broadcast lifecycle through the YouTube Data API.
4+
5+
The intended deployment target is a small Linux host such as a Raspberry Pi that should survive:
6+
7+
- camera power loss
8+
- encoder process crashes
9+
- host reboots
10+
- network interruptions
11+
- YouTube broadcasts ending when ingest stops
12+
13+
## What It Does
14+
15+
- Probes the source before creating a YouTube broadcast.
16+
- Creates a new YouTube broadcast only after the source is reachable.
17+
- Binds the broadcast to a reusable YouTube live stream.
18+
- Starts FFmpeg ingest.
19+
- Waits for YouTube to report ingest as active.
20+
- Transitions the broadcast through `testing` and then `live`.
21+
- Completes the broadcast when ingest exits.
22+
- Retries from the top until the source returns.
23+
24+
## Repository Layout
25+
26+
```text
27+
bin/youtube-autoencoder Production FFmpeg + lifecycle supervisor
28+
bin/youtube-autoencoder-api YouTube OAuth and Live Streaming API helper
29+
bin/youtube-autoencoder-test-pattern Temporary moving test-pattern stream
30+
config/youtube-autoencoder.env.example
31+
systemd/youtube-autoencoder@.service System service template
32+
systemd/user/youtube-autoencoder.service User service template
33+
docs/raspberry-pi.md Raspberry Pi deployment notes
34+
```
35+
36+
## Requirements
37+
38+
- Linux with systemd
39+
- Python 3.11 or newer
40+
- FFmpeg and FFprobe
41+
- A YouTube channel with live streaming enabled
42+
- A Google OAuth client JSON file for an installed/device-style app
43+
44+
No third-party Python packages are required.
45+
46+
## Quick Install
47+
48+
Install the scripts:
49+
50+
```bash
51+
sudo install -m 0755 bin/youtube-autoencoder /usr/local/bin/youtube-autoencoder
52+
sudo install -m 0755 bin/youtube-autoencoder-api /usr/local/bin/youtube-autoencoder-api
53+
sudo install -m 0755 bin/youtube-autoencoder-test-pattern /usr/local/bin/youtube-autoencoder-test-pattern
54+
```
55+
56+
Create a config directory for the service user:
57+
58+
```bash
59+
mkdir -p ~/.config/youtube-autoencoder
60+
cp config/youtube-autoencoder.env.example ~/.config/youtube-autoencoder/youtube-autoencoder.env
61+
chmod 600 ~/.config/youtube-autoencoder/youtube-autoencoder.env
62+
```
63+
64+
Edit the env file for your source and YouTube settings.
65+
66+
Install a service. For a system service running as user `encoder`:
67+
68+
```bash
69+
sudo install -m 0644 systemd/youtube-autoencoder@.service /etc/systemd/system/youtube-autoencoder@.service
70+
sudo systemctl daemon-reload
71+
sudo systemctl enable --now youtube-autoencoder@encoder.service
72+
```
73+
74+
For a user service:
75+
76+
```bash
77+
mkdir -p ~/.config/systemd/user
78+
cp systemd/user/youtube-autoencoder.service ~/.config/systemd/user/
79+
systemctl --user daemon-reload
80+
systemctl --user enable --now youtube-autoencoder.service
81+
```
82+
83+
## YouTube Authorization
84+
85+
Create an OAuth client in Google Cloud Console and place the downloaded JSON at:
86+
87+
```text
88+
~/.config/youtube-autoencoder/google-oauth-client.json
89+
```
90+
91+
Then run:
92+
93+
```bash
94+
youtube-autoencoder-api authorize
95+
```
96+
97+
Open the displayed device-flow URL, enter the code, and approve access for the YouTube channel account. The refresh token is stored at:
98+
99+
```text
100+
~/.config/youtube-autoencoder/youtube-token.json
101+
```
102+
103+
Keep both files private.
104+
105+
## Source Configuration
106+
107+
The simplest configuration is a direct RTSP source:
108+
109+
```text
110+
YTA_SOURCE_URL=rtsp://camera.example.local/stream1
111+
```
112+
113+
Alternatively, the encoder can reuse an OBS profile and scene collection:
114+
115+
```text
116+
YTA_OBS_SERVICE_FILE=/home/encoder/.config/obs-studio/basic/profiles/Stream/service.json
117+
YTA_OBS_SCENE_FILE=/home/encoder/.config/obs-studio/basic/scenes/Untitled.json
118+
YTA_OBS_SOURCE_NAME=Camera RTSP
119+
```
120+
121+
The OBS service file supplies the reusable YouTube RTMPS server and stream key. If YouTube AutoEncoder creates a reusable stream through the API, it updates that service file.
122+
123+
## Normal Operation
124+
125+
```bash
126+
systemctl status youtube-autoencoder@encoder.service
127+
journalctl -u youtube-autoencoder@encoder.service -f
128+
youtube-autoencoder-api status
129+
```
130+
131+
When the camera is offline, the service stays active but does not run FFmpeg and does not create YouTube broadcasts. Logs will show source-probe failures and retry timing.
132+
133+
When the camera comes back, the service creates and starts a fresh YouTube broadcast automatically.
134+
135+
## Test Pattern
136+
137+
To visually validate YouTube ingest quality:
138+
139+
```bash
140+
youtube-autoencoder-test-pattern 900
141+
```
142+
143+
For a complete visible API-managed test:
144+
145+
```bash
146+
youtube-autoencoder-api run-visible-test --duration 900 --privacy unlisted
147+
```
148+
149+
## Security Notes
150+
151+
- Do not commit OAuth client files, refresh tokens, stream keys, or `.env` files.
152+
- The scripts redact RTSP credentials and YouTube stream keys from their own logs.
153+
- System process listings can still expose full FFmpeg command lines to privileged local users while a stream is active.
154+
- Use a dedicated Google OAuth client and a dedicated encoder user where practical.
155+
156+
## License
157+
158+
MPL-2.0. See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)