feat: [video] 좌표 검증 및 영상 메타데이터를 analysis_data에 저장
- 각 step별 검증 결과 저장 (accurate/corrected + 원본 좌표) - 스크린 단위 검증 통계 저장 (정확/보정 수, 검증 시각) - 영상 완료 시 _output 메타데이터 저장 (경로, GCS, 비용, 슬라이드수, 총 재생시간)
This commit is contained in:
@@ -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: 완료', [
|
||||
|
||||
Reference in New Issue
Block a user