feat: 쇼츠 품질 모듈 4종 파이프라인 연결
- MotionEngine: stock_fetcher에서 kenburns 대신 7패턴 모션 적용 - HookOptimizer: 스크립트 추출 후 훅 점수 평가 및 최적화 - CaptionTemplates: 코너별 자막 템플릿 매핑 (AI인사이트→brand_4thpath 등) - ResilientAssembler: 클립별 개별 인코딩 + GPU 자동 감지 - video_assembler work_dir mkdir 누락 버그 수정 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -278,6 +278,10 @@ def fetch_clips(
|
||||
expressions = manifest.get('expressions', [])
|
||||
char_pose = manifest.get('pose', manifest.get('character', {}).get('default_pose', ''))
|
||||
|
||||
# MotionEngine: 정지 이미지에 7가지 모션 패턴 적용 (직전 2개 제외 자동 선택)
|
||||
from shorts.motion_engine import MotionEngine
|
||||
motion = MotionEngine()
|
||||
|
||||
result_clips: list[Path] = []
|
||||
|
||||
# 1. 사용자 제공 비디오 클립
|
||||
@@ -286,23 +290,24 @@ def fetch_clips(
|
||||
if _prepare_clip(Path(user_clip), out):
|
||||
result_clips.append(out)
|
||||
|
||||
# 2. 사용자 제공 이미지 → Ken Burns
|
||||
# 2. 사용자 제공 이미지 → MotionEngine (7패턴 자동 선택)
|
||||
for i, user_img in enumerate(manifest.get('user_images', [])[:max_clips]):
|
||||
if len(result_clips) >= max_clips:
|
||||
break
|
||||
out = clips_dir / f'clip_img_{i+1:02d}.mp4'
|
||||
if _kenburns_image(Path(user_img), out):
|
||||
result_clips.append(out)
|
||||
result_path = motion.apply(str(user_img), duration=6.0, output_path=str(out))
|
||||
if result_path:
|
||||
result_clips.append(Path(result_path))
|
||||
|
||||
# 3. 캐릭터 에셋 + 배경 합성
|
||||
background = manifest.get('background', '')
|
||||
if background and Path(background).exists() and len(result_clips) < max_clips:
|
||||
# 배경 이미지 → Ken Burns 클립 (표정별 합성)
|
||||
# 배경 이미지 → MotionEngine 클립 (표정별 합성)
|
||||
for seg_idx, expr_png in enumerate(expressions[:3]):
|
||||
if len(result_clips) >= max_clips:
|
||||
break
|
||||
out_bg = clips_dir / f'clip_bg_{seg_idx+1:02d}.mp4'
|
||||
if _kenburns_image(Path(background), out_bg):
|
||||
if motion.apply(str(background), duration=6.0, output_path=str(out_bg)):
|
||||
# 표정 오버레이
|
||||
if expr_png and Path(expr_png).exists():
|
||||
out_char = clips_dir / f'clip_char_{seg_idx+1:02d}.mp4'
|
||||
@@ -374,8 +379,9 @@ def fetch_clips(
|
||||
while len(result_clips) < min_clips:
|
||||
stock_idx += 1
|
||||
out = clips_dir / f'clip_fallback_{stock_idx:02d}.mp4'
|
||||
if _kenburns_image(fallback_img, out):
|
||||
result_clips.append(out)
|
||||
result_path = motion.apply(str(fallback_img), duration=6.0, output_path=str(out))
|
||||
if result_path:
|
||||
result_clips.append(Path(result_path))
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user