Commit Graph

15 Commits

Author SHA1 Message Date
김보곤
9a7c548246 style: Pint 포맷팅 적용 2026-02-25 11:45:01 +09:00
김보곤
7991f3e6d4 feat: [video] 좌표 검증 및 영상 메타데이터를 analysis_data에 저장
- 각 step별 검증 결과 저장 (accurate/corrected + 원본 좌표)
- 스크린 단위 검증 통계 저장 (정확/보정 수, 검증 시각)
- 영상 완료 시 _output 메타데이터 저장 (경로, GCS, 비용, 슬라이드수, 총 재생시간)
2026-02-21 16:37:08 +09:00
김보곤
b0685a8886 fix: [video] MNG Job 큐 분리 (API 워커 충돌 방지)
- TutorialVideoJob, VideoGenerationJob에 onQueue('mng') 지정
- API 워커가 MNG Job을 가져가 __PHP_Incomplete_Class 에러 발생 방지
2026-02-21 15:42:53 +09:00
김보곤
cf7cf9fd7a fix:ASS 자막 비활성화 (슬라이드 캡션바와 중복 제거)
- TutorialVideoJob: 자막 생성 제거, subtitlePath에 null 전달
- TutorialAssemblyService: subtitlePath 파라미터 nullable 변경
- VideoAssemblyService: subtitlePath nullable + null일 때 ass 필터 생략

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:10:38 +09:00
김보곤
ff80d50c9b fix:자막 하단 정렬 + 인트로 자막 중복 제거
- FFmpeg subtitles 필터 → ass 필터 변경 (ASS 스타일 Alignment 완전 보존)
- 인트로/아웃트로 씬 자막 제거를 이중 보장:
  1. Job에서 자막용 scenes 복사본의 인트로/아웃트로 narration을 빈 문자열로 설정
  2. generateAssSubtitle에서 scene_number int 캐스팅 + <= 1 비교로 안전장치 강화

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:39:39 +09:00
김보곤
c05ebab380 fix:튜토리얼 자막을 하단 한줄로 변경 (중앙 3줄 → 하단 1줄)
- generateAssSubtitle()에 layout 파라미터 추가 (portrait/landscape)
- landscape 모드: PlayRes 1920x1080, 폰트 48pt, Alignment=2(하단 중앙)
- WrapStyle=2 (줄바꿈 없음) + maxCharsPerLine=999 → 한줄 유지
- BorderStyle=3 (반투명 배경 박스) → 가독성 확보
- MarginL/R=20 (좌우 여백 최소) → 최대한 길게
- TutorialVideoJob에서 'landscape' 레이아웃으로 호출

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 17:22:02 +09:00
김보곤
46f1577d65 feat:튜토리얼 영상 멀티스텝 개선 (8초 → 30초~2분)
- ScreenAnalysisService: Gemini 프롬프트를 멀티스텝(3~5 steps) 출력으로 변경 + 하위 호환 fallback
- SlideAnnotationService: 스포트라이트 효과(annotateSlideWithSpotlight), 인트로/아웃트로 슬라이드 생성
- TutorialVideoJob: screen→steps 중첩 루프 + 인트로/아웃트로 씬 추가
- index.blade.php: 단계별 나레이션 편집 UI + 예상 시간 표시

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:36:56 +09:00
김보곤
768bc30a6d feat:사용자 매뉴얼 영상 자동 생성 기능 구현
- TutorialVideo 모델 (상태 관리, TenantScope)
- GeminiScriptService에 callGeminiWithParts() 멀티모달 지원 추가
- ScreenAnalysisService: Gemini Vision 스크린샷 AI 분석
- SlideAnnotationService: PHP GD 이미지 어노테이션 (마커, 캡션)
- TutorialAssemblyService: FFmpeg 이미지→영상 합성 (crossfade)
- TutorialVideoJob: 분석→슬라이드→TTS→BGM→합성 파이프라인
- TutorialVideoController: 업로드/분석/생성/상태/다운로드/이력 API
- React-in-Blade UI: 3단계 (업로드→분석확인→생성모니터링) + 이력

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:56:39 +09:00
김보곤
e4d8dbddb3 fix:자막-음성 싱크 개선 + 나레이션 밀도 증가 + BGM 볼륨 상향
1. 자막 싱크: ffprobe로 실제 TTS 오디오 길이 측정 → 자막 타이밍 반영
   - 기존: 장면 길이 * 0.75 추정 → 음성과 자막 불일치
   - 변경: 실제 나레이션 오디오 길이 기반 문장별 타이밍 계산
