- youtube_uploader.py: YOUTUBE_REFRESH_TOKEN/CLIENT_ID/CLIENT_SECRET 환경변수 폴백 추가 (token.json 없는 Docker 환경에서 브랜드 계정 인증 가능) - shorts_config.json: corners_eligible를 실제 블로그 코너명으로 수정 - caption_renderer.py: render_captions() 반환값 누락 수정 - get_token.py: web→installed 타입 변환, port 8080 고정, prompt=consent 추가 - get_youtube_token.py: YouTube 전용 OAuth 토큰 발급 스크립트 (별도 클라이언트) - CLAUDE.md: 프로젝트 개요, 배포 방법, 핵심 파일, YouTube 채널 정보 추가 - publisher_bot.py: 이미지 분산 배치, SEO 검증, 버그 수정 - scheduler.py: 알림 강화, atomic write, 중복 방지, hot reload 개선 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
152 lines
4.4 KiB
JSON
152 lines
4.4 KiB
JSON
{
|
|
"enabled": true,
|
|
|
|
"production_mode": "auto",
|
|
"_production_mode_options": ["auto", "semi_auto"],
|
|
"_production_mode_notes": {
|
|
"auto": "Full pipeline: blog post → LLM script → stock/character visuals → TTS → render → upload. Zero manual steps.",
|
|
"semi_auto": "Engine checks input/ folder FIRST. Any user-provided asset overrides the corresponding auto step. Missing assets fall back to auto."
|
|
},
|
|
|
|
"schedule": {
|
|
"frequency": "daily",
|
|
"times": ["10:30", "16:00"],
|
|
"max_per_day": 2
|
|
},
|
|
|
|
"input_dirs": {
|
|
"_description": "Semi-auto mode: drop files here to override auto-generation. Files are matched by article_id prefix or consumed in order.",
|
|
"images": "input/images/",
|
|
"videos": "input/videos/",
|
|
"scripts": "input/scripts/",
|
|
"audio": "input/audio/"
|
|
},
|
|
|
|
"assets": {
|
|
"_description": "Pre-made character and background assets. Generated once via ChatGPT Pro, reused across all videos.",
|
|
"characters": {
|
|
"fourth_path": {
|
|
"name": "zero",
|
|
"display_name": "Ø",
|
|
"default_pose": "assets/characters/zero/zero_front.png",
|
|
"poses_dir": "assets/characters/zero/poses/",
|
|
"expressions_dir": "assets/characters/zero/expressions/",
|
|
"backgrounds_dir": "assets/backgrounds/fourth_path/"
|
|
},
|
|
"tech_blog": {
|
|
"name": "bao",
|
|
"display_name": "바오",
|
|
"default_pose": "assets/characters/bao/bao_front.png",
|
|
"poses_dir": "assets/characters/bao/poses/",
|
|
"expressions_dir": "assets/characters/bao/expressions/",
|
|
"scarves_dir": "assets/characters/bao/scarves/",
|
|
"backgrounds_dir": "assets/backgrounds/tech_blog/"
|
|
}
|
|
},
|
|
"corner_character_map": {
|
|
"AI인사이트": "tech_blog",
|
|
"여행맛집": "tech_blog",
|
|
"스타트업": "tech_blog",
|
|
"제품리뷰": "tech_blog",
|
|
"생활꿀팁": "tech_blog",
|
|
"앱추천": "tech_blog",
|
|
"재테크절약": "tech_blog",
|
|
"재테크": "tech_blog",
|
|
"팩트체크": "tech_blog"
|
|
},
|
|
"character_overlay": {
|
|
"enabled": true,
|
|
"position": "bottom_right",
|
|
"scale_width": 300,
|
|
"margin_right": 40,
|
|
"margin_bottom": 250
|
|
}
|
|
},
|
|
|
|
"script": {
|
|
"language": "ko",
|
|
"max_hook_words": 8,
|
|
"max_body_sentences": 3,
|
|
"target_duration_sec": 20,
|
|
"llm_provider": "openclaw",
|
|
"llm_fallback": "claude_api"
|
|
},
|
|
|
|
"visuals": {
|
|
"_description": "Priority chain for sourcing visual clips per video segment.",
|
|
"source_priority": [
|
|
"input_dir",
|
|
"character_assets",
|
|
"pexels",
|
|
"pixabay",
|
|
"image_kenburns_fallback"
|
|
],
|
|
"pexels_api_key_env": "PEXELS_API_KEY",
|
|
"pixabay_api_key_env": "PIXABAY_API_KEY",
|
|
"orientation": "portrait",
|
|
"min_clips": 3,
|
|
"max_clips": 5,
|
|
"prefer_vertical": true
|
|
},
|
|
|
|
"tts": {
|
|
"engine_priority": ["elevenlabs", "google_cloud", "edge_tts"],
|
|
"elevenlabs": {
|
|
"api_key_env": "ELEVENLABS_API_KEY",
|
|
"voice_id": "pNInz6obpgDQGcFmaJgB",
|
|
"model": "eleven_multilingual_v2",
|
|
"speed": 1.1,
|
|
"stability": 0.5,
|
|
"similarity_boost": 0.8
|
|
},
|
|
"google_cloud": {
|
|
"credentials_env": "GOOGLE_APPLICATION_CREDENTIALS",
|
|
"voice_name": "ko-KR-Neural2-C",
|
|
"speaking_rate": 1.1
|
|
},
|
|
"edge_tts": {
|
|
"voice": "ko-KR-SunHiNeural",
|
|
"rate": "+10%"
|
|
},
|
|
"inter_sentence_pause_ms": 300
|
|
},
|
|
|
|
"caption": {
|
|
"font_ko": "Pretendard",
|
|
"font_en": "Inter",
|
|
"font_size": 48,
|
|
"hook_font_size": 72,
|
|
"highlight_color": "#FFD700",
|
|
"default_color": "#FFFFFF",
|
|
"outline_color": "#000000",
|
|
"outline_width": 3,
|
|
"position_from_bottom": 200,
|
|
"max_chars_per_line_ko": 18,
|
|
"max_chars_per_line_en": 40
|
|
},
|
|
|
|
"video": {
|
|
"resolution": [1080, 1920],
|
|
"fps": 30,
|
|
"crf": 18,
|
|
"codec": "libx264",
|
|
"audio_codec": "aac",
|
|
"audio_bitrate": "192k",
|
|
"crossfade_sec": 0.3,
|
|
"fade_in_sec": 0.5,
|
|
"fade_out_sec": 0.5,
|
|
"bgm_path": "assets/bgm/default_loop.mp3",
|
|
"bgm_volume_db": -18
|
|
},
|
|
|
|
"youtube": {
|
|
"category_id": "28",
|
|
"privacy_status": "public",
|
|
"default_tags": ["shorts", "AI", "테크"],
|
|
"made_for_kids": false,
|
|
"daily_upload_limit": 6
|
|
},
|
|
|
|
"corners_eligible": ["AI인사이트", "여행맛집", "스타트업", "제품리뷰", "생활꿀팁", "앱추천", "재테크절약", "재테크", "팩트체크"]
|
|
}
|