Audio songs: one-folder storage, version-aware download/share, GPU-checked renders
Storage structure
- All audio tracks (primary + per-language) now live in one folder per song with
unique lowercase names ({slug}-{lang}-{id}); no more tracks/ subfolder.
- Generated renders (download video + HLS) moved into the song's local-only cache/
subfolder, separated from source files (never synced to NAS, safe to wipe).
- tracks:reorganize artisan command (dry-run default) consolidates legacy files,
updates DB paths, and deletes orphans + empty folders.
- CLAUDE.md documents the canonical layout as a global rule (identical local + NAS).
Version-aware download & share
- Download MP3/Video and Share now act on the version being played; ?track={id}
is carried through share links and auto-selects audio + title + flag + about +
OG/meta on open.
GPU + visualizer
- Setting::gpuUsable() runs a cached health probe (nvidia-smi + nvenc smoke test,
256x144) before sending any encode to the GPU; falls back to CPU otherwise.
- Visualizer "Download Video" bakes in equal-width, cover-coloured, translucent
frequency bars; loop-filter rebuild makes generation ~25x faster.
Image cropper
- result-callback mode + per-song cover-slide cropper in upload/edit (modal + mobile).
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
66fd78c10f
commit
a4384113c2
24 files changed
+1738
-258
No files matched your search
@@ -51,7 +51,9 @@ class CompressVideoJob implements ShouldQueue
|
||||
]);
|
||||
$ffmpegVideo = $ffmpeg->open($originalPath);
|
||||
|
||||
$gpuEnabled = Setting::gpuEnabled();
|
||||
// Verify the GPU is actually reachable and able to encode before sending
|
||||
// the file to it; otherwise fall back to CPU so the job never hangs.
|
||||
$gpuEnabled = Setting::gpuUsable();
|
||||
$encoder = Setting::gpuEncoder();
|
||||
$preset = Setting::gpuPreset();
|
||||
$device = Setting::gpuDevice();
|
||||
|
||||
@@ -52,7 +52,12 @@ class GenerateHlsJob implements ShouldQueue
|
||||
}
|
||||
}
|
||||
|
||||
$hlsDir = 'public/hls/' . $video->id;
|
||||
// HLS rendition lives in the song's own cache/ subfolder (regenerable, local-only —
|
||||
// never pushed to NAS). Fall back to the shared public/hls only for legacy rows
|
||||
// whose path is not in the users/ layout.
|
||||
$hlsDir = str_starts_with((string) $video->path, 'users/')
|
||||
? dirname($video->path) . '/cache/hls'
|
||||
: 'public/hls/' . $video->id;
|
||||
$hlsPath = storage_path('app/' . $hlsDir);
|
||||
|
||||
if (is_dir($hlsPath)) {
|
||||
@@ -72,7 +77,9 @@ class GenerateHlsJob implements ShouldQueue
|
||||
|
||||
try {
|
||||
$ffmpegBin = \App\Models\Setting::ffmpegBinary();
|
||||
$gpuEnabled = Setting::gpuEnabled();
|
||||
// Verify the GPU is actually reachable and able to encode before sending
|
||||
// the file to it; otherwise fall back to CPU so the job never hangs.
|
||||
$gpuEnabled = Setting::gpuUsable();
|
||||
$encoder = Setting::gpuEncoder(); // h264_nvenc / hevc_nvenc / libx264
|
||||
$preset = Setting::gpuPreset(); // p1–p7 for NVENC, fast/medium/slow for x264
|
||||
$device = Setting::gpuDevice(); // GPU index (0, 1, …)
|
||||
|
||||
Reference in new issue
Block a user