- 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:
@@ -33,6 +33,13 @@ $native_player_sources = [];
|
||||
foreach ($player_sources as $player_source) {
|
||||
if (($player_source['kind'] ?? '') !== 'iframe') $native_player_sources[] = $player_source;
|
||||
}
|
||||
$native_player_mode = (($primary_player_source['kind'] ?? '') === 'audio') ? 'audio' : 'video';
|
||||
$active_native_sources = [];
|
||||
foreach ($native_player_sources as $player_source) {
|
||||
$kind = $player_source['kind'] ?? '';
|
||||
if ($native_player_mode === 'audio' && $kind === 'audio') $active_native_sources[] = $player_source;
|
||||
if ($native_player_mode === 'video' && $kind !== 'audio') $active_native_sources[] = $player_source;
|
||||
}
|
||||
|
||||
$meta_title = $video ? $video['title'] . ' — TyClifford.com' : 'Video Player';
|
||||
$meta_description = $video && trim($video['description'] ?? '') !== '' ? trim($video['description']) : 'TyClifford.com media player';
|
||||
@@ -153,6 +160,57 @@ header('Content-Security-Policy: frame-ancestors *');
|
||||
.video-js .vjs-current-time,
|
||||
.video-js .vjs-duration,
|
||||
.video-js .vjs-time-divider { color: rgba(255,255,255,.8) !important; font-size: .7em !important; }
|
||||
.audio-player-frame {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
background: radial-gradient(circle at 50% 35%, rgba(176,96,255,.12), transparent 55%), #09090f;
|
||||
}
|
||||
.audio-waveform-art {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(180deg, rgba(9,9,15,.2), rgba(9,9,15,.82));
|
||||
overflow: hidden;
|
||||
}
|
||||
.audio-waveform-art img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
opacity: .92;
|
||||
filter: saturate(1.15) contrast(1.05);
|
||||
}
|
||||
.audio-waveform-fallback {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background:
|
||||
linear-gradient(90deg, transparent 0 4%, rgba(0,232,122,.34) 4% 5%, transparent 5% 9%),
|
||||
radial-gradient(circle at 50% 35%, rgba(0,232,122,.12), transparent 55%),
|
||||
#09090f;
|
||||
background-size: 90px 100%, 100% 100%, 100% 100%;
|
||||
opacity: .9;
|
||||
}
|
||||
.audio-player-frame .video-js {
|
||||
position: relative !important;
|
||||
inset: auto !important;
|
||||
width: 100% !important;
|
||||
max-width: calc(100% - 1rem) !important;
|
||||
height: 4.2rem !important;
|
||||
background: rgba(9,9,15,.86) !important;
|
||||
border: 1px solid rgba(255,255,255,.08);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,.35);
|
||||
}
|
||||
.audio-player-frame .video-js .vjs-control-bar {
|
||||
background: rgba(9,9,15,.92) !important;
|
||||
height: 4.2rem !important;
|
||||
}
|
||||
.provider-embed-frame {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -240,20 +298,42 @@ header('Content-Security-Policy: frame-ancestors *');
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture; web-share"
|
||||
allowfullscreen
|
||||
referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
<?php elseif (!empty($native_player_sources)): ?>
|
||||
<video id="embed-player"
|
||||
class="video-js vjs-default-skin vjs-big-play-centered"
|
||||
controls preload="metadata"
|
||||
<?php if ($video['thumbnail']): ?>
|
||||
poster="<?= htmlspecialchars(public_absolute_url(public_media_url($video['thumbnail'])), ENT_QUOTES) ?>"
|
||||
<?php endif; ?>>
|
||||
<?php foreach ($native_player_sources as $src): ?>
|
||||
<source
|
||||
src="<?= htmlspecialchars($src['url'], ENT_QUOTES) ?>"
|
||||
type="<?= htmlspecialchars($src['mime'], ENT_QUOTES) ?>">
|
||||
<?php endforeach; ?>
|
||||
<p class="vjs-no-js">Your browser does not support HTML5 video.</p>
|
||||
</video>
|
||||
<?php elseif (!empty($active_native_sources)): ?>
|
||||
<?php if ($native_player_mode === 'audio'): ?>
|
||||
<div class="audio-player-frame">
|
||||
<div class="audio-waveform-art" aria-hidden="true">
|
||||
<?php if ($video['thumbnail']): ?>
|
||||
<img src="<?= h(public_absolute_url(public_media_url($video['thumbnail']))) ?>" alt="">
|
||||
<?php else: ?>
|
||||
<div class="audio-waveform-fallback"></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<audio id="embed-player"
|
||||
class="video-js vjs-default-skin"
|
||||
controls preload="metadata">
|
||||
<?php foreach ($active_native_sources as $src): ?>
|
||||
<source
|
||||
src="<?= htmlspecialchars($src['url'], ENT_QUOTES) ?>"
|
||||
type="<?= htmlspecialchars($src['mime'], ENT_QUOTES) ?>">
|
||||
<?php endforeach; ?>
|
||||
<p class="vjs-no-js">Your browser does not support HTML5 audio.</p>
|
||||
</audio>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<video id="embed-player"
|
||||
class="video-js vjs-default-skin vjs-big-play-centered"
|
||||
controls preload="metadata"
|
||||
<?php if ($video['thumbnail']): ?>
|
||||
poster="<?= htmlspecialchars(public_absolute_url(public_media_url($video['thumbnail'])), ENT_QUOTES) ?>"
|
||||
<?php endif; ?>>
|
||||
<?php foreach ($active_native_sources as $src): ?>
|
||||
<source
|
||||
src="<?= htmlspecialchars($src['url'], ENT_QUOTES) ?>"
|
||||
type="<?= htmlspecialchars($src['mime'], ENT_QUOTES) ?>">
|
||||
<?php endforeach; ?>
|
||||
<p class="vjs-no-js">Your browser does not support HTML5 video.</p>
|
||||
</video>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
@@ -265,13 +345,13 @@ header('Content-Security-Policy: frame-ancestors *');
|
||||
<line x1="8" y1="21" x2="16" y2="21"/>
|
||||
<line x1="12" y1="17" x2="12" y2="21"/>
|
||||
</svg>
|
||||
<p><?= $slug ? 'video not found' : 'no video specified' ?></p>
|
||||
<p><?= $slug ? 'media not found' : 'no media specified' ?></p>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($video && !empty($native_player_sources) && (!$primary_player_source || ($primary_player_source['kind'] ?? '') !== 'iframe')): ?>
|
||||
<?php if ($video && !empty($active_native_sources) && (!$primary_player_source || ($primary_player_source['kind'] ?? '') !== 'iframe')): ?>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var player = videojs('embed-player', {
|
||||
|
||||
Reference in New Issue
Block a user