Settings page saved to /config/settings.json but nothing downstream read that file. Schedule changes were silently ignored; max_quality and sleep_interval changes were silently ignored. The "Settings saved successfully" flash was a lie. Fix: - sync.sh reads max_quality + sleep_interval from settings.json on each run (jq -er ... // empty, falling back to env vars on missing/malformed file) - entrypoint.sh reads sync_schedule from settings.json before setting up cron, and writes the crond PID to /var/run/crond.pid so Flask can SIGHUP it - app.py adds apply_schedule(): rewrites /etc/crontabs/root, signals crond via the recorded PID, restarts crond if the PID is stale, drops the crontab when schedule is set to "manual". save_settings_route invokes it only when the schedule actually changed; any failure flashes a warning so the save still succeeds with the user informed - bare `except: pass` in get_settings replaced with explicit exception types + stderr warning so debugging malformed settings is possible - sync.sh: one bad channel no longer aborts the whole loop under set -e - Dockerfile adds jq for the JSON reads in sync.sh / entrypoint.sh - README: two stale github.com URLs fixed to Gitea; new Running Tests section under Building From Source - tests/test_settings.py: 3 pytest cases covering get_settings()'s three branches (missing file, valid file, malformed JSON) Settings hierarchy unchanged: env-var defaults seed the UI; settings.json wins when present and parseable. Timezone (TZ) is not applied live - tzdata is locked in at process start. Same behavior as before; not in scope for this commit.
204 lines
5.7 KiB
Markdown
204 lines
5.7 KiB
Markdown
# YouTube Channel Sync Docker
|
|
|
|
Automatically download and organize YouTube channel videos for Emby, Plex, or Jellyfin media servers with a built-in web UI for easy configuration.
|
|
|
|
## Features
|
|
|
|
- **Web-based configuration interface** - No more editing text files!
|
|
- Downloads videos in best quality up to 1080p (configurable)
|
|
- Organizes videos by season folders (year-based)
|
|
- Proper episode naming for media servers: `S2026E001 - Video Title - [VideoID].mp4`
|
|
- Embeds thumbnails and metadata
|
|
- Creates `tvshow.nfo` files for Emby/Plex
|
|
- Tracks downloaded videos to avoid re-downloading
|
|
- Supports YouTube cookies for authentication (bypasses bot detection)
|
|
- Scheduled automatic syncs via cron
|
|
- Real-time sync status and logs
|
|
- Lightweight Alpine Linux base (~250MB)
|
|
|
|
## Quick Start (Unraid)
|
|
|
|
1. Install from Community Applications: Search for "YouTube Sync"
|
|
2. Configure paths:
|
|
- Web UI Port: `8080` (or choose another port)
|
|
- Download Directory: `/mnt/user/media/YouTube` (or your media location)
|
|
- Config Directory: `/mnt/user/appdata/youtube-sync`
|
|
3. Start the container
|
|
4. Open the web UI at `http://YOUR-SERVER-IP:8080`
|
|
5. Add channels, configure settings, and upload cookies (optional) through the web interface
|
|
|
|
## Configuration
|
|
|
|
### channels.txt Format
|
|
|
|
```
|
|
# Format: CHANNEL_ID|Channel Name
|
|
UCfDNi1aEljAQ17mUrfUjkvg|Alton Brown
|
|
UCoq2qlWgvvKJzW_hBkLIE8w|Flavour Trip
|
|
```
|
|
|
|
**Finding Channel IDs:**
|
|
1. Go to the channel's main page on YouTube
|
|
2. View page source (Ctrl+U or Cmd+U)
|
|
3. Search for "channelId" or check the URL structure
|
|
|
|
### YouTube Cookies (Optional but Recommended)
|
|
|
|
YouTube may block downloads without authentication. To fix this:
|
|
|
|
**Method 1: Browser Extension**
|
|
1. Install "Get cookies.txt LOCALLY" extension for Firefox/Chrome
|
|
2. Go to YouTube.com while logged in
|
|
3. Click the extension icon and export cookies
|
|
4. Save as `/mnt/user/appdata/youtube-sync/cookies.txt`
|
|
|
|
**Method 2: yt-dlp command**
|
|
```bash
|
|
yt-dlp --cookies-from-browser firefox --cookies cookies.txt --skip-download "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
```
|
|
|
|
## Web UI
|
|
|
|
The container includes a built-in web interface for easy management:
|
|
|
|
- **Dashboard**: View sync status, channel statistics, and recent activity
|
|
- **Channels**: Add, remove, and manage YouTube channels
|
|
- **Settings**: Configure sync schedule, video quality, and other options
|
|
- **Cookies**: Upload YouTube cookies for authentication
|
|
- **Logs**: Real-time view of sync progress and errors
|
|
|
|
Access the web UI at: `http://YOUR-SERVER-IP:8080`
|
|
|
|
All configuration can be done through the web interface - no need to manually edit config files!
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `SYNC_SCHEDULE` | `0 2 * * *` | Cron schedule (2 AM daily). Use `manual` to disable. |
|
|
| `MAX_QUALITY` | `1080` | Maximum video quality (480, 720, 1080, 1440, 2160) |
|
|
| `SLEEP_INTERVAL` | `2` | Seconds between downloads (helps avoid rate limiting) |
|
|
| `TZ` | `America/Phoenix` | Timezone for scheduling |
|
|
| `PUID` | `99` | User ID for file ownership |
|
|
| `PGID` | `100` | Group ID for file ownership |
|
|
|
|
## Docker Compose
|
|
|
|
```yaml
|
|
version: '3'
|
|
services:
|
|
youtube-sync:
|
|
image: azcomputerguru/youtube-sync:latest
|
|
container_name: youtube-sync
|
|
ports:
|
|
- "8080:8080"
|
|
environment:
|
|
- SYNC_SCHEDULE=0 2 * * *
|
|
- MAX_QUALITY=1080
|
|
- SLEEP_INTERVAL=2
|
|
- TZ=America/Phoenix
|
|
- PUID=99
|
|
- PGID=100
|
|
volumes:
|
|
- /mnt/user/media/YouTube:/downloads
|
|
- /mnt/user/appdata/youtube-sync:/config
|
|
restart: unless-stopped
|
|
```
|
|
|
|
## Docker CLI
|
|
|
|
```bash
|
|
docker run -d \
|
|
--name youtube-sync \
|
|
-p 8080:8080 \
|
|
-e SYNC_SCHEDULE="0 2 * * *" \
|
|
-e MAX_QUALITY=1080 \
|
|
-e TZ=America/Phoenix \
|
|
-v /mnt/user/media/YouTube:/downloads \
|
|
-v /mnt/user/appdata/youtube-sync:/config \
|
|
azcomputerguru/youtube-sync:latest
|
|
```
|
|
|
|
## Manual Sync
|
|
|
|
To run a sync immediately:
|
|
|
|
```bash
|
|
docker exec youtube-sync /app/sync.sh
|
|
```
|
|
|
|
## Output Structure
|
|
|
|
```
|
|
/downloads/
|
|
├── Alton Brown/
|
|
│ ├── tvshow.nfo
|
|
│ ├── .downloaded.txt (tracking file)
|
|
│ ├── Season 2024/
|
|
│ │ ├── S2024E001 - Title - [VideoID].mp4
|
|
│ │ ├── S2024E001 - Title - [VideoID].info.json
|
|
│ │ └── ...
|
|
│ └── Season 2025/
|
|
│ └── ...
|
|
└── Flavour Trip/
|
|
├── tvshow.nfo
|
|
└── Season 2026/
|
|
└── ...
|
|
```
|
|
|
|
## Emby/Plex Setup
|
|
|
|
1. Add the download directory as a TV Shows library
|
|
2. Use "Local Media Assets (TV)" scanner
|
|
3. Episodes will appear organized by channel name and year
|
|
|
|
## Troubleshooting
|
|
|
|
### "Sign in to confirm you're not a bot" Error
|
|
|
|
YouTube is blocking downloads. Solution: Add cookies.txt (see Configuration section)
|
|
|
|
### Videos Not Downloading
|
|
|
|
1. Check `channels.txt` format (must be `CHANNEL_ID|Name`, no spaces around `|`)
|
|
2. Verify channel IDs are correct
|
|
3. Check container logs: `docker logs youtube-sync`
|
|
4. Ensure `/downloads` directory is writable
|
|
|
|
### Scheduling Not Working
|
|
|
|
1. Verify cron schedule format is correct
|
|
2. Check timezone is set properly
|
|
3. Set `SYNC_SCHEDULE=manual` and run manually to test
|
|
4. Check logs: `docker logs youtube-sync`
|
|
|
|
## Building From Source
|
|
|
|
```bash
|
|
git clone https://git.azcomputerguru.com/azcomputerguru/youtube-sync-docker
|
|
cd youtube-sync-docker
|
|
docker build -t youtube-sync .
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
Tests are dev-only and not bundled into the production image. Install the
|
|
dev dependencies and run pytest from the repo root:
|
|
|
|
```bash
|
|
pip install -r requirements-dev.txt
|
|
pytest tests/
|
|
```
|
|
|
|
## Support
|
|
|
|
Issues and pull requests: https://git.azcomputerguru.com/azcomputerguru/youtube-sync-docker
|
|
|
|
## License
|
|
|
|
MIT License - See LICENSE file for details
|
|
|
|
## Credits
|
|
|
|
Built by Arizona Computer Guru LLC using [yt-dlp](https://github.com/yt-dlp/yt-dlp)
|