TikTok 제휴)은(는) 무엇을 하나요?
John의 프로덕션 라인: 제품 스크린샷 → 스토리보드 프롬프트 (First Frame UGC Hub 전략) → Google Flow 생성 → TikTok Studio 웹 업로드 (10분 간격으로 분산) → Telegram 상태 알림 → John이 앱 내에서 Shop 제품을 첨부합니다. 반복 방지 + 시네마틱 픽스 (2026년 8월 6일): 마스터 프롬프트 v2.2가 파이프라인에 통합되었습니다. 이제 모든 스크립트 생성은 다음을 따라야 합니다: (1) /home/john/google-flow-automation/master_prompt_v2.2.txt (A-J 섹션) 읽기, (2) python3 /home/john/google-flow-automation/script_rotation.py pick 실행하고 allowed_strategies/allowed_hooks/allowed_ctas/allowed_personas/allowed_cameras/allowed_lighting에서만 선택, (3) 추가 prompt.json 필드(전략/훅_유형/페르소나/CTA_라인/카메라_움직임/조명) 작성, (4) 이후 script_rotation.py record --strategy N --hook ... --cta ... --persona ... --camera ... --lighting --starters ... 실행. 회전 상태는 rotation_state.json에 유지됩니다(마지막 10개 스크립트: 동일한 전략/훅/CTA/페르소나/카메라/조명이 연속으로 사용되지 않음, 마지막 10개 목록의 문장 시작 단어 사용 금지, '노란 바구니' CTA는 3개 비디오당 최대 1회). v2.2의 새로운 기능 (John의 8월 6일 요청): 모든 videoPrompt는 정확히 하나의 카메라 움직임(은행 I.1: 느린 푸시인, 부드러운 풀백, 측면 돌리, 핸드헬드 드리프트, 틸트다운 리빌, 로우앵글 푸시, 오빗, 랙 포커스, 정적 마이크로무브먼트, POV 워크인 — 10초 연속 동작, 정적 샷 금지) + 하나의 조명/분위기(은행 I.2: 골든 아워, 부드러운 창문 햇빛, 아늑한 저녁, 분위기 있는 시네마틱, 깔끔한 스튜디오, 아침의 신선함, 따뜻한 카페 보케, 네온 나이트) + 얼굴 없는 프레임 규칙(I.3: 얼굴을 절대 보여주지 않음 — 손/POV/어깨 너머 뒤에서/제품만; 화면 속 화자가 아닌 내레이션) + 음성 타이밍 사양(H: ≤20단어 = 약 7-8초 음성, 1초에 시작, 비트 사이 미세한 멈춤, 마지막 CTA 단어는 약 8초에 끝나고, 엔드 카드는 8-10초 유지)을 지정해야 합니다. 마스터 프롬프트 사본은 /home/john/google-flow-automation/master_prompt_v2.2.txt에 있습니다(Downloads/ai_studio_master_prompt.txt가 동기화된 소스이며, 편집 후 cp로 복사). 2026년 8월 6일 기준 상태: 섀도우 런 완료 — 파이프라인 종단 간 확인됨. TikTok Studio 업로드 흐름이 같은 날 저녁에 매핑됨 (업로드 + AI 토글 + 업로드 시 제품 첨부; 클릭 경로는 references/tiktok-studio-upload.md에 있음). CDP를 통한 경로 B (flow_driver.py, Chrome 151 네이티브, GOOGLE FLOW 프로필): 업로드 → 첨부 → 규정 준수 프롬프트 → Omni Flash 10초 9:16 x1 생성 → 1080p 업스케일 다운로드 모두 작동. 초기 생성 시도는 일시적으로 실패했지만(일반 메시지, 크레딧 차감 없음) 재시도는 성공했습니다 — Pitfalls 참조.
경로 A — SnapGen API 생성 (2026년 8월 11일 확인 — 새로운 기본 경로)
snapgen_client.py는 이제 첫 번째 생성 선택입니다 (2026년 8월 11일 AUTO_PROMPT 패치): api.snapgen.ai를 통한 순수 HTTP omni-flash 생성 — Chrome/CDP/X11 없음, Flow 크레딧 없음, 정지/대화 상자/이중 생성 실패 클래스 없음. 사용법: timeout 400 ~/.venvs/tiktok/bin/python /home/john/google-flow-automation/snapgen_client.py <작업-디렉토리> [--no-upscale] [--max-retries 3] — prompt.json의 videoPrompt + product_image*.png를 읽고, model=omni-flash 10초 9:16 1080p(프레임 모드 ≤2개 이미지, 재료 3개)를 제출하고, 약 2분 15초 동안 기록을 폴링하고, 서명된 mp4를 다운로드하고, ffmpeg로 1080x1920으로 업스케일합니다(API는 네이티브 720x1280 반환 — 업스케일 엔드포인트 없음; --no-upscale은 720p 유지), generated_video.json을 씁니다. 종료 코드 0 완료 / 1 치명적 오류 / 2 일시적 오류. 비디오당 30 크레딧; SNAPGEN_API_KEY는 프로젝트 .env 파일에 있습니다(John의 계정 PP0001). 충돌 후 재개 (8월 12일 — 두 클라이언트 모두): uuid는 제출 직후 <job-dir>/.snapgen_uuid(omni) / <seg-dir>/<out>.uuid(veo)에 저장됩니다. 재실행 시 클라이언트는 새로 제출하기 전에 먼저 기록에서 해당 uuid를 폴링합니다(서버는 클라이언트가 죽은 후에도 계속 생성합니다 — 2026년 8월 11일 확인: 고아가 된 Veo 제출 3개가 완료되어 복구됨; 재제출하면 크레딧이 이중으로 소모됨). 재개 마커는 성공 시 제거됩니다. veo 재개는 누락된 <out>.json 레코드를 기준으로 합니다(mp4가 아님 — 자르지 않은 부분 mp4는 완료로 간주되어서는 안 됨). 폴백 체인: snapgen → flow_batch.py → 수동 CDP. 음성 해설은 프롬프트 지시(동일한 비트, 정확한 스크립트 아님)에서 자체 Taglish 표현을 즉흥적으로 만듭니다. 이미지 생성 nano-banana-pro는 API를 통해 무료입니다(분당 5회) — 정지 이미지 클라이언트 작업용 — 스크립트에 포함되지 않음(John이 2026년 8월 11일에 결정: Nano Banana는 브라우저 전용으로 유지). 전체 세부 정보 + 확인: references/snapgen-api.md + /home/john/google-flow-automation/SNAPGEN_API_ANALYSIS.md.
/generate 대화형 흐름 + Veo 3.1 고속 경로 (2026년 8월 11일 확인)
SnapGen API를 통한 Veo 3.1 고속 경로 확인 (8월 11일): 4 크레딧, 8.0초, 9:16 허용됨(문서에는 16:9만 가능하다고 했으나 — API는 유연함), 참조 이미지로 프레임-투-비디오, 스크립트를 따르는 Taglish 음성 해설 생성(그대로 전사: "Magaan, komportable, pang araw-araw. Hanapin niyo sa TikTok Shop." — omni-flash와 달리 즉흥적으로 많이 만들지 않음), 네이티브 720x1280 → ffmpeg 1080p, has_watermark=0, 약 2분 15초. 봇 명령어 /generate (telegram_bot.py, ConversationHandler + 인라인 키보드, 8월 11일 라이브): /generate → [TikTok 제휴 | 일반 영상*] (스텁) → [Veo 3.1 고속 | Omni Flash] → 스크립팅 스타일 (CCC/Budol/POV/IRR/TV 광고) → 개수 1-4 → job_orders/generate_<ts>.json 작성 (product_folder = product_image.png + product_page.png가 있는 최신 auto- 폴더; 없으면 봇이 먼저 사진을 보내라고 알림) → 새로운 에이전트를 GENERATE_PROMPT와 함께 생성(--max-turns 400, 로그 job_orders/run_generate_*.log) → 에이전트: OCR로 사실 추출 → 스크립트를 N개 세그먼트로 분할(Veo ≤16단어/세그 8초, Omni ≤20단어/세그 10초; TV 광고 카메라 안무, 세그먼트당 하나의 움직임 및 세그먼트 간 연속성) → Veo 경로: flow_frame_gen.py 첫 번째 프레임 → N × snapgen_veo_client.py → 1개 이상이면 연결 → Telegram sendVideo를 통해 최종 mp4 전송 → 단계 (9): 'TikTok Studio에 업로드하시겠습니까?' 인라인 버튼 전송 (genup:yes: / genup:no:) → 봇의 gen_upload_choice 핸들러가 ~/tiktok-jobs/에서 basename을 확인하고 예를 선택하면 업로드 전용 에이전트를 생성(UPLOAD_PROMPT — final.mp4+prompt.json이 이미 존재하므로 업로드/예약만: 다음 사용 가능한 오전 6시/오후 6시 슬롯 → tiktok_studio_upload.py → 게시물 페이지 확인 → 알림); 아니요를 선택하면 비디오가 로컬에 남습니다. Omni 경로: N × flow_batch.py (재료) → 연결 → 전송 → 동일한 단계 (9). GENERATE_PROMPT에 내장된 하드 규칙 (8월 11일): /generate 에이전트는 절대 TikTok Studio를 건드리지 않습니다 — tiktok_studio_upload.py 없음, Studio 페이지 없음; 단계 (9) 버튼만이 업로드로 가는 유일한 경로이며, 봇(에이전트 아님)이 실행합니다. 프레임 생성 실패 시 폴백 (8월 11일): 한 번 재시도한 다음 실패한 세그먼트에 대해 이전의 좋은 프레임(frame_<i-1>.png)을 재사용합니다. 모든 프레임이 실패하면 --ref 없이 Veo 세그먼트를 실행하거나 Omni로 폴백합니다. 하나의 프레임 때문에 주문을 차단하지 말고, Studio 업로드를 즉흥적으로 실행하지 마십시오.
/generate는 최신 스테이징 폴더를 대상으로 합니다 — 오래된 제품 함정 (8월 11일): latest_product_folder()는 이미 product_image.png + product_page.png가 있는 가장 최근의 auto-* 폴더를 선택합니다. John이 다른 제품의 새 사진을 보내고 같은 분에 /generate를 실행하면 작업이 이전 제품의 폴더를 대상으로 할 수 있습니다(실제 사례: 06:17 /generate가 auto-20260811_054254/Smasher를 가져갔지만 그의 새 사진은 Product Folder에 준비되지 않은 상태였습니다 — 그의 접수 순서는 잘못된 제품에 대한 생성 작업 뒤에 대기열에 추가되었고 그는 "왜 이러지?"라고 물었습니다). "⏳ 귀하의 요청이 대기열에 있습니다" 응답은 올바른 동시성 보호 동작이며 버그가 아닙니다. 그러나 /generate 주문이 대기열에 추가되면 실행하기 전에 어떤 auto-* 폴더를 가리키는지 확인하십시오. 잘못된 제품이면 에이전트를 종료하고 해당 generate_<ts>.json을 삭제하여 대기열에 있는 접수(새 폴더 스테이징)가 활성 작업이 되도록 하십시오.
분리 실행 패턴 (8월 11일 업데이트 — setsid는 이제 차단됨): 터미널 도구는 포그라운드에서 setsid bash -c '...' &를 거부합니다("셸 수준 백그라운드 래퍼"). 대신 systemd-run을 사용하십시오 — 동일한 분리 의미, 완전히 도구의 프로세스 그룹 외부: systemd-run --user --unit=<이름> --collect bash -c '<명령어> > <로그> 2>&1; echo $? > <종료파일>', 그런 다음 약 30초마다 cat <exitfile>을 폴링합니다. systemctl --user is-active <이름> + 로그 꼬리 보기로 실행을 확인합니다. 유닛은 --collect로 자체 정리됩니다. 2026년 8월 11일 확인(seg_2 생성 + 연결 모두 이 방식으로 실행됨; 충돌 후 재개가 깔끔하게 작동함).
충돌 후 재개 규칙 (8월 11일, 실제): 파이프라인 에이전트가 주문 도중에 죽으면 작업 폴더에 확인된 상태가 있습니다 — 무엇이든 다시 생성하기 전에 확인하십시오. seg_1.mp4 + seg_1.mp4.json (ffprobe 확인) + seg_1.json/seg_2.json (스크립트가 이미 작성되고 회전이 이미 기록됨) + first_frame.png는 모두 충돌 후에도 유지됩니다. 이를 재사용하고 누락된 세그먼트만 생성하십시오. script_rotation.py record를 다시 실행하지 마십시오(이중 계산은 반복 방지 상태를 손상시킴) 그리고 seg JSON을 다시 쓰지 마십시오(seg_1.mp4는 정확히 해당 프롬프트로 만들어졌습니다).
새 스크립트 (모두 2026년 8월 11일 종료 코드 0 확인됨):
flow_frame_gen.py <작업-디렉토리> --prompt "<9:16 이미지 프롬프트>" [--out first_frame.png]— Flow CDP를 통한 Nano Banana 2 첫 번째 프레임 (브라우저 전용 — John의 규칙, 이미지 API 절대 사용 금지): 새 프로젝트 → 라이브러리 업로드 → attach_smart (라이브러리가 이미 열려 있지 않은 경우에만 더하기 기호를 클릭함 — 더하기 기호는 토글되어 두 번째 클릭 시 닫히며 Add to Prompt를 조용히 죽임; 수정 확인) → settings_chip를 통한 설정 팝업(프롬프트 막대 칩, y~714 하단, 텍스트 "Video · 10s crop_9_16 x1"/"🍌 Nano Banana 2 …" —find_btn의 첫 번째 일치가 상단 표시줄 기어를 선택하므로y>550+가장 작은 버튼프로브 사용) → role=tab 'Image' (탭 텍스트는 글리프 접두사가 붙음: "imageImage"/"videocamVideo" —==대신includes('Image')로 일치) → 종횡비 crop_9_16 탭 → Agent 필 그레이 체크 → 입력 + focus+Enter 제출(이미지의 경우 화살표가 작동하지 않음) → 이미지 카드 대기 → cookie+curl 수집기를 통해 download_frame (dump_cdp_cookies.py+flow_collect_media.py; 9:16 이미지 선택; 그리드 렌더링 ~768x1376 — Veo 참조로 괜찮음; 뷰어 클릭 금지 — 뷰어의 다운로드 메뉴는 지뢰밭: "1K Original size"만 표시되고 잘못된 클릭 시 인접한 휴지통 아이콘을 누르게 됨 ("1개 항목이 휴지통으로 이동됨" — 라이브러리 휴지통 보기 → 모두 복원에서 복원). 수집기 수정 8월 12일: 캐릭터 시트(1536x2752)도 9:16이므로 이전 종횡비 전용 선택기가 시트를 생성된 프레임 대신 가져갔습니다(08:27 실행의 frame_1 및 frame_3 — 에이전트가 수동 수정해야 했음). download_frame은 이제 캐릭터 시트의 정확한 크기를 제외하고 (768,1376)을 우선합니다. 새 프로젝트는 기본적으로 이미지 모드로 설정됩니다(Nano Banana 2 crop_9_16).snapgen_veo_client.py <작업-디렉토리> --prompt "<세그먼트>" --ref <프레임.png> --out seg_<i>.mp4 [--model veo-3.1-fast] [--duration 8] [--aspect 9:16] [--no-upscale]— API를 통한 하나의 세그먼트 (snapgen_client의 확인된 함수 재사용;job-dir/segments/에 씀). 종료 코드 0/1/2.stitch_videos.py <출력.mp4> <입력...>또는<작업-디렉토리> --out final.mp4(정렬된segments/*.mp4를 글로브함; 8월 12일 패치:*.raw.mp4네이티브는 이제 글로브에서 제외됨 — 이전의 '먼저 raw를 이동' 규칙은 이제 코드 가드이며, 더 이상 중간 비디오에 720p가 삽입되지 않음) — 균일한 재인코딩(1080x1920 24fps crf18 aac44.1 pad) + RE-ENCODE로 연결(-c copy아님:-c copy는 입력 시간 기준이 다른 경우 잘못된48/1 r_frame_rate헤더를 씀, 예:trim_dead_air의select/setpts이후; 재인코딩은 깔끔한 24/1을 제공함 — 8월 11일 패치). 확인됨: 10초+8초 → 18.0초 h264 1080x1920. 편집 패스 + 자막 (8월 15일):--edit auto가 이제 기본값입니다 — 프롬프트를 인식하는 세그먼트별 카메라 움직임(프롬프트에 카메라 동작이 명명된 세그먼트에는 추가 움직임이 없음; 다른 세그먼트는 위치에 따라 부드러운 푸시인/풀아웃), 밝기 조정(대비 1.03/채도 1.05), 세그먼트 간 0.25초 크로스페이드(비디오 xfade + 오디오 acrossfade, c1=tri:c2=tri — 이 ffmpeg는 'fade'를 거부함).--caption(일반/보통 모드 전용 — 제휴는 절대 사용하지 않음)은 최종 연결된 비디오를 Groq(무료,~/video-tools/groq_transcribe.py어댑터 →deepcaption build_captions.py→~/video-tools/burn_ass.py네이티브 해상도 번, 스타일 최소 기본값)로 전사합니다. 누락된 키/도구 → 자막은 경고와 함께 건너뛰며, 연결은 실패하지 않습니다. 모든 모드는 실제 vox_bf2 세그먼트(22.97초 크로스페이드, 자막 처리, 프레임 확인됨)에서 8월 15일에 확인됨. 전체 무료 자막 플레이북은 skill groq-video-captions를 참조하십시오.trim_dead_air.py <입력.mp4> [--out ...]— 무음 구간 자르기 (John의 8월 11일 규칙: "아무도 말하지 않는 부분을 잘라내십시오"): Veo/Omni 클립은 긴 조용한 꼬리를 가지고 있습니다(확인됨: seg_1 음성 0-3.26초 중 8초 = 4.7초 무음; 첫 번째 연결된 테스트 비디오의 43%가 주변 소음이었습니다). faster-whisper 단어 타임스탬프(실측 — 에너지 임계값은 여기서 실패합니다. 주변 꼬리가 고정된 RMS 컷오프 이상에 있기 때문)로 음성을 감지하고[첫 번째 단어−0.25초, 마지막 단어+0.35초]를 유지한 다음 ffmpegselect/aselect단일 패스로 재구축합니다. ~/.venvs/crypto/bin/python으로 실행합니다(faster-whisper가 있는 유일한 venv). 종료 코드 0 자름 / 2 자를 것 없음 / 3 오류(원본 유지 — 모든 곳에서 비치명적).snapgen_client.py,snapgen_veo_client.py(--no-trim으로 비활성화),flow_batch.py(다운로드 후)에 자동 연결됨 — 생성된 모든 세그먼트는 소스에서 잘립니다. /generate 에이전트는 명목상의 8초/10초 길이를 "복원"하기 위해 세그먼트를 다시 생성해서는 안 됩니다(확인됨: seg_1 8초→3.6초는 정확함). Trim은 crf 18로 재인코딩하여 프레임 속도/헤더가 깔끔하게 유지됩니다. 함정 (8월 12일에 대부분 수정됨):snapgen_veo_client는<out>.raw.mp4(네이티브 720p)를segments/에 남깁니다.stitch_videos.py는 이제 글로브에서*.raw.mp4를 제외하므로 중간 비디오에 720p가 삽입되는 일은 더 이상 발생하지 않습니다. 하지만 raw를job-dir/raw_720p/로 이동하는 것은 여전히 좋은 습관입니다. 또한:--out final.mp4는 작업 디렉토리가 아닌 스크립트의 CWD(현재 작업 디렉토리)를 기준으로 확인됩니다. 절대 경로를 전달하거나 먼저cd로 작업 디렉토리로 이동하십시오(상대--out에cwd=google-flow-automation이 있으면 조용히final.mp4를 거기에 씁니다).- GENERATE_PROMPT는
telegram_bot.py에 있습니다(단일 소스;.format()플레이스홀더:config/mode/caption/model/style/count/product_folder/chat_id/duration— 템플릿에 이스케이프되지 않은 중괄호 없음, 리터럴 JSON 중괄호는format을 충돌시킴). 편집 후 봇을 다시 시작하십시오. 8월 15일: /generate 마법사는 이제 두 모드를 모두 지원합니다(일반 모드가 더 이상 막다른 골목이 아님) — 일반 모드는 "자막 추가"(예/아니요 → 편집 패스(예/아니요) → 스타일 선택(CCTV 캠/자연스러운/시네마틱/영화관) → 세그먼트당 뉴스 음성 톤 질문 → 요약 확인을 묻습니다. 제휴 모드는 음성 톤을 건너뛰고 자막을 강제로 차단합니다. 두 모드 모두 비디오를 생성하고 동일한 단계 (9) 업로드 질문을 합니다. 없음이 차단되지 않았습니다. 8월 15일 마법사 UI: 모든 선택은 인라인 키보드 버튼입니다(이전의 텍스트만 응답이 아님, 혼란스러운 "freeform" 상태 제거됨 — 전환하는 동안에도 사용자는 항상 버튼을 봅니다). "대기 중" 애니메이션 없음 — 봇은 처리 중에 행동을 취합니다. 검증된 경로: /generate → 상점 전환 → 스타일 선택 메시지(버튼: CCC, POV, TVC, 스토리텔링/버디) → 세그먼트 수 → script_gen 실행 중입니다… → (30초 후) 비디오가 생성 중입니다… → (120초 후) 비디오가 거의 준비되었습니다… → 완료, 업로드하시겠습니까? — 봇이 업로드할 때까지 총 20회전, 마법사 13회전. 에이전트 점프 수정 (8월 15일): 일련번호가 매겨진 동작들은(22:18:31 → 22:18:33) 원래 이전 스크립트 출력 직후에 에이전트가 "음...여기 팔로우업이 있습니다"라고 대답할 때 발생했습니다 — 이제 GENERATE_PROMPT는 마법사 동작들을 RUN_SILENT로 명시적으로 표시합니다(에이전트가 메시지를 생성하지 않음). 이는 별개의 문제인 오디오 관련 후속 조치(아래 Pitfalls 참조)를 수정하지 않습니다.
수집기 세부 정보
flow_collect_media.py는 쿠키 + 컬 기반 다운로더로, CDP 기반 다운로드보다 빠르고 안정적입니다. dump_cdp_cookies.py는 Chrome 쿠키(cookies.json)를 덤프합니다. 수집은 캔버스의 썸네일 그리드를 사용합니다(뷰어 이미지 아님 — 뷰어는 네비게이션 지뢰밭임). 텍스트 프롬프트 생성은
…
(원본 내용이 잘렸습니다. 전체 번역을 위해 원본의 나머지 부분을 제공해 주십시오.)