diff --git a/app/Jobs/TutorialVideoJob.php b/app/Jobs/TutorialVideoJob.php index e6107a15..3203ae17 100644 --- a/app/Jobs/TutorialVideoJob.php +++ b/app/Jobs/TutorialVideoJob.php @@ -241,16 +241,7 @@ public function handle( // === Step 5: 최종 합성 (80%) === $tutorial->updateProgress(TutorialVideo::STATUS_ASSEMBLING, 70, '영상 합성 중...'); - // ASS 자막 생성 (인트로/아웃트로 나레이션은 자막에서 제외) - $subtitleScenes = array_map(function ($scene) { - $sn = (int) ($scene['scene_number'] ?? 0); - if ($sn <= 1 || $sn === 999) { - $scene['narration'] = ''; - } - return $scene; - }, $scenes); - $subtitlePath = "{$workDir}/subtitle.ass"; - $videoAssembly->generateAssSubtitle($subtitleScenes, $subtitlePath, $narrationDurations, 'landscape'); + // 자막 비활성화: 슬라이드 하단 캡션바에 나레이션이 이미 표시되므로 ASS 자막 불필요 // 최종 MP4 합성 $finalOutputPath = "{$workDir}/final_tutorial.mp4"; @@ -259,7 +250,7 @@ public function handle( $durations, $narrationPath, $bgmResult, - $subtitlePath, + null, $finalOutputPath ); diff --git a/app/Services/Video/TutorialAssemblyService.php b/app/Services/Video/TutorialAssemblyService.php index 1446433a..6ced1dc2 100644 --- a/app/Services/Video/TutorialAssemblyService.php +++ b/app/Services/Video/TutorialAssemblyService.php @@ -29,7 +29,7 @@ public function assembleFromImages( array $durations, ?string $narrationPath, ?string $bgmPath, - string $subtitlePath, + ?string $subtitlePath, string $outputPath ): ?string { if (empty($slidePaths)) { diff --git a/app/Services/Video/VideoAssemblyService.php b/app/Services/Video/VideoAssemblyService.php index 3530854d..244e7c34 100644 --- a/app/Services/Video/VideoAssemblyService.php +++ b/app/Services/Video/VideoAssemblyService.php @@ -395,7 +395,7 @@ public function assemble( string $videoPath, ?string $narrationPath, ?string $bgmPath, - string $subtitlePath, + ?string $subtitlePath, string $outputPath ): ?string { $dir = dirname($outputPath); @@ -436,9 +436,6 @@ public function assemble( $filterComplex = null; } - // 자막 비디오 필터 (ass 필터: ASS 스타일(Alignment 등) 완전 보존) - $vf = sprintf("ass=%s", escapeshellarg($subtitlePath)); - // FFmpeg 명령 조립 $cmd = 'ffmpeg -y ' . implode(' ', $inputs); @@ -447,7 +444,12 @@ public function assemble( } $cmd .= ' ' . implode(' ', $mapParts); - $cmd .= ' -vf ' . escapeshellarg($vf); + + // 자막 비디오 필터 (슬라이드 캡션바에 텍스트 포함 시 생략 가능) + if ($subtitlePath && file_exists($subtitlePath)) { + $vf = sprintf("ass=%s", escapeshellarg($subtitlePath)); + $cmd .= ' -vf ' . escapeshellarg($vf); + } $cmd .= ' -c:v libx264 -preset fast -crf 23 -r 30'; $cmd .= ' -c:a aac -b:a 192k'; $cmd .= ' -shortest';