|
7 | 7 | use App\Models\Metadata; |
8 | 8 | use App\Models\Record; |
9 | 9 | use App\Models\SubTask; |
| 10 | +use App\Models\Subtitle; |
10 | 11 | use App\Services\TaskService; |
11 | 12 | use Illuminate\Support\Facades\Bus; |
12 | 13 | use Illuminate\Support\Facades\Log; |
@@ -74,6 +75,7 @@ public function handle(TaskService $taskService): void { |
74 | 75 |
|
75 | 76 | private function verifyFiles(TaskService $taskService) { |
76 | 77 | $transactions = []; |
| 78 | + $subtitleSets = []; |
77 | 79 | $error = false; |
78 | 80 | $index = 0; |
79 | 81 |
|
@@ -176,6 +178,19 @@ private function verifyFiles(TaskService $taskService) { |
176 | 178 | $changes['duration'] = is_numeric($duration) ? floor($duration) : null; |
177 | 179 | } |
178 | 180 |
|
| 181 | + if (is_null($metadata->subtitles_scanned_at) || $fileUpdated) { |
| 182 | + $this->confirmMetadata($filePath); |
| 183 | + $subtitleStreams = array_filter( |
| 184 | + $this->fileMetaData['streams'], |
| 185 | + fn($stream) => ($stream['codec_type'] ?? null) === 'subtitle' |
| 186 | + ); |
| 187 | + |
| 188 | + if (count($subtitleStreams)) { |
| 189 | + $subtitleSets = [...$subtitleSets, $uuid => $subtitleStreams]; |
| 190 | + } |
| 191 | + $changes['subtitles_scanned_at'] = now(); |
| 192 | + } |
| 193 | + |
179 | 194 | if (! $is_audio && (is_null($metadata->resolution_height) || is_null($metadata->codec) || $fileUpdated)) { |
180 | 195 | $this->confirmMetadata($filePath); |
181 | 196 | foreach ($this->fileMetaData['streams'] as $stream) { |
@@ -314,12 +329,17 @@ private function verifyFiles(TaskService $taskService) { |
314 | 329 | 'date_scanned', |
315 | 330 | 'date_uploaded', |
316 | 331 | 'media_type', |
| 332 | + 'subtitles_scanned_at', |
317 | 333 | ] |
318 | 334 | ); |
319 | 335 |
|
320 | 336 | $summary = 'Updated ' . count($transactions) . ' videos from id ' . ($transactions[0]['video_id']) . ' to ' . ($transactions[count($transactions) - 1]['video_id']); |
321 | 337 | dump($summary); |
322 | 338 |
|
| 339 | + if (count($subtitleSets)) { |
| 340 | + $summary .= $this->upsertSubtitles($subtitleSets); |
| 341 | + } |
| 342 | + |
323 | 343 | return $summary; |
324 | 344 | } catch (\Throwable $th) { |
325 | 345 | $ids = array_column($transactions, 'id'); |
@@ -516,4 +536,44 @@ protected function extractMimeType($filePath) { |
516 | 536 |
|
517 | 537 | return $mimeType; |
518 | 538 | } |
| 539 | + |
| 540 | + private function upsertSubtitles(array $streamSets): string { |
| 541 | + try { |
| 542 | + $totalTransactions = 0; |
| 543 | + foreach ($streamSets as $uuid => $set) { |
| 544 | + $transactions = $this->generateSubtitleTransactions($uuid, $set); |
| 545 | + $totalTransactions += count($transactions); |
| 546 | + Subtitle::upsert($transactions, ['metadata_uuid', 'track_id'], ['language', 'codec']); |
| 547 | + } |
| 548 | + |
| 549 | + return $totalTransactions ? " and found $totalTransactions subtitle track(s)." : ''; |
| 550 | + } catch (\Throwable $th) { |
| 551 | + Log::error('Failed upserting subtitle tracks', [ |
| 552 | + 'error' => $th->getMessage(), |
| 553 | + ]); |
| 554 | + |
| 555 | + return ''; |
| 556 | + } |
| 557 | + } |
| 558 | + |
| 559 | + private function generateSubtitleTransactions(string $uuid, array $streams): array { |
| 560 | + $transactions = []; |
| 561 | + foreach ($streams as $stream) { |
| 562 | + try { |
| 563 | + $subtitle = ['metadata_uuid' => $uuid]; |
| 564 | + $subtitle['track_id'] = $stream['index']; |
| 565 | + $subtitle['language'] = $stream['tags']['language'] ?? null; |
| 566 | + $subtitle['codec'] = $stream['codec_name'] ?? null; |
| 567 | + |
| 568 | + array_push($transactions, $subtitle); |
| 569 | + } catch (\Throwable $th) { |
| 570 | + Log::error('Failed generating subtitle track', [ |
| 571 | + 'uuid' => $uuid, |
| 572 | + 'error' => $th->getMessage(), |
| 573 | + ]); |
| 574 | + } |
| 575 | + } |
| 576 | + |
| 577 | + return $transactions; |
| 578 | + } |
519 | 579 | } |
0 commit comments