- Implemented audio support with Video.js.
What changed: Added uploaded/direct audio playback paths in [index.php](/Users/tyemeclifford/Documents/GH/mediaplayer/index.php) and [embed.php](/Users/tyemeclifford/Documents/GH/mediaplayer/embed.php). Added common audio upload support: MP3, M4A, AAC, WAV, FLAC, OGG, OGA, OPUS. Added waveform poster generation for uploaded audio via ffmpeg, stored like normal thumbnails under media/thumbs/. Updated add/edit forms to accept media files, not just video files. Added audio-friendly labels like Audio, 320kbps, 256kbps, 128kbps. Updated docs and changelog.
This commit is contained in:
+27
-19
@@ -88,7 +88,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
||||
$inserted_sources = 0;
|
||||
$moved_files = [];
|
||||
$allowed_video = ['mp4','webm','ogv','ogg','mov','mkv','avi'];
|
||||
$allowed_media = media_allowed_upload_extensions();
|
||||
|
||||
for ($i = 0; $i < $source_count; $i++) {
|
||||
$type = ($source_types[$i] ?? 'local') === 'remote' ? 'remote' : 'local';
|
||||
@@ -99,7 +99,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if ($type === 'remote') {
|
||||
$url = normalize_media_url($source_urls[$i] ?? '');
|
||||
if ($url === '') {
|
||||
if (trim($source_urls[$i] ?? '') !== '') $error = 'External video URLs must start with http:// or https://.';
|
||||
if (trim($source_urls[$i] ?? '') !== '') $error = 'External media URLs must start with http:// or https://.';
|
||||
continue;
|
||||
}
|
||||
$metadata = $source_metadata[$url] ?? [];
|
||||
@@ -119,15 +119,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (empty($tmp) || !is_uploaded_file($tmp)) continue;
|
||||
$orig_name = $source_files['name'][$i] ?? '';
|
||||
$ext = strtolower(pathinfo($orig_name, PATHINFO_EXTENSION));
|
||||
if (!in_array($ext, $allowed_video, true)) continue;
|
||||
if (!in_array($ext, $allowed_media, true)) {
|
||||
$error = 'Uploaded media files must be one of: ' . media_upload_format_summary() . '.';
|
||||
break;
|
||||
}
|
||||
|
||||
$fname = $slug . '_' . ($i+1) . '_' . time() . '.' . $ext;
|
||||
if (move_uploaded_file($tmp, $videos_dir . $fname)) {
|
||||
$moved_files[] = $videos_dir . $fname;
|
||||
$target = $videos_dir . $fname;
|
||||
$moved_files[] = $target;
|
||||
$db->prepare("
|
||||
INSERT INTO video_sources (video_id, label, source_type, file_path, source_url, mime_type, quality, sort_order)
|
||||
VALUES (?,?,?,?,?,?,?,?)
|
||||
")->execute([$video_id, $label, 'local', 'videos/' . $fname, '', mime_from_ext($fname), $quality, $sort]);
|
||||
")->execute([$video_id, $label, 'local', 'videos/' . $fname, '', media_mime_from_local_file($target, $fname), $quality, $sort]);
|
||||
$inserted_sources++;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +158,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
}
|
||||
}
|
||||
|
||||
render_head('Add Video — Admin', '
|
||||
render_head('Add Media — Admin', '
|
||||
.form-grid { display:grid; grid-template-columns:1fr; gap:1.2rem; }
|
||||
@media(min-width:700px) { .form-grid { grid-template-columns:1fr 1fr; } }
|
||||
.form-grid .span2 { grid-column:1/-1; }
|
||||
@@ -206,7 +210,7 @@ render_head('Add Video — Admin', '
|
||||
<div class="topbar-brand">
|
||||
<div>
|
||||
<div class="brand-name">Ty Clifford</div>
|
||||
<div class="brand-sub">admin / add video</div>
|
||||
<div class="brand-sub">admin / add media</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="topbar-social">
|
||||
@@ -234,7 +238,7 @@ render_head('Add Video — Admin', '
|
||||
</a>
|
||||
<a href="add.php" class="active">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||
Add Video
|
||||
Add Media
|
||||
</a>
|
||||
<a href="youtube_import.php">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22.54 6.42a2.78 2.78 0 00-1.95-2C18.88 4 12 4 12 4s-6.88 0-8.59.46a2.78 2.78 0 00-1.95 2A29 29 0 001 12a29 29 0 00.46 5.58 2.78 2.78 0 001.95 2C5.12 20 12 20 12 20s6.88 0 8.59-.46a2.78 2.78 0 001.95-2A29 29 0 0023 12a29 29 0 00-.46-5.58z"/><polygon points="10,15 15,12 10,9"/></svg>
|
||||
@@ -251,7 +255,7 @@ render_head('Add Video — Admin', '
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.25rem;flex-wrap:wrap;gap:.75rem;">
|
||||
<div>
|
||||
<p class="eyebrow eyebrow-purple" style="margin-bottom:.3rem">New Entry</p>
|
||||
<h1 style="font-size:1.05rem;font-weight:700;color:var(--text);">Add Video</h1>
|
||||
<h1 style="font-size:1.05rem;font-weight:700;color:var(--text);">Add Media</h1>
|
||||
</div>
|
||||
<a href="index.php" class="btn btn-secondary btn-sm">← Back</a>
|
||||
</div>
|
||||
@@ -260,7 +264,7 @@ render_head('Add Video — Admin', '
|
||||
|
||||
<!-- ── Video details ── -->
|
||||
<div class="card" style="margin-bottom:1rem;">
|
||||
<p class="section-heading">Video Details</p>
|
||||
<p class="section-heading">Media Details</p>
|
||||
<div class="form-grid">
|
||||
<div class="form-group span2">
|
||||
<label class="form-label" for="title">Title</label>
|
||||
@@ -290,9 +294,9 @@ render_head('Add Video — Admin', '
|
||||
accept="image/jpeg,image/png,image/webp,image/gif" style="padding:.45rem .6rem;">
|
||||
<label style="display:flex;align-items:center;gap:.55rem;margin-top:.55rem;cursor:pointer;">
|
||||
<input type="checkbox" name="auto_thumbnail" value="1" <?= isset($_POST['auto_thumbnail']) || $_SERVER['REQUEST_METHOD'] !== 'POST' ? 'checked' : '' ?>>
|
||||
<span style="font-size:.78rem;color:var(--text-2);">Auto-grab thumbnail from source if no image is uploaded</span>
|
||||
<span style="font-size:.78rem;color:var(--text-2);">Auto-grab thumbnail or waveform from source if no image is uploaded</span>
|
||||
</label>
|
||||
<span class="hint">JPG, PNG, WebP or GIF. Auto-grab supports YouTube, Vimeo, Dailymotion and other oEmbed providers; local uploads use ffmpeg when available.</span>
|
||||
<span class="hint">JPG, PNG, WebP or GIF. Auto-grab supports providers, local video first frames, and local audio waveforms when ffmpeg is available.</span>
|
||||
</div>
|
||||
<div class="form-group" style="justify-content:flex-end;padding-bottom:.2rem;">
|
||||
<label style="display:flex;align-items:center;gap:.6rem;cursor:pointer;">
|
||||
@@ -304,12 +308,12 @@ render_head('Add Video — Admin', '
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Video sources ── -->
|
||||
<!-- ── Media sources ── -->
|
||||
<div class="card">
|
||||
<p class="section-heading">Video Sources</p>
|
||||
<p class="section-heading">Media Sources</p>
|
||||
<p class="hint" style="margin-bottom:1rem;">
|
||||
Upload a video file, link a direct media file, or paste a provider page URL such as YouTube or Vimeo. The player will use a provider embed when the URL supports it.
|
||||
Uploaded files: <strong>MP4, WebM, OGV, MOV, MKV, AVI</strong>. Remote URLs must use <strong>http://</strong> or <strong>https://</strong>.
|
||||
Upload a video or audio file, link a direct media file, or paste a provider page URL such as YouTube or Vimeo. The player will use a provider embed when the URL supports it.
|
||||
Uploaded files: <strong><?= h(media_upload_format_summary()) ?></strong>. Remote URLs must use <strong>http://</strong> or <strong>https://</strong>.
|
||||
</p>
|
||||
|
||||
<div class="sources-section" id="sources-container">
|
||||
@@ -323,9 +327,9 @@ render_head('Add Video — Admin', '
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group source-location-panel source-location-local">
|
||||
<label class="form-label">Video File</label>
|
||||
<label class="form-label">Media File</label>
|
||||
<input class="form-input" type="file" name="source_file[]"
|
||||
accept="video/mp4,video/webm,video/ogg,.mp4,.webm,.ogv,.mov,.mkv,.avi"
|
||||
accept="<?= h(media_upload_accept_attribute()) ?>"
|
||||
style="padding:.45rem .6rem;">
|
||||
</div>
|
||||
<div class="form-group source-location-panel source-location-remote" hidden>
|
||||
@@ -344,6 +348,10 @@ render_head('Add Video — Admin', '
|
||||
<option value="480p">480p</option>
|
||||
<option value="360p">360p</option>
|
||||
<option value="4K">4K</option>
|
||||
<option value="Audio">Audio</option>
|
||||
<option value="320kbps">320kbps</option>
|
||||
<option value="256kbps">256kbps</option>
|
||||
<option value="128kbps">128kbps</option>
|
||||
<option value="">—</option>
|
||||
</select>
|
||||
</div>
|
||||
@@ -367,7 +375,7 @@ render_head('Add Video — Admin', '
|
||||
<div style="display:flex;gap:.75rem;margin-top:1rem;flex-wrap:wrap;">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><polyline points="17,21 17,13 7,13 7,21"/><polyline points="7,3 7,8 15,8"/></svg>
|
||||
Save Video
|
||||
Save Media
|
||||
</button>
|
||||
<a href="index.php" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user