# -*- coding: utf-8 -*- # 動画「ハコブくんの声と絵は、どう作っているのか」(シリーズ「ひとりとAIのチーム」4回目・描く係と声の係)の場面 PATTERN = 2 # 画面パターン2(大文字型・video_rules.md 4-4c) MOVE = True # 画面型の動き(4-4d)を強弱を付けて使う(2026-11-01 エイイチが選んだ) # 2026-11-01: 「AIに昨日の続きをさせる」の scenes.py の形を写して書いた # 強弱(video_rules.md 4-4d): # 中: manga(縦長の並び)・vd_text(頼んだ文章)・size(チェック項目) # 強(11場面・続けない): hook_koma(腕が3本のコマ)・question・body(体の絵)・fail_arm(直す前/直した後)・ledger(22 と数え上げ)・ # listen_old(前の声の動画)・cast(10 個)・read_table(207 と数え上げ)・quiz_ans・mitate_job・answer2 # 背景の「画面」は、記録のファイルをエディタの見た目で描いて下へ送った映像(make_bg.py。中身は記録のまま) # マンガの絵は生成AI(Gemini)で描いた物。直す前の絵(腕が3本)は 第121話/生成/第121話_P3_20261030_114254.jpg import os as _os, sys as _sys _here = _os.path.dirname(_os.path.abspath(__file__)) for _c in (_os.environ.get("P2M_BASE", ""), _os.path.join(_here, "..", "base"), _os.path.join(_here, "..", "_制作ベース")): if _c and _os.path.exists(_os.path.join(_c, "scene_kit.py")): _sys.path.insert(0, _c); break from scene_kit import * from motion_kit import use_motion, CAP import json as _json, base64 as _b64 from scene_kit import _p2page # --- 場面ごとの、文の始まりの秒(声の長さから)。「車は作れるのにロボは作れない」の scenes.py から写した --- _idx = _json.load(open(_os.path.join(_here, 'tts/index.json'))) if _os.path.exists(_os.path.join(_here, 'tts/index.json')) else [] _LINES = {} for _o in _idx: _d = _LINES.setdefault(_o['scene'], []) _t0 = (_d[-1][0] + _d[-1][1] + _d[-1][2]) if _d else 0.0 _d.append((_t0, _o['dur'], _o['pause'])) def at(scene, k=0, f=0.0): L = _LINES.get(scene) if not L: return 0.3 k = min(k, len(L) - 1) return round(L[k][0] + L[k][1] * f, 2) def scene_len(scene): L = _LINES.get(scene) return (L[-1][0] + L[-1][1] + L[-1][2]) if L else 4.0 FUDA_CSS = """ .fuda{position:absolute;left:140px;top:96px;display:flex;align-items:center;gap:14px;font-size:30px;font-weight:700;color:#0D0D0D} .fuda .k{padding:6px 18px;border-radius:999px;font-size:28px;font-weight:900} .fuda .k.ei{background:#C4471F;color:#fff} """ def fuda(who): return f'