feat:영상 파일 GCS 저장 및 삭제 연동

- VideoGenerationJob: 최종 합성 후 GCS 업로드, gcs_path 저장
- Veo3Controller: download/preview GCS 서명URL 사용, destroy GCS 파일 삭제
- VideoGeneration 모델: gcs_path fillable 추가
- GCS 불가 시 로컬 파일로 폴백

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-15 11:11:18 +09:00
parent 5e4a9c9291
commit 3f4cd88c20
3 changed files with 57 additions and 4 deletions

View File

@@ -8,6 +8,7 @@
use App\Services\Video\TtsService;
use App\Services\Video\VeoVideoService;
use App\Services\Video\VideoAssemblyService;
use App\Services\GoogleCloudStorageService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -41,7 +42,8 @@ public function handle(
VeoVideoService $veo,
TtsService $tts,
BgmService $bgm,
VideoAssemblyService $assembly
VideoAssemblyService $assembly,
GoogleCloudStorageService $gcs
): void {
$video = VideoGeneration::withoutGlobalScopes()->find($this->videoGenerationId);
@@ -264,6 +266,28 @@ public function handle(
return;
}
// === GCS 업로드 ===
$gcsPath = null;
if ($gcs->isAvailable()) {
$video->updateProgress(VideoGeneration::STATUS_ASSEMBLING, 95, 'GCS 업로드 중...');
$objectName = "video_gen/{$video->id}/final_{$video->id}.mp4";
$gcsUri = $gcs->upload($finalPath, $objectName);
if ($gcsUri) {
$gcsPath = $objectName;
Log::info('VideoGenerationJob: GCS 업로드 성공', [
'id' => $video->id,
'gcs_path' => $objectName,
]);
} else {
Log::warning('VideoGenerationJob: GCS 업로드 실패, 로컬 파일로 계속', [
'id' => $video->id,
]);
}
}
// === 완료 ===
$stepMsg = empty($skippedScenes)
? '완료'
@@ -274,6 +298,7 @@ public function handle(
'progress' => 100,
'current_step' => $stepMsg,
'output_path' => $finalPath,
'gcs_path' => $gcsPath,
'cost_usd' => $totalCost,
]);
@@ -283,6 +308,7 @@ public function handle(
Log::info('VideoGenerationJob: 영상 생성 완료', [
'id' => $video->id,
'output' => $finalPath,
'gcs_path' => $gcsPath,
'cost' => $totalCost,
]);
} catch (\Exception $e) {