feat: [video] 좌표 검증 및 영상 메타데이터를 analysis_data에 저장

- 각 step별 검증 결과 저장 (accurate/corrected + 원본 좌표)
- 스크린 단위 검증 통계 저장 (정확/보정 수, 검증 시각)
- 영상 완료 시 _output 메타데이터 저장 (경로, GCS, 비용, 슬라이드수, 총 재생시간)
This commit is contained in:
김보곤
2026-02-21 16:37:08 +09:00
parent cf6525c8f3
commit 7991f3e6d4
2 changed files with 54 additions and 3 deletions

View File

@@ -46,6 +46,7 @@ public function handle(
if (! $tutorial) {
Log::error('TutorialVideoJob: 레코드를 찾을 수 없음', ['id' => $this->tutorialVideoId]);
return;
}
@@ -67,6 +68,7 @@ public function handle(
if (empty($screenshots)) {
$tutorial->markFailed('업로드된 스크린샷이 없습니다');
return;
}
@@ -74,6 +76,7 @@ public function handle(
if (empty($analysisData)) {
$tutorial->markFailed('스크린샷 분석에 실패했습니다');
return;
}
@@ -126,6 +129,7 @@ public function handle(
if (! $imagePath || ! file_exists($imagePath)) {
Log::warning("TutorialVideoJob: 스크린샷 없음 - index {$i}");
continue;
}
@@ -176,6 +180,7 @@ public function handle(
if (count($slidePaths) <= 2) { // 인트로+아웃트로만 있으면 실패
$tutorial->markFailed('슬라이드 생성에 실패했습니다');
return;
}
@@ -257,6 +262,7 @@ public function handle(
if (! $result || ! file_exists($finalOutputPath)) {
$tutorial->markFailed('영상 합성에 실패했습니다');
return;
}
@@ -267,13 +273,26 @@ public function handle(
$gcsPath = null;
if ($gcs->isAvailable()) {
$objectName = "tutorials/{$tutorial->tenant_id}/{$tutorial->id}/tutorial_" . date('Ymd_His') . '.mp4';
$objectName = "tutorials/{$tutorial->tenant_id}/{$tutorial->id}/tutorial_".date('Ymd_His').'.mp4';
$gcsPath = $gcs->upload($finalOutputPath, $objectName);
}
$tutorial->updateProgress(TutorialVideo::STATUS_ASSEMBLING, 95, '업로드 완료');
// === Step 7: 완료 (100%) ===
// analysis_data에 영상 저장 경로 메타데이터 추가
$analysisWithMeta = $tutorial->analysis_data ?? $analysisData;
if (is_array($analysisWithMeta)) {
$analysisWithMeta['_output'] = [
'completed_at' => now()->toIso8601String(),
'output_path' => $finalOutputPath,
'gcs_path' => $gcsPath,
'cost_usd' => round($totalCost, 4),
'total_slides' => count($slidePaths),
'total_duration' => $totalDuration,
];
}
$tutorial->update([
'status' => TutorialVideo::STATUS_COMPLETED,
'progress' => 100,
@@ -281,6 +300,7 @@ public function handle(
'output_path' => $finalOutputPath,
'gcs_path' => $gcsPath,
'cost_usd' => $totalCost,
'analysis_data' => $analysisWithMeta,
]);
Log::info('TutorialVideoJob: 완료', [