47de94a3df
The core conversion helper is in [includes/db.php (line 1161)](/Users/tyemeclifford/Documents/GH/mediaplayer/includes/db.php:1161). The upload flows insert the converted MP4 first for playback and retain the original M4A as a separate source in [admin/add.php (line 129)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/add.php:129) and [admin/edit.php (line 172)](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/edit.php:172). I also updated the admin upload hints, [README.md (line 77)](/Users/tyemeclifford/Documents/GH/mediaplayer/README.md:77), and [changelog.md (line 14)](/Users/tyemeclifford/Documents/GH/mediaplayer/changelog.md:14).
173 lines
8.7 KiB
Markdown
173 lines
8.7 KiB
Markdown
# TyClifford.com — Media Player
|
||
|
||
A self-hosted multimedia player website built with PHP + SQLite + Video.js.
|
||
Styled to match the existing `gate.php` / `index.php` dark theme exactly.
|
||
|
||
|
||
---
|
||
|
||
## Requirements
|
||
|
||
- PHP 8.0+ with `pdo_sqlite`, `fileinfo` extensions
|
||
- Apache `mod_rewrite` for default pretty URLs, or switch to query URLs in Admin → Settings
|
||
- Write permissions on the `data/` and `media/` directories
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
1. **Upload** all files to your web server. To use domain-level pretty URLs such as `/v/my-video`, deploy the app at the web root.
|
||
|
||
2. **Set permissions** so PHP can write to these directories:
|
||
```bash
|
||
mkdir -p data media/videos media/thumbs
|
||
chmod 755 data media media/videos media/thumbs
|
||
```
|
||
|
||
3. **Visit** `index.php` — the SQLite database is created automatically on first load.
|
||
|
||
4. **Log into admin** at `admin/login.php`
|
||
- Default password: **`admin`**
|
||
- ⚠️ Change it immediately in **Admin → Settings → Change Password**
|
||
|
||
---
|
||
|
||
## File Structure
|
||
|
||
```
|
||
/ ← web root (deploy here)
|
||
├── index.php ← Main player + catalogue (home page)
|
||
├── catalogue.php ← Full video catalogue browse page
|
||
├── .htaccess ← Pretty URL rewrite rules
|
||
├── includes/
|
||
│ ├── db.php ← SQLite bootstrap + helper functions
|
||
│ └── layout.php ← Shared HTML head, topbar, footer, pagination
|
||
├── admin/
|
||
│ ├── index.php ← Video list with search + pagination
|
||
│ ├── add.php ← Add new video with uploaded or external URL sources
|
||
│ ├── edit.php ← Edit video metadata + manage local/remote sources
|
||
│ ├── youtube_import.php ← Scrape a YouTube channel and import videos
|
||
│ ├── settings.php ← Site settings, per-page count, password
|
||
│ ├── login.php ← Admin login
|
||
│ ├── logout.php ← Session destroy + redirect
|
||
│ └── auth.php ← Session auth helpers
|
||
├── media/ ← All media files (created automatically)
|
||
│ ├── videos/ ← Uploaded video files
|
||
│ └── thumbs/ ← Uploaded thumbnail images
|
||
└── data/
|
||
└── media.db ← SQLite database (auto-created)
|
||
```
|
||
|
||
---
|
||
|
||
## Usage
|
||
|
||
### Adding Videos (Admin)
|
||
|
||
1. Go to `admin/add.php`
|
||
2. Fill in title, description, duration, sort order, or paste an external URL and click **Fetch Info** to auto-fill readable metadata
|
||
3. Upload a thumbnail (JPG/PNG/WebP)
|
||
4. Add one or more video sources. Each source can be either:
|
||
- an uploaded local video file, stored under `media/videos/`
|
||
- an external URL, stored in SQLite and played as a direct media source or provider embed
|
||
5. For uploaded files, supported formats include:
|
||
- **MP4** (H.264) — widest compatibility
|
||
- **WebM** (VP9) — smaller size, modern browsers
|
||
- **OGV** — Firefox fallback (legacy)
|
||
- **M4A** — kept as an original source and converted to a black-frame H.264 MP4 companion source when `ffmpeg` is installed
|
||
6. Set quality labels (1080p, 720p, 480p, etc.)
|
||
7. Save — Video.js will use the stored source location and auto-select the best format the browser supports
|
||
|
||
External URLs must use `http://` or `https://`. Uploaded files and remote URLs can be mixed on the same video. Recognized provider URLs such as YouTube, Vimeo, Dailymotion, Twitch, Facebook, TikTok, Instagram, X/Twitter, SoundCloud, Spotify, Google Drive, Wistia, Streamable, and Loom render through their embed players.
|
||
|
||
When adding an external URL, the admin form can fetch title, description, duration, thumbnail metadata, and readable provider view counts through oEmbed, page metadata, and JSON-LD. The save action repeats the metadata lookup as a fallback, so blank titles can be filled from supported external pages even if the browser autofill was not used.
|
||
|
||
If no thumbnail image is uploaded, the add/edit forms can auto-grab one from the first supported source. YouTube and Dailymotion use direct thumbnail URLs; Vimeo, Wistia, TikTok, SoundCloud, and Spotify use oEmbed when available. Local uploaded videos can generate a first-frame thumbnail when `ffmpeg` is installed on the server. Uploaded M4A files also use `ffmpeg` to create a black-frame H.264 MP4 playback source while keeping the original M4A source.
|
||
|
||
### Live Homepage Option
|
||
|
||
The homepage can show a **Videos / Live** switch above the main player. Configure it in **Admin → Settings → Live Section** with either a direct embeddable URL or an iframe snippet. The default live embed is `https://stream.place/embed/tyclifford.com`. Use `?land=live` on the homepage URL to open with the live embed displayed first. Disable the setting to return the homepage to the normal video-only layout.
|
||
|
||
### Importing YouTube Channels
|
||
|
||
Use **Admin → YouTube Importer** to paste a YouTube channel URL, `@handle`, or `UC...` channel ID. The importer scrapes the channel's `/videos` page, extracts video data from `ytInitialData`, previews the results, and imports selected videos as remote YouTube embed sources. Duplicate YouTube watch URLs are skipped.
|
||
|
||
Imported YouTube videos use the video's original publish date for the database `created_at` timestamp when YouTube exposes it. The admin dashboard also includes **Upkeeping → Correct YouTube timestamps** to backfill existing YouTube entries in batches. Use **Upkeeping → Correct catalogue order** to rebuild catalogue sorting from those publish dates so newer dated videos appear first.
|
||
|
||
### View Counts and Public Statistics
|
||
|
||
Each public player load increments the video's site-local `view_count`, including standalone embeds served through `embed.php`. External provider totals are stored separately as `external_view_count`, and public totals add local and external counts together. View counts appear in the admin video list and can be edited per video from **Admin → Edit Video** for older local uploads or manual corrections.
|
||
|
||
The public display is configurable in **Admin → Settings → Public Display**:
|
||
|
||
- show or hide per-video view counts
|
||
- show or hide the total public view count
|
||
- show or hide public page statistics on the homepage and catalogue
|
||
|
||
The admin dashboard also includes **Upkeeping → Correct external view counts**. It checks existing remote-source videos in batches, scrapes readable provider counts when available, and adds those provider totals to the media-site totals without double-counting local plays. YouTube has dedicated handling, and generic metadata patterns cover readable Vimeo, Dailymotion, and similar provider pages when they expose counts. Unsupported providers and local-only uploads can still be corrected manually on the edit screen.
|
||
|
||
### Public Search
|
||
|
||
The full catalogue page includes a public search for published videos only. Search matches video title, description, and slug; draft videos remain hidden.
|
||
|
||
### Public URLs
|
||
|
||
Pretty URLs are enabled by default:
|
||
|
||
- `/v/<slug>` plays a video
|
||
- `/all` lists all public videos
|
||
- `/search/<query>` searches public videos
|
||
|
||
You can switch to PHP query URLs in **Admin → Settings → Public URL Style** if your host does not support `.htaccess` rewrites.
|
||
|
||
### Catalogue Per-Page
|
||
|
||
Configurable in **Admin → Settings → Videos per page** (1–50).
|
||
The home page catalogue and the full catalogue page both respect this setting.
|
||
|
||
### Publishing
|
||
|
||
Videos can be toggled between **Published** and **Draft** from the admin list.
|
||
Only published videos appear on the public-facing pages.
|
||
|
||
### Sorting
|
||
|
||
Use the **Sort Order** field — lower numbers appear first. Default is 0. The **Upkeeping → Correct catalogue order** action can recalculate sort order from video publish dates, newest first.
|
||
|
||
---
|
||
|
||
## Player Features
|
||
|
||
- **Video.js 8.x** — responsive, accessible HTML5 player
|
||
- Custom skin matching the site's dark purple/green theme
|
||
- Playback rate controls: 0.5×, 1×, 1.25×, 1.5×, 2×
|
||
- Multiple source fallback — browser picks best format automatically
|
||
- Local uploaded sources and remote URL sources
|
||
- M4A uploads can add a generated black-frame H.264 MP4 companion source
|
||
- Provider embeds for popular video and audio platforms
|
||
- Thumbnail posters
|
||
- Per-video view counts and optional public library statistics
|
||
- Keyboard accessible
|
||
|
||
---
|
||
|
||
## Security Notes
|
||
|
||
- Change the default admin password (`admin`) immediately after setup
|
||
- Consider adding `.htaccess` HTTP auth or IP restriction to `/admin/`
|
||
- The `data/` directory should not be web-accessible; add to `.htaccess`:
|
||
```apache
|
||
<Directory data>
|
||
Require all denied
|
||
</Directory>
|
||
```
|
||
- For production, consider adding CSRF tokens to admin forms
|
||
|
||
---
|
||
|
||
## Customisation
|
||
|
||
- **Branding**: Edit site title/subtitle in Admin → Settings
|
||
- **Theme colours**: All CSS variables are in `includes/layout.php` `:root {}`
|
||
- **Social links**: Edit the About/Links cards in `index.php`
|