Fix match-video playback: HEVC → H.264 transcode + correct HLS URL
- CompressVideoJob: rewrite to exec ffmpeg directly. php-ffmpeg's X264 format class validates the codec name and only accepts libx264, so every job dispatched with h264_nvenc had been throwing within ~1s and leaving the source untouched. The job now honours the GPU encoder settings, and always replaces the source when the codec is HEVC/H.265 so downloads and the MP4 fallback stay playable. - VideoController + video-player component: point HLS URLs at playlist.m3u8 (the actual master file GenerateHlsJob writes) instead of the non-existent master.m3u8, which was 404-ing and forcing the player back to the raw MP4. - VideoController@store: on the NAS-success branch, flip status to 'ready' and populate duration/is_shorts before dispatching GenerateHlsJob, so the job no longer silently no-ops. - Upload chooser: render as a bottom sheet on mobile, and forward the picked type to /videos/create?type= so the create page pre-selects it. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
e0aa6e4817
commit
76f5ef0c84
5 files changed
+170
-68
No files matched your search
@@ -711,6 +711,55 @@
|
||||
}
|
||||
.utc-card:hover .utc-card-arr { opacity: 1; transform: translateX(0); }
|
||||
|
||||
/* ── Mobile: render the chooser as a bottom sheet ───────────── */
|
||||
@media (max-width: 768px) {
|
||||
.utc-overlay {
|
||||
align-items: flex-end; justify-content: stretch;
|
||||
padding: 0; background: rgba(0,0,0,.55);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
.utc-box {
|
||||
max-width: none; width: 100%;
|
||||
border-radius: 20px 20px 0 0;
|
||||
border-left: none; border-right: none; border-bottom: none;
|
||||
padding: 10px 18px calc(22px + env(safe-area-inset-bottom));
|
||||
transform: translateY(100%); transition: transform .28s cubic-bezier(.22,1,.36,1);
|
||||
box-shadow: 0 -12px 40px rgba(0,0,0,.6);
|
||||
max-height: 88vh; overflow-y: auto;
|
||||
}
|
||||
.utc-overlay.show .utc-box { transform: translateY(0); }
|
||||
|
||||
/* Grabber handle at the top */
|
||||
.utc-box::before {
|
||||
content: ''; display: block; width: 40px; height: 4px;
|
||||
background: #333; border-radius: 2px; margin: 4px auto 14px;
|
||||
}
|
||||
|
||||
.utc-close { top: 12px; right: 12px; }
|
||||
.utc-head { margin-bottom: 16px; }
|
||||
.utc-head-icon { width: 44px; height: 44px; font-size: 20px; margin-bottom: 10px; }
|
||||
.utc-title { font-size: 17px; }
|
||||
.utc-sub { font-size: 12px; }
|
||||
|
||||
/* Row of compact tiles instead of full stacked cards */
|
||||
.utc-grid { grid-template-columns: repeat(3, 1fr); gap: 10px; }
|
||||
.utc-card {
|
||||
padding: 16px 8px 14px; border-radius: 14px; border-width: 1px;
|
||||
}
|
||||
.utc-card-ico {
|
||||
width: 44px; height: 44px; margin-bottom: 8px;
|
||||
font-size: 20px; border-radius: 12px;
|
||||
}
|
||||
.utc-card-title { font-size: 13px; }
|
||||
.utc-card-desc { display: none; }
|
||||
.utc-card-arr { display: none; }
|
||||
.utc-card:active {
|
||||
transform: scale(.96);
|
||||
background: color-mix(in srgb, var(--accent) 10%, #111);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
}
|
||||
|
||||
/* ════════════════════════════════════════════════════════════════
|
||||
Unified control system — one consistent look for every field,
|
||||
dropdown and picker in the upload modal. Scoped to #uploadModal
|
||||
@@ -829,19 +878,28 @@ const _UTC_META = {
|
||||
};
|
||||
|
||||
function openUploadChooser() {
|
||||
// Mobile keeps the existing full-page create flow (with its own type picker)
|
||||
if (window.innerWidth < 992) {
|
||||
window.location.href = '{{ route("videos.create") }}';
|
||||
return;
|
||||
}
|
||||
// Chooser is shown on every viewport — on mobile chooseUploadType() routes
|
||||
// straight to the standalone create page with the picked ?type= preserved.
|
||||
document.getElementById('upload-type-chooser').classList.add('show');
|
||||
}
|
||||
|
||||
// Called from the desktop chooser cards on mobile — carries the picked type
|
||||
// through to the standalone create page via ?type=.
|
||||
function chooseUploadTypeMobile(type) {
|
||||
const t = ['generic', 'music', 'match'].includes(type) ? type : 'generic';
|
||||
window.location.href = '{{ route("videos.create") }}?type=' + encodeURIComponent(t);
|
||||
}
|
||||
|
||||
function closeUploadChooser() {
|
||||
document.getElementById('upload-type-chooser').classList.remove('show');
|
||||
}
|
||||
|
||||
function chooseUploadType(type) {
|
||||
// Mobile has no modal — route straight to the create page with the type preserved.
|
||||
if (window.innerWidth < 992) {
|
||||
chooseUploadTypeMobile(type);
|
||||
return;
|
||||
}
|
||||
const meta = _UTC_META[type] || _UTC_META.generic;
|
||||
closeUploadChooser();
|
||||
openUploadModal();
|
||||
|
||||
Reference in new issue
Block a user