# Setup Guide

Setup instructions for the ABCC Media Server at `/var/www/html/media`.

## Dependencies

Install these on the server before running any scripts:

```bash
# yt-dlp (video downloader)
sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \
     -o /usr/local/bin/yt-dlp && sudo chmod +x /usr/local/bin/yt-dlp

# ffmpeg + ffprobe
sudo apt install -y ffmpeg

# jq (JSON processor — required by live stream scripts)
sudo apt install -y jq

# php-cli (required by sync scripts)
sudo apt install -y php-cli

# python3 (required by getPlaylist.sh and gen_banners.py)
sudo apt install -y python3
```

## Configuration

All paths and URLs are defined in `config.php` at the project root. Every PHP
file and shell script derives its paths from this file — no hardcoded paths.

```php
// config.php (excerpt)
define('BASE',        '/var/www/html/media');
define('DATA_DIR',    BASE . '/data');
define('VIDEOS_DIR',  BASE . '/videos');
define('SCRIPTS_DIR', BASE . '/scripts');
define('YT_KEY_FILE', DATA_DIR . '/yt_key.txt');
define('COOKIES_FILE', DATA_DIR . '/cookies.txt');
```

## YouTube API Key

Place your YouTube Data API v3 key in:

```
/var/www/html/media/data/yt_key.txt
```

This file is git-ignored. It is read by `scripts/getPlaylist.sh` and other scripts
that call the YouTube Data API.

## Cookies File

To download age-restricted or members-only videos, export your browser cookies
in Netscape format. Upload via the admin page at `/admin/uploadCookies.php`, or
place the file directly at:

```
/var/www/html/media/data/cookies.txt
```

Recommended browser extension: **Get cookies.txt LOCALLY** (Chrome / Firefox).

> Both files are git-ignored.

## Sync Pipeline

The sync pipeline keeps video libraries up to date. Run via cron or manually:

```bash
bash /var/www/html/media/scripts/run.sh
```

`run.sh` runs in sequence:

1. **`Process.php`** — reads `data/playlists.json`, fetches video IDs from WordPress
   or YouTube, downloads missing MP4s, JPGs, and JSON sidecars into `videos/{id}/`
2. **`genFeed.php`** — regenerates `roku/feeds/primary-feed.json`
3. **`generate_daily_plan.php`** — regenerates `data/daily-plan.json`
4. **`encode_videos.sh`** — encodes new MP4s into HLS segments under `live/hls/`
5. **`gen_banners.py`** — regenerates banner images

### Cron (recommended: daily at 2 am)

```
0 2 * * * bash /var/www/html/media/scripts/run.sh >> /var/www/html/media/logs/run.log 2>&1
```

## Live Stream

The live stream is managed by a systemd service:

```bash
sudo systemctl status abcc-live
sudo systemctl restart abcc-live
```

The service runs `scripts/setup.sh` (which launches FFmpeg), reading
`data/daily-plan.json` to determine the current video.

### Now-Playing Update (cron — every 5 minutes)

```
*/5 * * * * bash /var/www/html/media/scripts/update_now_playing.sh
```

Writes `roku/now-playing.json` consumed by the Roku app.

## Script Reference

| Script | Purpose |
|--------|---------|
| `run.sh` | Master entry point — runs all sync steps in order |
| `Process.php` | Fetches playlists and downloads missing videos |
| `getFromWP.php` | Fetches video metadata from WordPress REST API |
| `getPlaylist.sh` | Fetches YouTube playlist video IDs via Data API |
| `getVideo.sh` | Downloads a single video (mp4 / jpg / json) via yt-dlp |
| `genFeed.php` | Generates Roku JSON feed |
| `generate_daily_plan.php` | Builds `data/daily-plan.json` from schedule + packages |
| `encode_videos.sh` | Encodes MP4s into HLS segments |
| `update_now_playing.sh` | Writes `roku/now-playing.json` |
| `normalize_lists.php` | Upgrades any list.txt files to 3-column format |
| `validate_plan.php` | Validates the daily plan against now-playing |
| `gen_banners.py` | Generates schedule banner images |
| `setup.sh` | Systemd service helper (starts FFmpeg playout) |

All scripts are in `scripts/`. Shell scripts self-locate via:

```bash
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
BASE_DIR="$(dirname "$SCRIPT_DIR")"
```

## Directory Layout

```
/var/www/html/media/
├── config.php              Global path & URL constants (single source of truth)
├── data/
│   ├── playlists.json      Playlist definitions (WP category or YouTube playlist)
│   ├── schedule.json       Playout schedule (defaults + date overrides)
│   ├── packages.json       Content packages referenced by schedule
│   ├── daily-plan.json     Pre-computed 30-hour playout plan
│   ├── yt_key.txt          YouTube Data API key (git-ignored)
│   └── cookies.txt         yt-dlp auth cookies (git-ignored)
├── admin/                  Admin dashboard (PHP pages + shared classes)
│   ├── Schedule.php        Schedule data class
│   ├── Playlist.php        Playlist data class
│   ├── VideoLibrary.php    Video disk utilities (duration, title, path)
│   ├── DailyPlan.php       Daily plan loader with current-entry lookup
│   └── *.php               Admin UI pages
├── scripts/                All CLI scripts (sync, encoding, live stream)
├── videos/                 Downloaded video files (git-ignored)
│   └── {playlist-id}/
│       ├── list.txt        Tab-separated: date \t videoId \t title (oldest first)
│       ├── {videoId}.mp4
│       ├── {videoId}.jpg   Thumbnail
│       └── {videoId}.json  Metadata sidecar (duration, title, upload_date)
├── live/
│   ├── stream.php          HLS stream endpoint
│   └── hls/                Per-video HLS segment cache
└── roku/
    ├── feeds/primary-feed.json   Roku Direct Publisher feed
    └── now-playing.json          Current block/video info (updated by cron)
```