2. 나레이션 밀도: 장면당 40~70자 → 60~100자 (빈 시간 없이 채움)
3. BGM 볼륨: 0.4 → 1.2 (안 들리던 문제 해결)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:50:52 +09:00
김보곤
06c6005771 feat:Google Lyria API로 AI 배경음악 생성 연동
Lyria API 연동:
- Vertex AI 기반 Google Lyria 음악 생성 API 추가
- 분위기(mood)별 영어 프롬프트 매핑 (upbeat, energetic, calm 등 8종)
- 생성된 30초 WAV → MP3 변환 + 영상 길이에 맞춰 루프/트림
- 페이드인(1초) + 페이드아웃(3초) 자동 적용
- 비용: $0.06/30초

BGM 우선순위 변경:
- 1순위: Lyria AI 배경음악 (신규)
- 2순위: 프리셋 BGM 파일 (storage/app/bgm/)
- 3순위: FFmpeg 앰비언트 (기존 폴백)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:51:38 +09:00
김보곤
3f4cd88c20 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>
2026-02-15 11:11:18 +09:00
김보곤
60edc28a17 fix:한국인 여성 캐릭터 고정 + 나레이션-영상 싱크 버그 수정
- Gemini 프롬프트: visual_prompt에 한국인 여성(20대) 등장인물 규칙 추가
- Veo 프롬프트: 모든 클립에 "Korean woman in her 20s" 프리픽스 자동 추가
- 싱크 버그: activeNarrationPaths 인덱스 off-by-one ($num-1→$num) 수정
  - 나레이션이 영상보다 1장면 앞서 재생되던 근본 원인
- concatNarrations: atrim+apad로 나레이션을 장면 길이에 정확히 매칭

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:50:51 +09:00
김보곤
01efd99004 fix:자막 중앙배치+크기2배, TTS 볼륨 증가, BGM 앰비언트 자동생성
- 자막: 하단→중앙(Alignment=5), 48→96pt, 외곽선 5px, 줄바꿈 12자
- TTS: 나레이션 볼륨 1.0→2.0 (2배 증가)
- BGM: 무음 대신 분위기별 앰비언트 화음 자동생성 (FFmpeg aevalsrc)
- BGM 볼륨: 0.15→0.4 (나레이션 방해 안 하는 수준)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:45:22 +09:00
김보곤
fb69877330 fix:영상 클립 RAI 필터링 대응 (재시도 + 건너뛰기)
- VeoVideoService.waitAndSave() 반환값을 array로 변경 (실패 원인 포함)
- 클립 생성 실패 시 프롬프트 수정 후 자동 재시도
- 재시도 실패 시 해당 장면 건너뛰고 나머지로 합성 진행
- 성공 클립이 절반 미만일 때만 전체 실패 처리
- 건너뛴 장면의 나레이션/자막 자동 필터링

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 10:01:32 +09:00
김보곤
6ab93aedd2 feat:YouTube Shorts AI 자동 생성 시스템 구현 (Veo 3.1 + Gemini)
- GeminiScriptService: 트렌딩 제목/시나리오 생성
- VeoVideoService: Veo 3.1 영상 클립 생성
- TtsService: Google TTS 나레이션 생성
- BgmService: 분위기별 BGM 선택
- VideoAssemblyService: FFmpeg 영상 합성
- VideoGenerationJob: 백그라운드 처리
- Veo3Controller: API 엔드포인트
- React 프론트엔드 (5단계 위저드)
- GoogleCloudService.getAccessToken() public 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 08:46:28 +09:00