Chunked video upload, persistent track order, per-track playlist entries
Chunked uploads: bypass Cloudflare's 100 MB request cap by slicing the video/audio into 8 MB chunks and reassembling server-side before the normal store flow runs. Track reorder: audio tracks gain a `position` column so a user's edit- modal ordering survives reload. `Video::audioTracks()` now orders by position, `promote_track_id` remembers the swapped row, and freshly uploaded tracks append to the end. Playlist per-track pinning: `playlist_videos.audio_track_id` remembers which language the user pinned when adding a song. Same song with a different track becomes a separate row (Spotify-style duplicates). Player-data exposes `active_stream_url` + `active_track_id`, sidebar cards render `?track=` from the pivot, and both `plTransitionTo` and initial-load code activate the corresponding language option. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
af276f2cd1
commit
ba8ab11ce4
12 files changed
+547
-49
No files matched your search
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('video_audio_tracks', function (Blueprint $table) {
|
||||
$table->unsignedInteger('position')->default(0)->after('label');
|
||||
$table->index(['video_id', 'position']);
|
||||
});
|
||||
|
||||
// Backfill existing rows so their current id-order becomes the
|
||||
// canonical position. New rows start at 0 and get placed at the
|
||||
// end by the update handler.
|
||||
DB::statement('UPDATE video_audio_tracks SET position = id');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('video_audio_tracks', function (Blueprint $table) {
|
||||
$table->dropIndex(['video_id', 'position']);
|
||||
$table->dropColumn('position');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('playlist_videos', function (Blueprint $table) {
|
||||
// Nullable — null means "play the primary track".
|
||||
$table->unsignedBigInteger('audio_track_id')
|
||||
->nullable()
|
||||
->after('video_id');
|
||||
|
||||
// Drop the old (playlist_id, video_id) uniqueness so the same
|
||||
// video can appear multiple times with different tracks.
|
||||
$table->dropUnique(['playlist_id', 'video_id']);
|
||||
|
||||
$table->index(['playlist_id', 'video_id', 'audio_track_id'], 'playlist_video_track_idx');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('playlist_videos', function (Blueprint $table) {
|
||||
$table->dropIndex('playlist_video_track_idx');
|
||||
$table->unique(['playlist_id', 'video_id']);
|
||||
$table->dropColumn('audio_track_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user