Claude の使い方を実例で伝える ― Unity の舞台で縦長ショート10本

Claude の使い方を実例で伝える ― Unity の舞台で縦長ショート10本

この記事の素材(コード・ログ・データ 15ファイル・まとめてダウンロードあり)
AIで読む ChatGPT・Claude などで、この記事に質問できます

TikTok で見かけた縦長動画の構図(奥の板に1つずつ出し、2人が床の円の上に立ち、足もとに字幕を置く)を、Claude Code が Unity で13分で建てた夜の作業部屋の舞台に置き換え、Claude と Claude Code の使い方を話す22〜29秒のショートを10本作りました。 10本は YouTube に上げる前に、X へ動画付きで、11月17日から26日まで毎晩22:00に1本ずつ予約しました。

この型ができて、次のことが変わりました。

  • 次の1本は、舞台を撮り直さずに作れる。変えるのは、セリフ(narration.py)と、奥のモニターに出す画面と動き(spec.py)だけ。2本目から10本目は、この形で作った
  • 見た目の決まりを部品と動画の決まり(video_rules.md の12節)に残した。モニターの中は面で組み、1画面で言うことは1つ、オレンジは「いま話している1つ」だけ。山場の演出は紙吹雪のほかに7つ用意し、毎回同じにしない
  • 公開のあとに、エイイチの指摘で3つ直した。2本目からの8本で最後のサイトへの入口を入れ忘れていたのを足し、文字の被りを0.1秒ごとに機械で探す点検(check_overlap.py)を作って4本の被りを直し、締めの「公開中」の言い方を4通りから選び直した。どれも動画の決まりに書き足した
  • 時間:舞台を建てて撮るまでは13分(依頼箱の記録・22:46〜22:59)。1本の書き出しは、作業環境で2本ずつ並べて動かして、8本で約16分だった(並べた回の時刻からの見積もりで、1本ずつは測っていない)。前の型と比べて何分縮んだかは、前を測っていないので分からない

きっかけは、エイイチが TikTok で見た、きよさん(「きよ | ゲーム感覚でAI×SNS」)の縦長動画「SNS運用、Claudeが終わらせた」です(画面写真で共有を受けたので、動画の URL は控えていません)。薄暗い部屋の床の円の上に作者の分身と Claude 役のキャラクターが立ち、奥の板に「スキル一覧」が1つずつ出て、下に字幕が出る。1画面に1つしか出さないので、スマホでも字が大きく読めます。ねらいは、Claude と Claude Code をふだんどう使っているかを、ひとり研究所の実例で伝えることで、この構図はその入れ物にちょうどよい形でした。中身(SNS の自動化の11個のスキル)は取り込まず、構図だけを借りて、中身と舞台はうちのものに置き換えています。

やったことなぜ結果
参考の動画から、取り込む所と取り込まない所を決めた
バズを集める仕組みは、主指標(再現できる環境の数)と逆を向くため
構図(舞台・奥の板・床の円・足もとの字幕)だけを借りる
Claude Code に Unity で舞台を建ててもらった(依頼箱 #99)
毎回同じ舞台を使い、見た瞬間にうちの動画だと分かるようにするため
夜の作業部屋・オレンジのふちのモニター・黄色と黒の破線の円。13分で撮れた
書き出しの部品 butai_kit.py を作った
舞台の上に、モニターの中身・2人・字幕を重ねるため
1本目「研究のスキル一覧」29.2秒
エイイチの指摘で3回直した
距離感・モニターの雑さ・紙吹雪・床の円
2人を寄せ、モニターを面で組み、床の円を回した
部品 butai_parts.py にまとめ、9本を作った
2本目からはセリフと画面だけを書けば済むようにするため
Claude・Claude Code ネタで19〜24秒の9本(締めを足したあとは22〜28秒)
紙吹雪のほかの演出を7つ足した
エイイチ「毎回紙吹雪なので違うパターンも考えて」
光の筋・集中線・波紋・スポットライト・星・光の帯・立ちのぼる四角
X に動画で予約した
AIあるある と同じく、YouTube より先に X で出すため
11/17〜26 の 22:00
最後にサイトへの入口を足した
エイイチ「うちのサイトへの動線部分がないけど?」。X の文にリンクを入れていないので、動画の中が唯一の入口
10本とも pixelstomotors.com で締める。すべての型の動画の決まりにした
文字の被りを機械で探した
エイイチ「文字が被ってるところがある」
check_overlap.py を作り、4本の被りを直した
締めの声を作り直した
エイイチ「最後の「公開中」のイントネーションが変」
4通りを聞き比べ、エイイチが「公開中です!」を選んだ
舞台型のショート10本の9秒目のコマ。どれも同じ作業部屋の舞台で、奥のモニターの中身とセリフだけが違う

作業ログ ― 参考の縦長動画から、取り込む所と取り込まない所を決める

取り込むのは構図だけで、中身の「バズ研究」は取り込まない

エイイチが、参考の動画の画面写真を9枚送ってきたところから始まりました。最初の返事では、中身(投稿・バズ研究・X収集・伸びた分析・週次レポ・リール台本・図解動画・解説動画・アフィ投稿の11個のスキル)は、すでに回っているもの(サイトの計測・LinkedIn の分析の書き出し・自動の予約・動画のスキル)と重なり、「バズを集めて寄せる」方向は MASTER の主指標(再現できる環境の数)と逆を向くので、仕組みとしては取り込まない、と答えています。そのうえで、使えるのは見せ方だと分けました。

参考の動画取り込むかうちでは
作者の分身と Claude 役が、同じ床の円の上に立つ
取り込む
左にハコブくん(Claude 役)、右にエイイチ。2人とも全身で、身長の比(1.15m・1.7m)で立つ
上に大きい見出し、奥の板に1つだけ、下に字幕
取り込む
見出しは最後まで同じ。奥の壁のモニターに1つずつ出す
上の「CLAUDE VS 手作業SNS」の体力ゲージ
今回は入れない勝負の形の話ではないため
薄暗い本棚の部屋・ろうそく・青緑の円
なぞらない
夜のロボットの作業部屋・卓上ライト・作業エリアの黄色と黒の破線の円
11個のスキル(SNS の自動化)
取り込まない
中身はエイイチが実際に使っている仕組みだけにする

エイイチの答えは「これをうちに取り込める?取り込むためにはどんなことをしますか?」で、舞台をつくる・キャラを全身で立たせる・板の中身を型にする・画面の文字の位置を固定する・決まりに書く・試作を1本つくる、の6つを出しました。1本目の題材は、エイイチが「研究をひとりとClaudeで回すスキル一覧」を選びました。

1本目の板に並べる7つと、「いちばん助かっているもの」の理由

板に並べる候補は、研究そのもの・確かめる・記録と発信、の3つに分けて11個を出し、エイイチが「研究寄りの6〜7個に絞る」を選びました。並べたのは、運用分析・GPUで学習・依頼箱・課題地図・事実確認・声の単語帳・記録→記事の7つです。「いちばん助かっているもの」はエイイチが依頼箱を選び、理由は次の言葉でした。

今まで煩わしかったターミナルでの作業から解放されたこと

この言葉を、エイイチのセリフ「依頼箱。今まで煩わしかった、ターミナルの作業から、解放された!」にしています。ユーモアや実体験を Claude が作ると嘘っぽくなるので、エイイチのセリフは本人の言葉から取る、という前からの決まり(video_rules.md)どおりです。舞台は、画像で作る案と Unity で建てる案を出し、エイイチが Unity を選びました。

作業ログ ― 依頼箱で Claude Code に Unity の舞台を建ててもらう

この記事のコード・ログ・データは、1ファイルずつ下に置いています。全文はリンク先にあります。

ファイルの一覧(15本)

01_sec02.md ― Claude Code の報告(全文)・3,077字

02_VideoStageBuilder.cs.txt ― 舞台を組み立てて撮る VideoStageBuilder.cs(全文)・32,036字

03_butai_kit.py.txt ― butai_kit.py(全文)・25,521字

04_butai_parts.py.txt ― butai_parts.py(全文)・13,299字

05_spec.py.txt ― 01 研究のスキル一覧 の spec.py・14,621字

06_spec.py.txt ― 02 Claude Codeへの頼み方 の spec.py・4,555字

07_spec.py.txt ― 03 寝ている間に回す の spec.py・4,315字

08_spec.py.txt ― 04 Claudeに覚えてもらう の spec.py・4,116字

09_spec.py.txt ― 05 記事の公開は誰が の spec.py・4,789字

10_spec.py.txt ― 06 別のAIに疑わせる の spec.py・4,129字

11_spec.py.txt ― 07 並行で作る の spec.py・4,763字

12_spec.py.txt ― 08 Claudeのデザイン の spec.py・5,494字

13_spec.py.txt ― 09 全部ログに残す の spec.py・4,317字

14_spec.py.txt ― 10 このショートの作り方 の spec.py・3,995字

15_sec10.py.txt ― エイイチ「文字が被ってるのところがある」・3,989字

依頼箱は、Claude が書いた依頼を Mac の見張り係が Claude Code に渡す仕組み

依頼箱は、Claude が書いた Claude Code あての依頼を置くフォルダです。Mac で動く見張り係(inbox_runner.py)が1件ずつ Claude Code に渡し、報告を「結果」に書き戻します。自動で回してよいのは、決めた作業フォルダ(ServiceSim と r2r2r-scripts)だけです。舞台は ServiceSim のプロジェクトの中に、Assets/VideoStage/ として足してもらいました。既存のシーンと設定には触れない、と依頼文に書いています。

依頼箱 #99 の依頼文(全文)

---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 90
---
# ショート動画用の「舞台」を Unity で建てて、縦長の背景として撮る

## 目的
縦長ショート(1080×1920)の背景に使う、固定カメラの「舞台」を1つ作る。キャラ(ハコブくん・エイイチの2Dの絵)と、壁のモニターの中身(文字・図)は、あとで Claude が動画側で重ねる。Unity で撮るのは背景だけ。

## 守ること
- ServiceSim の既存のシーン・スクリプト・設定(ビルド設定・時間・物理)は一切変えない。新しく作るのは `Assets/VideoStage/` の中だけ
- ArticulationBody の値には触れない(この依頼では使わない)
- 前の依頼で残った画面なしの Unity があれば、最初に終わらせる
- git は個別ファイルを指定して add する(`git add .`・`git clean` は使わない)。作業の区切りでコミットする
- 外部のアセットのダウンロードはしない。Unity の基本の形(Cube・Cylinder・Plane など)とマテリアル・ライトだけで作る

## 舞台の中身(ロボットの作業部屋)
- 夜の薄暗い作業部屋。奥の壁に棚が並び、部品箱が置いてある。奥はぼんやりした暖色の明かりで、手前は暗め
- 奥の壁の真ん中に、大きな壁掛けモニター(黒い画面・細いふち。ふちの色は #C4471F のオレンジ)。画面は少し光る濃紺(#0E1420 前後)
- 床の真ん中に、ロボットの作業エリアを示す床のマーキング(黄色と黒の破線の円。直径 約3m)。2人がこの円の上に立つ
- 右奥に作業台。台の上にロボットアームらしい形(四角と円柱を組んだ簡単なもの)と卓上ライト(暖色の点光源)
- 色は落ち着いた暗い茶・灰。派手な色はモニターのふちのオレンジと床の黄色だけ

## カメラと画面の割り振り(縦長 1080×1920・固定)
- 少し上から見下ろす(俯角 10〜15度)
- 画面の y 0〜440 は暗くしておく(見出しの文字を載せる)
- モニターの画面(光る部分): x 80〜1000・y 460〜1080 くらいに収める
- 床の円: 中心が y 1560 前後、横幅 800〜880px の楕円に見えるように
- 円の上に立つ人の大きさ: 身長 1.7m が 画面で 520〜580px くらい

## 撮るもの(出力先: /Volumes/KIOXIA/r2r2r-data/videos/_ショート専用/研究のスキル一覧/_取り込み/舞台/)
1. `stage_bg.png` — 1080×1920、キャラなし、モニターは光った状態(中身は空)
2. `stage_bg_off.png` — 同じ構図で、モニターの電源が切れた状態(真っ黒)
3. `stage_check.png` — 同じ構図に、円の上に身長 1.7m と 1.15m の灰色のカプセルを左右に立てた確認用
4. `stage_meta.json` — 次の値(すべて画面の px・左上が原点)
   - `screen_corners`: モニターの光る部分の4隅 [左上, 右上, 右下, 左下]
   - `ring_center`, `ring_rx`, `ring_ry`: 床の円の中心と、楕円の横・縦の半径
   - `foot_left`, `foot_right`: 円の上で左右に立つ位置(足もと)の x, y
   - `px_per_m_at_ring`: 円の位置で 1m が何 px か
   - カメラの位置・向き・画角
5. `stage_loop.mp4` — 同じ構図で6秒・30fps。卓上ライトがわずかにゆらぐ・モニターの光がわずかに明滅する程度の、ほぼ止まった映像(つなげてループできるように最初と最後をそろえる)

書き出しは画面なし(-batchmode)で、カメラから RenderTexture に撮って PNG にする形でよい。

## 報告に書くこと
- 作ったファイルの一覧と、`stage_check.png` を見て、カプセルの大きさと位置が上の目安に入ったか
- 目安から外れた所と、その理由
- 最後の1行に「判定:合格/止めた(決めてほしいことあり)/失敗」

Claude Code の報告(全文)

01_sec02.md3,077字・71行・markdown
# 結果:20261106_99_ショート用の舞台を建てて撮る

- 状態:完了
- 始めた時刻:2026-11-06 22:46
- 終わった時刻:2026-11-06 22:59(13分)
- 作業フォルダ:/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき:作業フォルダで `claude --resume cac61545-2860-4b9e-9f79-22254d4d1089`
- 止められた操作:1件(いちばん下に一覧)
別のタブで開く保存

「止められた操作」の1件は、試しの撮影の前に一時フォルダを消す rm -rf が、依頼箱の決まりで止められたものです。Claude Code はほかの方法で続け、撮影は終わっています(報告の最後の行は、決めてほしいことがあるので「止めた」)。

舞台を組み立てて撮る VideoStageBuilder.cs(全文)

ServiceSim の Assets/VideoStage/Editor/VideoStageBuilder.cs です。記事に載せるために、依頼箱 #103 で KIOXIA に写してもらいました(ServiceSim の中は変えていません)。

02_VideoStageBuilder.cs.txt32,036字・626行・csharp
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
別のタブで開く保存

動画の側が使う位置の値 stage_meta.json

{
  "image_size": [1080, 1920],
  "origin": "top-left, px",
  "screen_corners": [[90.0, 470.0], [990.0, 470.0], [990.0, 1070.0], [90.0, 1070.0]],
  "screen_corners_order": "top-left, top-right, bottom-right, bottom-left",
  "ring_center": [540.0, 1560.0],
  "ring_rx": 433.4,
  "ring_ry": 222.2,
  "ring_center_floor_point": [540.0, 1510.2],
  "ring_note": "ring_center/rx/ry = bounding box of the projected ring (line center, radius 1.5 m, line width 0.10 m). ring_center_floor_point = projection of the ring's center on the floor",
  "foot_left": [291.7, 1675.6],
  "foot_right": [788.3, 1675.6],
  "foot_world_m": {"left": [-0.75, 0, -1], "right": [0.75, 0, -1]},
  "px_per_m_at_ring": 281.6,
  "px_per_m_at_feet": 331.0,
  "person_height_px": {"left_1.70m": 539.2, "right_1.15m": 357.0, "right_1.70m": 539.2},
  "camera": {
    "position_m": [0, 3.273, -6],
    "rotation_euler_deg": [12, 0, 0],
    "pitch_down_deg": 12,
    "vertical_fov_deg": 55,
    "horizontal_fov_deg": 32.642,
    "near_far_m": [0.1, 40],
    "axes": "Unity world, y up, z toward the back wall, meters. ring center at (0,0,0)"
  },
  "loop": {"fps": 30, "seconds": 6, "frames": 180}
}
Unity で撮った舞台。左はキャラのいない背景、右は身長1.7mと1.15mの灰色のカプセルを立てた確かめの画像

2人の立つ位置は、撮り直さずに動画の側で決めた

報告の「決めてほしいこと」の1つ目は、2人の立つ位置でした。円の中心の深さでは 1m が 282px なので、1.7m は約 480px にしかならず、目安(520〜580px)に届きません。Claude Code は足もとを円の中心より 1.0m 手前に置いていました。

これは Unity を撮り直さず、動画の側で決めました。足もとの y を 1525 に上げて円の奥寄りに立たせ、大きさを 0.88 倍にしています(奥に立つほど小さく見えるのと合うため)。2人の間は、版2でエイイチの「ハコブくんとオレの距離感もっと近くて良さそう」を受けて、580px から 300px に詰めました。

作業ログ ― 舞台型の書き出し butai_kit.py を作る

AIあるある の書き出し aiaru_kit.py から変えた所

書き出しは、ショート「AIあるある」の aiaru_kit.py を写して作りました。2人とも全身・左にハコブくん・右にエイイチ・字幕はハコブくんが水色でエイイチが白、という所は同じです。変えたのは次の所です。

変えた所aiaru_kit.pybutai_kit.py
背景茶色のグラデーション
Unity の舞台(stage_bg.png)。モニターが消えた絵からついた絵に切り替える
画面の中身画面いっぱいに置く確認の窓
モニターの光る部分(900×600 の枠)の中だけに置く。stage_meta.json の4隅から位置を決める
2人の大きさと位置決まった px
舞台の 1m の px から決める(ハコブくん 1.15m・エイイチ 1.7m)。エイイチのドット絵は整数倍で拡大
字幕
白い字に黒いふち(y 1150)
黒い箱に1行ずつ(y 1590・足もとの下)
上の見出しの下なし
見出しが読めるよう、上を暗くする帯
モニターの外の演出なし
spec.py の OVER で、床の円・紙吹雪・ほかの演出を重ねる

butai_kit.py(全文)

03_butai_kit.py.txt25,521字・467行・python
# -*- coding: utf-8 -*-
"""ショート「舞台型」の書き出し(2026-11-06「研究のスキル一覧」で作った。元は AIあるある の aiaru_kit.py)。
舞台(Unity で撮った背景 stage_bg.png と位置の値 stage_meta.json)の上に、奥のモニターの中身・2人(全身・身長の比)・字幕の黒い箱を重ねる。
各回の作業フォルダに narration.py と spec.py(NAME・HEAD・scene(T,S)・FACE・POSE・LEAN・SE・ENDING・LEAD・STAGE=舞台のフォルダ)を置き、そこで
  P2M_BASE=<_制作ベース> python3 ../舞台型_共通/butai_kit.py [--still 秒,…]

以下は元の aiaru_kit.py の説明:
ショート「AIあるある」の共通の書き出し(1080×1920・2026-11-02「確認いらん」で作り、2本目から共通にした)。
別のタブで開く保存

作業ログ ― モニターの中を、枠線と記号から面に組み直す(版1 → 版2)

エイイチ「グラフィカルな部分はもう少しクオリティを上げたいかな。雑に見える」

版1のモニターは、細い枠線の札、記号のアイコン(▶■✉◆)、緑と赤の帯、凡例、と要素が多く、1画面で何を見せたいのかがぼやけていました。デザインを直すときの決まり(1画面で伝えることは1つ・細い線より面・色は意味を1つ決めてそこにだけ使う)に照らして、全部の画面を組み直しています。

  • ねらい:スマホで見て、モニターの中で何を言っているかが1秒で分かるようにする
  • 変わったこと:枠線をやめてベタの面で組んだ。記号のアイコンをやめて番号(01〜07)にした。どの画面も左上に「番号 / 07・名前」、その下に言いたいことを1文、図は1つ。オレンジは止まり・いまの手順・選んだ1つ・✕ だけにし、緑と赤をやめた
  • 見込める効果:見て分かるかは、X の動画の再生と、見られた長さで確かめる(まだ出していないので見込み)
同じ5.2秒目のコマ。左の版1は細い枠線と記号のアイコン、右の版2はベタの面で、左に大きな7、右に7行の一覧

字幕は1行ずつにして、足もとの下に置いた

2人を寄せると、2行の字幕の箱がハコブくんの体を半分隠しました。字幕を1行ずつ(48px・1行15字まで)にし、箱を足もとの下(y 1590)に置いています。YouTube のショートでは y 1640 より下にタイトルが重なるので、箱の下の端が少しかかりますが、字は1640より上に収まっています。

作業ログ ― 床の円をゆっくり回し、紙吹雪を細かくする(版3)

エイイチ「紙吹雪をもっと細かく華やかに。床のサークルをゆっくり回して」

床の円は Unity の背景に焼き込まれているので、そのままでは回せません。Unity で撮り直す代わりに、背景から円を消し、同じカメラの値で円を描き直して回すことにしました。

  1. stage_meta.json のカメラの値(位置 (0, 3.273, -6) m・俯角12度・縦の画角55度)で、床の上の半径1.37〜1.63m の帯を画面に写し、その帯を OpenCV の inpaint(まわりの色で穴を埋める処理)で埋める
  2. 破線の明るさを、元の画像から10度ごとに拾ってならす。手前は明るく、奥は暗い、という Unity の照明を残すため
  3. 書き出しのたびに、ページの canvas に36本の破線を、48秒で1周する速さで描く

写す計算が合っているかは、円の中心が y 1510、左の足もとが (291.7, 1675.6) に写ることで確かめました(stage_meta.json の値と同じ)。

左から、Unity で撮った円、円を消した床、描き直して回している版3のコマ

make_noring.py(全文)

会話の中で2回に分けて動かしたもの(inpaint と明るさの表)を、記事に載せるために1つのファイルにまとめました。まとめたファイルを同じ舞台の画像で動かし直し、できた画像(画素の差の最大が0)と明るさの表が、動画に使ったものと同じになることを確かめています。

# -*- coding: utf-8 -*-
"""舞台(Unity で撮った stage_bg.png)から床の円を消し、回して描き直すための値を作る(2026-11-06「研究のスキル一覧」版3)。
エイイチ「床のサークルをゆっくり回して」。Unity を撮り直さず、円を消した床の上に butai_parts.stage_fx が円を描き直す。

1. stage_meta.json のカメラの値(位置・俯角・縦の画角)で、床の上の半径 1.37〜1.63m の帯を画面に写し、その帯を OpenCV の inpaint で埋める
   → stage_bg_noring.png / stage_bg_off_noring.png
2. 円の破線の明るさを、元の画像から 10度ごとに拾ってならす(手前は明るく、奥は暗い。Unity の照明のまま)
   → ring_lut.json(lut: 36個の RGB・fy・カメラの位置・俯角)

使い方: python3 make_noring.py <舞台のフォルダ>(stage_bg.png・stage_bg_off.png・stage_meta.json があるところ)
会話の中で2回に分けて動かしたもの(inpaint と明るさの表)を、1つのファイルにまとめた。
"""
import json, math, os, sys
import numpy as np
import cv2
from PIL import Image

D = sys.argv[1] if len(sys.argv) > 1 else "stage"
M = json.load(open(os.path.join(D, "stage_meta.json")))
c = M["camera"]
C = np.array(c["position_m"])
p = math.radians(c["pitch_down_deg"])
f = np.array([0, -math.sin(p), math.cos(p)])      # カメラの前
u = np.array([0, math.cos(p), math.sin(p)])       # カメラの上
fy = 960 / math.tan(math.radians(c["vertical_fov_deg"] / 2))


def proj(x, z):
    """床(y=0)の点 (x, z) を画面の px に写す。円の中心が原点"""
    d = np.array([x, 0, z]) - C
    return 540 + fy * d[0] / (d @ f), 960 - fy * (d @ u) / (d @ f)


# 確かめ: 円の中心は y 1510、左の足もとは (291.7, 1675.6) に写る(stage_meta.json の値と同じ)
print(proj(0, 0), proj(-0.75, -1))

# 1. 円を消す
th = np.linspace(0, 2 * np.pi, 720)
outer = np.array([proj(1.63 * np.cos(a), 1.63 * np.sin(a)) for a in th], np.int32)
inner = np.array([proj(1.37 * np.cos(a), 1.37 * np.sin(a)) for a in th], np.int32)
mask = np.zeros((1920, 1080), np.uint8)
cv2.fillPoly(mask, [outer], 255)
cv2.fillPoly(mask, [inner], 0)
for nm in ("stage_bg", "stage_bg_off"):
    im = cv2.imread(os.path.join(D, f"{nm}.png"))
    out = cv2.inpaint(im, mask, 9, cv2.INPAINT_TELEA)
    cv2.imwrite(os.path.join(D, f"{nm}_noring.png"), out)

# 2. 破線の明るさ(10度ごとに、いちばん明るい点を拾い、前後とならす)
im = np.asarray(Image.open(os.path.join(D, "stage_bg.png")).convert("RGB")).astype(float)
lut = []
for k in range(36):
    best = np.zeros(3)
    for a in np.linspace(math.radians(k * 10), math.radians(k * 10 + 10), 30):
        for rr in (1.47, 1.5, 1.53):
            x, y = proj(rr * math.cos(a), rr * math.sin(a))
            px = im[int(y), int(x)]
            if px.sum() > best.sum():
                best = px
    lut.append(best)
lut = np.array(lut)
sm = (np.roll(lut, 1, 0) + 2 * lut + np.roll(lut, -1, 0)) / 4
print(sm.astype(int)[::3].tolist())
json.dump(dict(lut=sm.round().astype(int).tolist(), fy=fy, C=list(C), pitch=c["pitch_down_deg"]),
          open(os.path.join(D, "ring_lut.json"), "w"))
(np.float64(540.0), np.float64(1510.1998084280149)) (np.float64(291.7412860969673), np.float64(1675.6201892029471))
[[62, 41, 5], [70, 43, 5], [129, 71, 9], [154, 82, 14], [128, 68, 7], [121, 65, 8], [107, 59, 9], [71, 44, 6], [65, 42, 6], [65, 43, 6], [90, 54, 9], [115, 66, 10]]

紙吹雪は、CSS の四角60片から、canvas に描く230片に変えました。円の左右の2か所から打ち上げ、1片を小さくし(5〜11px)、四角・丸・細長いリボン・光る星の4種類が、裏返りながら揺れて落ちます。エイイチの返事は「OK。」でした。

作業ログ ― 部品 butai_parts.py と、紙吹雪のほかの演出7つ

2本目からは spec.py に場面と動きだけを書く

エイイチの「Claude や Claude Code ネタで作って欲しい」で4本、続けて「さらに5本」で5本を作りました。1本目の spec.py にあった、モニターの見た目(CSS)・場面の出し入れ(win)・小さな見出し(kick)・床の円と紙吹雪(stage_fx)を butai_parts.py に移し、各回の spec.py は from butai_parts import * で始めて、場面と動きと効果音だけを書く形にしています。

エイイチ「毎回紙吹雪なので違うパターンも考えてください」

4本を出したあと、山場がどれも紙吹雪だと指摘を受けました。stage_fx に、紙吹雪のほかの演出を7つ足し、話の中身に合わせて選ぶようにしています。

演出動き合う場面使った回
紙吹雪
円の左右から打ち上げて、ひらひら落ちる
お祝い
研究のスキル一覧・このショートの作り方
rays
床の円の真ん中から光の筋が回る
決まった所・浮いた時間
記事の公開は誰が・全部ログに残す
speed
マンガの集中線がモニターへ集まる
叩きつけ・ツッコミ
Claudeに覚えてもらう・Claude Codeへの頼み方
shock床の円から波紋が3つ広がる知らせ・音・決定
Claudeに覚えてもらう・Claude Codeへの頼み方・寝ている間に回す・並行で作る
spot
まわりを暗くして、1人にスポットライト
決めるのは○○別のAIに疑わせる
stars
上の方に星がまたたき、少し暗くなる
夜寝ている間に回す
shine
モニターの上を光の帯が斜めに走る
作り直したClaudeのデザイン
rise床から小さな四角が立ちのぼるデータ・記録全部ログに残す

暗くする演出(spot・stars)と光の筋は、モニターの中にはかけません。モニターに出している言葉が読めなくなるためです。

紙吹雪と7つの演出を、それぞれ使った回のコマで並べた

butai_parts.py(全文)

04_butai_parts.py.txt13,299字・166行・python
# -*- coding: utf-8 -*-
"""舞台型ショートの部品(2026-11-06「研究のスキル一覧」で決めた見た目を、2本目から共通にした)。
モニターの中(900×600)は面で組む: 左上に小さな見出し、その下に言いたいことを1文、図は1つ。
オレンジは「いま話している1つ」だけ。細い枠線・記号のアイコンは使わない。
"""
import json, os
from kabe_kit import shake_js, counter_js
別のタブで開く保存

作業ログ ― 10本の台本と画面(narration.py と spec.py)

エイイチのセリフは、どれもエイイチがこれまでに話した言葉(チャットで話したこと・MASTER・動画の決まり)から取り、どこから取ったかを narration.py の1行目に書いています。ハコブくんのセリフは、決まりや記録に書いてある事実だけにしました。

回長さエイイチのセリフのもと
研究のスキル一覧(版5)29.3秒
「今まで煩わしかったターミナルでの作業から解放されたこと」(この会話)
Claude Codeへの頼み方(版4)
26.9秒
Claude Code への指示を自分で貼って渡す形はNG(2026-11-03)
寝ている間に回す(版3)24.9秒
寝ている間も依頼を続けて回せるように/途中経過は毎時間は多い(2026-10-27・11-05)
Claudeに覚えてもらう(版4)
24.0秒
「いい加減覚えてください」(2026-11-01・Log 番号の件)
記事の公開は誰が(版4)27.9秒
記事1本の公開に30〜45分/Studio の更新はもう面倒でやりたくない
別のAIに疑わせる(版4)25.7秒
codex に任せるとただのニュースのようになる(2026-10-28)/最終判断はエイイチ(MASTER)
並行で作る(版3)23.4秒
何本も並行して作るので一覧で見たい(2026-10-15)/会議中に喋られると困る
Claudeのデザイン(版3)
24.8秒
弱いのはデザイン力ではなく進め方と統一する力(2026-10-24)
全部ログに残す(版2)21.9秒
最初はブログ記事のつもり/全部残せば AI に読ませて使える/AI にしっかり読まれている
このショートの作り方(版3)23.0秒
いちばん時間がかかるのは音声確認(2026-11-02)

声は、ハコブくんがいつもの声、エイイチは槙原さんの声(ElevenLabs の自作の声を流用)で、Mac から tts_eleven.py で作りました。文ごとの長さ(前後の無音を切ったあと)は次のとおりです。

研究のスキル一覧	2.56 / 2.48 / 3.55 / 4.33 / 2.99 / 2.14 / 5.60 / 3.27
Claude Codeへの頼み方	2.93 / 2.72 / 4.08 / 4.95 / 2.60 / 3.76 / 3.27
寝ている間に回す	2.34 / 2.33 / 3.59 / 3.86 / 3.87 / 3.13 / 3.27
Claudeに覚えてもらう	2.72 / 2.91 / 3.37 / 3.40 / 1.85 / 3.76 / 3.27
記事の公開は誰が	3.12 / 5.28 / 3.98 / 3.91 / 3.30 / 2.42 / 3.27
別のAIに疑わせる	3.00 / 2.88 / 3.51 / 3.66 / 4.84 / 2.01 / 3.27
並行で作る	3.64 / 3.01 / 2.56 / 2.94 / 2.09 / 3.23 / 3.27
Claudeのデザイン	2.38 / 2.27 / 4.63 / 3.42 / 3.40 / 2.83 / 3.27
全部ログに残す	2.83 / 2.59 / 3.05 / 3.47 / 3.45 / 4.50
このショートの作り方	2.11 / 3.32 / 3.52 / 3.56 / 2.83 / 1.79 / 3.27

01 研究のスキル一覧(29.3秒)の narration.py

# -*- coding: utf-8 -*-
# 研究のスキル一覧(ショート専用・舞台型の試作1本目・2026-11-06)。#6 はエイイチの言葉「今まで煩わしかったターミナルでの作業から解放されたこと」から
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "ロボットの研究、ひとりで回せる?", 0.15),
 ("seven", "joy", "回せます。仕組みは、7つ!", 0.15),
 ("ops", "base", "1つは、ロボットの動画から、止まった所を読む。", 0.1),
 ("gpu", "base", "1つは、GPUを借りて学習。終わったら、消す。", 0.1),
 ("doubt", "wink", "1つは、別のAIに、疑わせる。", 0.2),
 ("fav_ei", "base", "で、いちばん助かってるのは…", 0.1),
 ("inbox_ei", "base", "依頼箱。今まで煩わしかった、ターミナルの作業から、解放された!", 0.3),
 ("end", "smile", "研究の記録は、毎日サイトで公開中です!", 0.5),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("7つ", "ななつ"), ("1つ", "ひとつ"), ("依頼箱", "いらいばこ"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

01 研究のスキル一覧 の spec.py

05_spec.py.txt14,621字・206行・python
# -*- coding: utf-8 -*-
"""研究のスキル一覧(ショート専用・舞台型の試作1本目・2026-11-06)
奥のモニターに1つずつ出す。中身はエイイチが実際に使っている仕組みだけ(誇張しない)。
#6 のセリフはエイイチの言葉「今まで煩わしかったターミナルでの作業から解放されたこと」から。
"""
import json, os
from kabe_kit import shake_js
別のタブで開く保存

01 研究のスキル一覧 の書き出しのログ

研究のスキル一覧: 880コマ(撮影 880)
out/研究のスキル一覧_版5.mp4  29.3秒

02 Claude Codeへの頼み方(26.9秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# Claude Codeへの頼み方(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(Claude Code への指示を自分で貼って渡す形はNG(2026-11-03))
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "Claude Codeへの指示、まだ手で貼ってる?", 0.15),
 ("write", "joy", "僕が依頼を書いて、依頼箱に置きます!", 0.1),
 ("pass", "base", "Macの見張り係が、1件ずつClaude Codeに渡します。", 0.1),
 ("report", "smile", "終わったら、合格か、止めたか、失敗か。判定つきで報告。", 0.15),
 ("ng_ei", "base", "自分で貼って渡すのは、もうナシ。", 0.2),
 ("lock", "wink", "ただし、実機を動かす依頼は、確認待ちで止めます!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("Unity", "ユニティ"), ("Mac", "マック"),
               ("pixelstomotors.com", "ピクセルズトゥモーターズ ドットコム"), ("1件", "いっけん"), ("1つ", "ひとつ"), ("1画面", "ひとがめん"), ("2時間", "にじかん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

02 Claude Codeへの頼み方 の spec.py

06_spec.py.txt4,555字・71行・python
# -*- coding: utf-8 -*-
"""Claude Codeへの頼み方(ショート専用・舞台型・2026-11-06)
エイイチの言葉: Claude Code への指示を自分で貼って渡す形はNG(2026-11-03)。依頼箱の決まりは 依頼箱/README.md"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "Claude Codeへの頼み方", 4
HEAD = "Claude Code<br>どう頼む?"
別のタブで開く保存

02 Claude Codeへの頼み方 の書き出しのログ

Claude Codeへの頼み方: 807コマ(撮影 807)
out/Claude Codeへの頼み方_版4.mp4  26.9秒

03 寝ている間に回す(24.9秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# 寝ている間に回す(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(寝ている間も依頼を続けて回せるようにしてほしい/長い依頼の途中経過は知りたいが毎時間は多い)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "寝てる間も、研究を進めたい。", 0.15),
 ("night", "joy", "夜は、Claude Codeが回します!", 0.1),
 ("gpu", "base", "クラウドのGPUで学習して、終わったら片付けまで。", 0.1),
 ("unity", "base", "Unityの店も、条件を変えて、何十回も回します。", 0.15),
 ("info_ei", "base", "途中経過は知りたい。でも、毎時間は多い。", 0.15),
 ("two", "smile", "じゃあ、2時間ごとか、区切りでお知らせします!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("Unity", "ユニティ"), ("Mac", "マック"),
               ("pixelstomotors.com", "ピクセルズトゥモーターズ ドットコム"), ("1件", "いっけん"), ("1つ", "ひとつ"), ("1画面", "ひとがめん"), ("2時間", "にじかん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

03 寝ている間に回す の spec.py

07_spec.py.txt4,315字・75行・python
# -*- coding: utf-8 -*-
"""寝ている間に回す(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 寝ている間も依頼を続けて回せるようにしてほしい(2026-10-27)/長い依頼の途中経過は知りたいが、毎時間は多い。2時間ごとかタスクの区切りでよい(2026-11-05)"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "寝ている間に回す", 3
HEAD = "寝てる間に<br>研究は進む?"
別のタブで開く保存

03 寝ている間に回す の書き出しのログ

寝ている間に回す: 748コマ(撮影 748)
out/寝ている間に回す_版3.mp4  24.9秒

04 Claudeに覚えてもらう(24.0秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# Claudeに覚えてもらう(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(同じチャットは同じLog番号にしてください(いい加減覚えてください))
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "同じこと、何回言えば覚えるの?", 0.15),
 ("forget", "trouble", "会話が変わると、僕は忘れてしまいます…", 0.15),
 ("book", "base", "だから、決めたことは、ルールの本に書き足します。", 0.1),
 ("count", "joy", "動画のルールは、もう105回、書き足しました!", 0.2),
 ("angry_ei", "base", "いい加減、覚えてください。", 0.25),
 ("read", "smile", "はい!次の会話は、まず本を読むところから!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("GitHub", "ギットハブ"), ("Unity", "ユニティ"), ("SNS", "エスエヌエス"), ("ElevenLabs", "イレブンラボ"), ("codex", "コーデックス"), ("1つ", "ひとつ"), ("105回", "ひゃくごかい"), ("13分", "じゅうさんぷん"), ("30分", "さんじゅっぷん"), ("45分", "よんじゅうごふん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

04 Claudeに覚えてもらう の spec.py

08_spec.py.txt4,116字・74行・python
# -*- coding: utf-8 -*-
"""Claudeに覚えてもらう(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 「同じチャットは同じlog番号にしてください(いい加減覚えてください)」"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "Claudeに覚えてもらう", 4
HEAD = "AIに<br>覚えてもらうには?"
別のタブで開く保存

04 Claudeに覚えてもらう の書き出しのログ

Claudeに覚えてもらう: 721コマ(撮影 721)
out/Claudeに覚えてもらう_版4.mp4  24.0秒

05 記事の公開は誰が(27.9秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# 記事の公開は誰が(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(自動化の前は記事1本の仕上げと公開に30〜45分/Studio の更新はもう面倒でやりたくない)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "記事1本の公開、どれくらいかかってた?", 0.15),
 ("time", "trouble", "サムネイル作りに、貼り付け。1本、30分から45分!", 0.15),
 ("push", "joy", "いまは、Claudeが仕上げて、GitHubからそのまま公開。", 0.1),
 ("sns", "smile", "SNSの投稿も、時間を決めて、自動で予約します。", 0.15),
 ("studio_ei", "base", "サイトの更新は、もう面倒でやりたくなかった。", 0.2),
 ("lab", "joy", "浮いた時間は、ロボットの研究へ!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("GitHub", "ギットハブ"), ("Unity", "ユニティ"), ("SNS", "エスエヌエス"), ("ElevenLabs", "イレブンラボ"), ("codex", "コーデックス"), ("1つ", "ひとつ"), ("105回", "ひゃくごかい"), ("13分", "じゅうさんぷん"), ("30分", "さんじゅっぷん"), ("45分", "よんじゅうごふん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

05 記事の公開は誰が の spec.py

09_spec.py.txt4,789字・73行・python
# -*- coding: utf-8 -*-
"""記事の公開は誰が(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 自動化の前は記事1本の仕上げと公開に30〜45分/Studio の更新はもう面倒でやりたくない"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "記事の公開は誰が", 4
HEAD = "記事の公開<br>誰がやる?"
別のタブで開く保存

05 記事の公開は誰が の書き出しのログ

記事の公開は誰が: 838コマ(撮影 838)
out/記事の公開は誰が_版4.mp4  27.9秒

06 別のAIに疑わせる(25.7秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# 別のAIに疑わせる(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(codex に任せると、ただのニュースのようになってしまう/最終判断はエイイチ)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "AIが書いた台本、間違ってたらどうする?", 0.15),
 ("doubt", "joy", "別のAIに、1文ずつ疑わせます!", 0.1),
 ("rows", "base", "数字の出どころ、言い過ぎ、引用の原文。", 0.15),
 ("news_ei", "base", "でも、codexに任せると、ただのニュースみたいになる。", 0.15),
 ("split", "wink", "だから、codexは事実確認だけ。話の筋は、変えません!", 0.15),
 ("final_ei", "base", "最後に決めるのは、オレ。", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("GitHub", "ギットハブ"), ("Unity", "ユニティ"), ("SNS", "エスエヌエス"), ("ElevenLabs", "イレブンラボ"), ("codex", "コーデックス"), ("1つ", "ひとつ"), ("105回", "ひゃくごかい"), ("13分", "じゅうさんぷん"), ("30分", "さんじゅっぷん"), ("45分", "よんじゅうごふん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

06 別のAIに疑わせる の spec.py

10_spec.py.txt4,129字・65行・python
# -*- coding: utf-8 -*-
"""別のAIに疑わせる(ショート専用・舞台型・2026-11-06)
エイイチの言葉: codex に任せると、ただのニュースのようになってしまう(2026-10-28)/最終判断はエイイチ(MASTER)"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "別のAIに疑わせる", 4
HEAD = "AIの間違い<br>誰が見つける?"
別のタブで開く保存

06 別のAIに疑わせる の書き出しのログ

別のAIに疑わせる: 772コマ(撮影 772)
out/別のAIに疑わせる_版4.mp4  25.7秒

07 並行で作る(23.4秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# 並行で作る(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(何本も並行して作ることが多くなったので一覧で見て進めたい/ハコブくんの声のお知らせは会議中に喋られると困る・うるさくない程度に)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "何本も同時に作ってると、どれがどこまでか分からない。", 0.15),
 ("page", "joy", "進み具合のページに、会話ごとに書き込みます!", 0.1),
 ("turn", "base", "いま誰の番か、ひと目で分かります。", 0.15),
 ("voice", "smile", "エイイチさんの番になったら、僕の声でお知らせ!", 0.15),
 ("mtg_ei", "base", "会議中に喋られると困る。", 0.2),
 ("quiet", "trouble", "はい。うるさくならないように、控えめにします…", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("Unity", "ユニティ"), ("Mac", "マック"),
               ("pixelstomotors.com", "ピクセルズトゥモーターズ ドットコム"), ("1件", "いっけん"), ("1つ", "ひとつ"), ("1画面", "ひとがめん"), ("2時間", "にじかん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

07 並行で作る の spec.py

11_spec.py.txt4,763字・79行・python
# -*- coding: utf-8 -*-
"""並行で作る(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 動画を何本も並行して作ることが多くなったので、一覧で見て簡単に進めたい(2026-10-15)/ハコブくんの声のお知らせは、うるさくならない程度にし、止められるように(仕事のMTG中に喋られると困る)"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "並行で作る", 3
HEAD = "何本も同時に<br>どこまで進んだ?"
別のタブで開く保存

07 並行で作る の書き出しのログ

並行で作る: 702コマ(撮影 702)
out/並行で作る_版3.mp4  23.4秒

08 Claudeのデザイン(24.8秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# Claudeのデザイン(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(Claude のデザインの質が低いのはデザイン力ではなく進め方・修正・組み立て・統一する力が弱いから/要素を詰め込みすぎる)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "Claudeにデザインを頼むと、どうなる?", 0.15),
 ("stuff", "trouble", "つい、要素を詰め込みすぎます…", 0.15),
 ("why_ei", "base", "デザイン力じゃない。進め方と、統一する力が弱い。", 0.2),
 ("one", "base", "だから、1画面で伝えることは、1つに決めます。", 0.1),
 ("face", "smile", "線より面。色は、意味を1つだけ。", 0.15),
 ("this", "joy", "このモニターも、そのルールで作り直しました!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("Unity", "ユニティ"), ("Mac", "マック"),
               ("pixelstomotors.com", "ピクセルズトゥモーターズ ドットコム"), ("1件", "いっけん"), ("1つ", "ひとつ"), ("1画面", "ひとがめん"), ("2時間", "にじかん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

08 Claudeのデザイン の spec.py

12_spec.py.txt5,494字・85行・python
# -*- coding: utf-8 -*-
"""Claudeのデザイン(ショート専用・舞台型・2026-11-06)
エイイチの言葉: Claude のデザインの質が低いのは、デザイン力がないからではなく、進め方・修正・組み立て・統一する力が弱いから/要素を詰め込みすぎる(2026-10-24)
このモニターの見た目も、2026-11-06 にエイイチ「雑に見える」で、面で組む・1画面に1つ・色の意味は1つ、に作り直した"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "Claudeのデザイン", 3
別のタブで開く保存

08 Claudeのデザイン の書き出しのログ

Claudeのデザイン: 745コマ(撮影 745)
out/Claudeのデザイン_版3.mp4  24.8秒

09 全部ログに残す(21.9秒)の narration.py

# -*- coding: utf-8 -*-
# 全部ログに残す(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(最初はブログ記事のつもりで書いていた/全記録を残すことでAIに読み込ませてそのまま使える/AIにしっかり読まれていることは確認できた)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("log_ei", "base", "毎日の作業、全部ログに残してる。", 0.15),
 ("blog", "smile", "最初は、ブログ記事のつもりでしたよね。", 0.1),
 ("full", "base", "途中から、全部を書き起こすログに変えました。", 0.15),
 ("ai_ei", "base", "全部残せば、AIに読ませて、そのまま使える。", 0.2),
 ("read", "joy", "実際に、サイトはAIにしっかり読まれています!", 0.15),
 ("site", "smile", "記録は、pixelstomotors.comで、毎日公開中です!", 0.5),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("Unity", "ユニティ"), ("Mac", "マック"),
               ("pixelstomotors.com", "ピクセルズトゥモーターズ ドットコム"), ("1件", "いっけん"), ("1つ", "ひとつ"), ("1画面", "ひとがめん"), ("2時間", "にじかん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

09 全部ログに残す の spec.py

13_spec.py.txt4,317字・65行・python
# -*- coding: utf-8 -*-
"""全部ログに残す(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 記事は最初ブログ記事のつもりで書いていた。途中から全量ログに(overview)/全記録を残すことで、AIに読み込ませてそのまま使える(2026-10-20)/AIにしっかり読まれていることは確認できた(2026-11-05)"""
from butai_parts import *

NAME, VER = "全部ログに残す", 2
HEAD = "毎日の作業<br>なぜ全部残す?"
T_ON = (0, 1.2)
別のタブで開く保存

09 全部ログに残す の書き出しのログ

全部ログに残す: 658コマ(撮影 658)
out/全部ログに残す_版2.mp4  21.9秒

10 このショートの作り方(23.0秒)の narration.py

# -*- coding: utf-8 -*-
# 2026-11-07: 最後に締め(サイトへの入口)の文を足した。声は「研究のスキル一覧」の 007 をそのまま使う(エイイチ「うちのサイトへの動線部分がないけど?」)
# このショートの作り方(ショート専用・舞台型・2026-11-06)。エイイチのセリフは、エイイチがこれまでに話した言葉から(動画づくりで一番時間を取られるのは音声確認)
FACES = ("base", "smile", "surprise", "doubt", "think", "trouble", "joy", "wink")
SEGS = [
 ("ask_ei", "base", "このショート、どうやって作ってる?", 0.15),
 ("script", "joy", "台本と画面は、僕、Claudeが作りました!", 0.1),
 ("room", "smile", "この部屋は、Claude Codeが、Unityで建てました。", 0.1),
 ("voice", "base", "声はElevenLabs。僕の声も、AIです。", 0.15),
 ("check_ei", "base", "いちばん時間がかかるのは、音声の確認。", 0.2),
 ("decide", "joy", "見て決めるのは、エイイチさん!", 0.5),
 ("outro", "smile", "研究の記録は、毎日サイトで公開中です!", 0.6),
]
ELEVEN_READ = [("GPU", "ジーピーユー"), ("AI", "エーアイ"), ("Claude Code", "クロード コード"), ("Claude", "クロード"), ("GitHub", "ギットハブ"), ("Unity", "ユニティ"), ("SNS", "エスエヌエス"), ("ElevenLabs", "イレブンラボ"), ("codex", "コーデックス"), ("1つ", "ひとつ"), ("105回", "ひゃくごかい"), ("13分", "じゅうさんぷん"), ("30分", "さんじゅっぷん"), ("45分", "よんじゅうごふん"), ("…", "。")]
EI_LINES = [i for i, seg in enumerate(SEGS) if seg[0].endswith("_ei")]
READ = [("「", ""), ("」", "")]


def parse(seg):
    scene, face, text = seg[0], seg[1], seg[2]
    pause = seg[3] if len(seg) > 3 else 0.35
    return scene, face, text, pause

10 このショートの作り方 の spec.py

14_spec.py.txt3,995字・76行・python
# -*- coding: utf-8 -*-
"""このショートの作り方(ショート専用・舞台型・2026-11-06)
エイイチの言葉: 動画づくりで一番時間を取られるのは音声確認(2026-11-02)。部屋は依頼箱 #99 で Claude Code が Unity で建てた(22:46 開始 → 22:59 完了=13分)"""
from butai_parts import *
OUTRO_K = 6   # 締めの文の番号(narration.py の最後に足した文)

NAME, VER = "このショートの作り方", 3
HEAD = "この動画<br>誰が作った?"
別のタブで開く保存

10 このショートの作り方 の書き出しのログ

このショートの作り方: 691コマ(撮影 691)
out/このショートの作り方_版3.mp4  23.0秒

作業ログ ― X に動画付きで予約した10本

AIあるある と同じく、YouTube より先に X に動画で出します。AIあるある が11月16日まで毎晩22:00に入っているので、その枠を引き継いで11月17日から26日に1本ずつ入れました。動画は Cloudflare R2(p2m-media)に short_butai{NN}_{名前}_v{N}.mp4 の名前で入れ、投稿文の x_video から指しています。いまの決まりどおり、X の文にリンクは入れていません。ショートは LinkedIn に出さない決まりなので、LinkedIn には予約していません。

日時予定表の id動画
11-17 22:00BUTAI01-x
short_butai01_skills_v5.mp4
11-18 22:00BUTAI02-x
short_butai02_tanomikata_v4.mp4
11-19 22:00BUTAI03-x
short_butai03_yoru_v3.mp4
11-20 22:00BUTAI04-x
short_butai04_oboeru_v4.mp4
11-21 22:00BUTAI05-x
short_butai05_kokai_v4.mp4
11-22 22:00BUTAI06-x
short_butai06_utagau_v4.mp4
11-23 22:00BUTAI07-x
short_butai07_heiko_v3.mp4
11-24 22:00BUTAI08-x
short_butai08_design_v3.mp4
11-25 22:00BUTAI09-x
short_butai09_log_v2.mp4
11-26 22:00BUTAI10-x
short_butai10_tsukurikata_v3.mp4

最初に R2 へ入れたときの出力(11月6日)

入れる 10・入っている 0・名前の重なり 0・合計 32.2MB
  10/10
おわり

X の投稿文(sns/BUTAI{NN}_sns_posts.json・10本の全文)

BUTAI01_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 01「研究のスキル一覧」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "ロボットの研究、ひとりで回してる。\n仕組みは7つ。いちばん助かってるのは、Claude Code に自動で依頼を渡す「依頼箱」。\n\n煩わしかったターミナルの作業から、やっと解放された。\n\n#ClaudeCode #フィジカルAI",
    "x_video": "/media/short_butai01_skills_v5.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI02_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 02「Claude Codeへの頼み方」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "Claude Code への指示を、自分で貼って渡すのはもうやめた。\nClaude が依頼を書いて箱に置き、Mac の見張り係が1件ずつ渡す。終わったら判定つきで報告が来る。\n\n実機を動かす依頼だけは、確認待ちで止める。\n\n#ClaudeCode #生成AI",
    "x_video": "/media/short_butai02_tanomikata_v4.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI03_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 03「寝ている間に回す」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "寝てる間も、研究は進めたい。\n夜は Claude Code が、借りたGPUで学習して片付けまで。Unity の店も、条件を変えて何十回も回す。\n\n途中経過は知りたい。でも毎時間は多い。2時間ごとか区切りで十分。\n\n#ClaudeCode #フィジカルAI",
    "x_video": "/media/short_butai03_yoru_v3.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI04_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 04「Claudeに覚えてもらう」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "同じこと、何回言えば覚えるの?\n会話が変わると、AIは決めたことを忘れる。だから決めたことはルールの本に書き足す。動画のルールは、もう105回。\n\nそれでも言う。いい加減、覚えてください。\n\n#Claude #生成AI",
    "x_video": "/media/short_butai04_oboeru_v4.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI05_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 05「記事の公開は誰が」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "記事1本の仕上げと公開、前は30〜45分かかってた。\nいまは Claude が仕上げて、GitHub からそのまま公開。SNS も時間を決めて自動で予約。\n\nサイトの更新は、もう面倒でやりたくなかった。\n\n#Claude #ひとり研究所",
    "x_video": "/media/short_butai05_kokai_v4.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI06_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 06「別のAIに疑わせる」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "AIが書いた台本は、別のAIに1文ずつ疑わせてる。数字の出どころ、言い過ぎ、引用の原文。\n\nでも codex に台本ごと任せると、ただのニュースみたいになる。だから事実確認だけ。最後に決めるのはオレ。\n\n#生成AI #ファクトチェック",
    "x_video": "/media/short_butai06_utagau_v4.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI07_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 07「並行で作る」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "動画を何本も同時に作ってると、どれがどこまでか分からなくなる。\n進み具合のページで、いま誰の番かをひと目で。\n\n自分の番になると、ハコブくんが声で知らせてくれる。会議中だけは困る。\n\n#Claude #ひとり研究所",
    "x_video": "/media/short_butai07_heiko_v3.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI08_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 08「Claudeのデザイン」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "Claude にデザインを頼むと、要素を詰め込みすぎる。\n弱いのはデザイン力じゃなくて、進め方と統一する力。\n\nだから1画面に1つ、線より面、色の意味は1つだけ。このショートのモニターも、それで作り直した。\n\n#Claude #デザイン",
    "x_video": "/media/short_butai08_design_v3.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI09_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 09「全部ログに残す」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "毎日の作業は、全部ログに残してる。\n最初はブログ記事のつもりだった。途中から、全部を書き起こすログに変えた。\n\n全部残せば、AIに読ませてそのまま使える。実際、サイトはAIにしっかり読まれてる。\n\n#Claude #フィジカルAI",
    "x_video": "/media/short_butai09_log_v2.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

BUTAI10_sns_posts.json

{
  "meta": {
    "kind": "x_short_video",
    "title": "ショート 舞台型 10「このショートの作り方」",
    "url": "https://pixelstomotors.com"
  },
  "posts": {
    "x": "このショートは、台本と画面を Claude、部屋を Claude Code が Unity で13分で建てた。声は ElevenLabs。\n\nいちばん時間がかかるのは、音声の確認。見て決めるのはオレ。\n\n#ClaudeCode #Unity",
    "x_video": "/media/short_butai10_tsukurikata_v3.mp4"
  },
  "note": "ショート専用『舞台型』(Claude・Claude Code ネタ)を YouTube より先に X に動画で出す(AIあるある と同じ扱い・22:00 の枠を引き継ぐ)。エイイチのセリフと X の文は、エイイチがこれまでに話した言葉から。作り方は iCloud 動画/_ショート専用/{動画名}/"
}

作業ログ ― video_rules.md の12節「舞台型」(いまの全文)

## 12. ショート「舞台型」(2026-11-06「研究のスキル一覧」で作った・エイイチ「OK」)

TikTok の縦長動画(「SNS運用、Claudeが終わらせた」)の構図を取り込んだ、ショート専用の型。上に見出し、奥のモニターに1つずつ、2人が床の円の上に立ち、足もとに字幕の黒い箱。中身と舞台はうちのもの(参考動画のろうそく・青緑の円はなぞらない)。
- 舞台は Unity で建てた夜の作業部屋(ServiceSim の `Assets/VideoStage/`。依頼箱 #99。既存のシーンと設定には触れない)。撮ったもの: KIOXIA `videos/_ショート専用/研究のスキル一覧/_取り込み/舞台/`(stage_bg・stage_bg_off・確認用・stage_meta.json〈モニターの4隅・円・カメラの値〉・6秒のループ)。次の回もこの舞台を使い、モニターの中身とセリフだけを替える
- 書き出し: `_ショート専用/舞台型_共通/butai_kit.py`(AIあるある の aiaru_kit.py が元)。作業フォルダに narration.py・spec.py(HEAD・scene(T,S)・OVER(T)・FACE・POSE・MOVES・SE・ENDING・STAGE・BG_NAME・T_ON・FOOT_L/FOOT_R・SIZE・SUB_ONE_LINE)を置き、`P2M_BASE=<_制作ベース> python3 ../舞台型_共通/butai_kit.py [--still 秒,…]`
- 2人の位置: 円の奥寄りに寄せて立たせる(足もと y 1525・左 x 390/右 x 690・SIZE 0.88)。エイイチ「距離感もっと近くて良さそう」で、最初の 580px 離れた位置から詰めた。身長の比はハコブくん 1.15m・エイイチ 1.7m(エイイチのドット絵は整数倍で拡大)
- 字幕: 黒い箱に1行ずつ(48px・1行15字まで)、足もとの下(y 1590)。2行の箱だとハコブくんの体が隠れた。ハコブくんは水色・エイイチは白
- **モニターの中(900×600)は面で組む**(エイイチ「グラフィカルな部分はもう少しクオリティを上げたい。雑に見える」)。細い枠線・記号のアイコン(▶■✉)・緑と赤をやめた。どの画面も、左上に「番号 / 07・名前」、その下に言いたいことを1文、図は1つ。オレンジは「いま話している1つ」だけ(止まり・いまの手順・選んだ1つ・✕)。なくても伝わる注記(凡例など)は入れない
- **床の円はゆっくり回す**(48秒で1周)。Unity の背景から円を消した版(stage_bg_noring.png・OpenCV の inpaint で作った)の上に、stage_meta.json のカメラの値で円を描き直し、破線の明るさは Unity の照明から取った(ring_lut.json)。画面を毎コマ撮るので、書き出しは約4分
- **紙吹雪は細かく華やかに**(エイイチの指示)。円の左右から打ち上げ、230片・小さめ・四角/丸/リボン/光る星、裏返りながら揺れて落ちる(canvas に描く。spec.py の OVER)
- 中身はエイイチが実際に使っているものだけにする(誇張しない)。「いちばん○○」の理由はエイイチの言葉をセリフにする(この回は「今まで煩わしかったターミナルでの作業から解放されたこと」)
- **2本目からの部品**: `舞台型_共通/butai_parts.py`(モニターの CSS・win・kick・stage_fx)と `舞台型_共通/stage/`(舞台の画像・位置の値・円の明るさ)。spec.py は `from butai_parts import *` で始め、scene と OVER と動き・効果音だけを書く。2〜10本目(Claude・Claude Code ネタ)はこの形で作った
- **山場の演出は毎回紙吹雪にしない**(エイイチ「毎回紙吹雪なので違うパターンも考えて」)。stage_fx の fx に1〜2つ選ぶ: rays(床から光の筋が回る・お祝い)/speed(マンガの集中線・叩きつけやツッコミ)/shock(床の円から波紋・知らせや決定)/spot(まわりを暗くしてスポットライト・決めるのは○○)/stars(星がまたたき少し暗く・夜)/shine(モニターの上を光の帯が走る・作り直した)/rise(床から小さな四角が立ちのぼる・データや記録)。紙吹雪(bursts)は5本に1本くらいまで。暗くする演出はモニターの中にはかけない
- エイイチのセリフは、エイイチがこれまでに話した言葉(メモリ・MASTER・ルールの本)から取り、どこから取ったかを narration.py の1行目に書く
- **最後は必ずサイトへの入口で締める**(2026-11-07 エイイチの指摘「うちのサイトへの動線部分がないけど?なんで無くしたの?」。2本目からの8本で入れ忘れていた)。narration.py の最後に「研究の記録は、毎日サイトで公開中!」の文を足し(声は「研究のスキル一覧」の 007 をそのまま使う)、spec.py の scene の最後に `h += outro(T, 締めの文の番号)` を書く(butai_parts.py の outro。モニターを pixelstomotors.com で覆う)。X の投稿文はいまリンクなしなので、動画の中の入口が唯一の動線になる
- **書き出す前に、文字の被りを機械で見る**(2026-11-07 エイイチの指摘「文字が被ってるところがある」。「記事の公開は誰が」で数字「30〜45分」と手作業のカードが重なっていた)。作業フォルダで `butai_kit.py --still 1` を走らせてから `python3 ../舞台型_共通/check_overlap.py 総尺` を回し、0.1秒ごとに (1) モニターの中の文字どうしの重なり (2) エイイチの頭と肩にかかる文字(締めで跳ねる高さも含む)を出す。出たものは静止画で目で確かめ、本当に被っていれば直す。大きな数字の行の高さによる誤検出(字面は離れている)と、わざと散らかした絵(「Claudeのデザイン」の詰め込みの例)は残してよい

video_rules.md の更新履歴(この作業で足した5行)

- 2026-11-07(109回目): C節に「最後は必ずサイトへの入口」を足した。舞台型だけでなく、本編・ショートのすべての型に当てる(エイイチの指示)
- 2026-11-07(108回目): 12節に「書き出す前に、文字の被りを機械で見る」(check_overlap.py)を足した(エイイチの指摘)。10本を点検し、4本(記事の公開・頼み方・作り方・スキル一覧)の被りを直した
- 2026-11-07(107回目): 12節に「最後は必ずサイトへの入口で締める」を足した(エイイチの指摘)。舞台型の2本目からの8本に締めがなく、作り直した
- 2026-11-06(106回目): 12節に、2本目からの部品(butai_parts.py)と、山場の演出を毎回紙吹雪にしない決まり(7つの演出)を足した。舞台型で Claude・Claude Code ネタを9本作った
- 2026-11-06(105回目): 12節「舞台型」を足した。TikTok の縦長動画の構図(舞台・奥のモニター・床の円・足もとの字幕の箱)を取り込み、Unity で夜の作業部屋の舞台を建てて1本目「研究のスキル一覧」(29.2秒)を作った。2人を寄せる・モニターの中を面で組む・字幕を1行ずつ・床の円を回す・紙吹雪を細かく、はエイイチの指示

作業ログ ― 公開のあとに直した3つ(サイトへの入口・文字の被り・締めの声)

10本を X に予約し、この記事を公開したあとで、エイイチに動画を見てもらって3つ直しました。直した順に書きます。

エイイチ「うちのサイトへの動線部分がないけど?なんで無くしたの?」

1本目の「研究のスキル一覧」と9本目の「全部ログに残す」は、最後にモニターへ pixelstomotors.com を出して締めていました。ところが、2本目からの残り8本は、部品 butai_parts.py にまとめて作ったときに、この締めを入れ忘れていました。わざと外したのではなく、部品に締めの場面がなかったので、spec.py ごとに書くのを忘れた、というのが原因です。

X の投稿文には、いまの決まりでリンクを入れていません。動画の中の締めが、見た人がサイトへ来るただ1つの入口です。それがない動画を8本も予約していました。

直し方は次の3つです。

  • butai_parts.py に、締めの場面を出す outro(T, k) を足した。モニターを紺の面で覆い、「研究の記録」の見出し・pixelstomotors.com(.com だけオレンジ)・「毎日、公開中」を順に出す
  • 8本の narration.py の最後に、ハコブくんの文「研究の記録は、毎日サイトで公開中!」を足した。声は1本目の同じ文の録音(tts/007.wav)を写して使い、新しく作らなかった
  • 8本の spec.py の scene の最後に h += outro(T, OUTRO_K) を書いた(OUTRO_K は足した文の番号で、どれも6)

あわせて、エイイチの指示「動画の最後にサイトへの動線セクションは常に追加してください」を、舞台型だけでなく本編・ショートのすべての型の決まりとして、video_rules.md のいちばん先に読む C節に書き足しました。

### 最後は必ずサイトへの入口(2026-11-07 エイイチの指示「動画の最後にサイトへの動線セクションは常に追加してください」)

- 本編・ショートの**すべての型**で、動画の最後にサイト(pixelstomotors.com)への入口の場面を入れる。画面に `pixelstomotors.com` を大きく出し、声でも「研究の記録は、毎日サイトで公開中」など、サイトに行けることを言う
- 入れ忘れないよう、書き出しの前の確認(0節・7節)で、最後の場面にサイトの入口があるかを必ず見る。舞台型の部品は 12節(butai_parts.py の outro)

エイイチ「文字が被ってるのところがある」

エイイチがスマホで見た画面写真では、「記事の公開は誰が」の2つ目の場面で、大きな数字「30〜45分」の上に、手作業のカード3枚(サムネイル作り・貼り付け・公開)が重なっていました。数字を左に、カードを右に置いたつもりが、数字が横に長く、カードの下にもぐっていました。

ここは、カードを上の段に横並びにし、数字をその下の真ん中に分けて直しました。

    # 2026-11-07 エイイチ「文字が被ってる」: 数字と手作業のカードが重なっていたので、カードを上の段に横並び、数字を下に分けた
    jobs = "".join(f'<div class="card" style="left:{48 + k * 276}px;top:110px;width:252px;height:92px;font-size:30px;align-items:center;padding:0;white-space:nowrap;opacity:0;animation:{a("up", t1 + 0.3 + k * 0.5)}">{nm}</div>'
                   for k, nm in enumerate(["サムネイル作り", "貼り付け", "公開"]))
    h += win(t1, T(2, 0), kick("前は(記事1本)") + jobs
             + f'<div class="hero" style="left:0;right:0;text-align:center;top:290px;font-size:170px;opacity:0;animation:{a("pop", t1 + s1 - 2.2, .4)}">30〜45<span>分</span></div>')

1か所見つかったなら、ほかの9本にもあるはずです。目で全コマを見るのは見落とすので、0.1秒ごとに機械で探す点検 check_overlap.py を作りました。見るのは次の2つです。

  • モニターの中で、文字どうしが重なっている所。画面が切り替わる一瞬の重なりは数えず、0.4秒以上続くものだけを出す。上に別の画面が重なって隠れている文字は数えない
  • モニターの中の文字が、エイイチの頭と肩(体の上 40%)にかかる所。エイイチの絵は、ページではなく書き出しのときに重ねるので、ページの中にはいない。そこで butai_kit.py の --still が、0.1秒ごとのエイイチの絵の範囲を out/ei_rects.json に書くようにした。締めで跳ねる高さも入れている

1回目の点検は、頭にかかる文字だけを正しく拾いました。

== Claude Codeへの頼み方 26.73
エイイチの頭: ナシ  17.9〜18.1秒(0.3秒)
被り 1 件
== このショートの作り方 22.87
エイイチの頭: 声  17.3〜17.9秒(0.6秒)
被り 1 件
== 研究のスキル一覧 29.17
エイイチの頭: ?  2.2〜3.5秒(1.4秒)
エイイチの頭: 解放!  24.2〜24.7秒(0.5秒)
被り 2 件
(ほかの7本は 被り 0 件)

文字どうしの重なりは、このとき1件も出ませんでした。直す前の「記事の公開は誰が」を写して点検にかけても0件で、点検のほうが間違っていました。原因は、紙吹雪や床の円を描く透明な層(canvas)が画面のいちばん上に乗っていて、「この点でいちばん上に見えている文字はどれか」を調べると、どの点でもその層が返ってきていたことです。どの文字も「見えていない」扱いになり、重なりを数えていませんでした。モニターの中の要素だけを、透明になった覆いを飛ばして上から探すように直すと、直す前の「記事の公開は誰が」で、エイイチが見つけた被りをそのとおりに出しました。

文字どうし: サムネイル作り × 30〜45分  7.3〜9.5秒(2.3秒)
文字どうし: 貼り付け × 30〜45分  7.3〜9.5秒(2.2秒)
文字どうし: 貼り付け × 分  7.3〜9.5秒(2.2秒)
被り 3 件

直した点検で10本をかけ直した結果です(この時点で「記事の公開は誰が」は直してあり、「Claude Codeへの頼み方」の「ナシ」は1回目の結果を見て一度動かしたあと)。

== Claude Codeへの頼み方
文字どうし: 自分で貼って渡す × ナシ  17.9〜18.7秒(0.9秒)
被り 1 件
== Claudeに覚えてもらう
文字どうし: 動画のルールを書き足した回数 × 105  13.0〜13.8秒(0.9秒)
被り 1 件
== Claudeのデザイン
文字どうし: ◆ × NEW!  4.3〜5.7秒(1.5秒)
文字どうし: POINT × 重要  5.0〜20.9秒(4.0秒)
被り 2 件
== このショートの作り方
文字どうし: この部屋(Claude Co × 0  6.6〜6.9秒(0.4秒)
文字どうし: この部屋(Claude Co × 13  8.9〜10.1秒(1.3秒)
被り 2 件
== 並行で作る
被り 0 件
== 全部ログに残す
被り 0 件
== 別のAIに疑わせる
被り 0 件
== 寝ている間に回す
被り 0 件
== 研究のスキル一覧
エイイチの頭: ?  2.6〜3.5秒(1.0秒)
文字どうし: 7 × つの仕組み  4.5〜6.1秒(1.7秒)
文字どうし: $ cd ~/Robotic × 解放!  24.2〜25.5秒(1.4秒)
被り 3 件
== 記事の公開は誰が
被り 0 件

出たものは、1つずつ静止画で目で確かめて、本当に被っているものだけを直しました。

動画出たもの目で見て直したこと
Claude Codeへの頼み方
「ナシ」のハンコが「自分で貼って渡す」に乗る。最初の位置では、エイイチが跳ねたときに頭で隠れていた
被っている
ハンコをカードの下の真ん中へ(left 330・top 400)
このショートの作り方
エイイチが跳ねると、頭が下の段の「声」にかかる
被っている
跳ねるのを、締めのサイトの画面のときに移した(ENDING を (6, 0.9) に)
研究のスキル一覧
「解放!」がコマンドの文字に乗り、頭にもかかる
被っている
左下へ移し、字を 60px から 44px に
研究のスキル一覧大きな「7」と「つの仕組み」字の下がくっついていた
「つの仕組み」を 16px から 48px 下げた(点検では行の高さで出続けるが、字面は離れた)
研究のスキル一覧「?」がエイイチの頭にかかる字面は頭より上
そのまま(大きな字の行の高さによる誤検出)
Claudeに覚えてもらう「105」と上の見出し字面は離れているそのまま(同じく誤検出)
このショートの作り方「13」と上の見出し字面は離れているそのまま(同じく誤検出)
Claudeのデザイン散らかった言葉どうしわざと散らかした絵
そのまま(「詰め込みすぎ」を見せる場面)

点検のコードの全文です。動画の決まりにも「書き出す前に、文字の被りを機械で見る」を足しました(12節。全文は下の「video_rules.md の12節」)。

15_sec10.py.txt3,989字・75行・python
# -*- coding: utf-8 -*-
"""舞台型ショートの「文字が被っている所」を探す(2026-11-07 エイイチ「文字が被ってるところがある」)
使い方: 作業フォルダで butai_kit.py --still を1回走らせて _block.html を作ってから
  python3 ../舞台型_共通/check_overlap.py 総尺秒
見るもの:
  1. モニターの中で、文字どうしが重なっている所(0.4秒以上続くものだけ。画面の切り替えの一瞬は数えない)
  2. モニターの中の文字が、エイイチの体の上 40%(頭と肩)にかかる所
     (エイイチは絵を後から重ねるのでページの中には無い。butai_kit.py --still が out/ei_rects.json に0.1秒ごとの位置を書く)
別のタブで開く保存

エイイチ「最後の「公開中」のイントネーションが変」

締めの文の声を、ハコブくんの声(ElevenLabs)で4通り作り直しました。言葉そのものを変えたものと、読み方の渡し方を変えたものです。

試し_01 研究の記録は、毎日サイトで公開中です!
試し_02 研究の記録は、毎日サイトで、こうかいちゅう!
試し_03 研究の記録は、毎日サイトで公開しています!
試し_04 研究の記録は、毎日サイトで公開してます!
できあがり: voice_eleven/締め直し  使った文字数 約82字

エイイチが聞き比べて、A(試し_01「公開中です!」)を選びました。10本の締めの声と字幕をこの言い方にそろえ、モニターに出す文(butai_parts.py の OUTRO_TEXT)も合わせました。「全部ログに残す」だけは締めの文が「記録は、pixelstomotors.comで、毎日公開中!」とほかと違うので、同じ言い方の「…毎日公開中です!」で作り直しました(読みは narration.py の ELEVEN_READ と同じ「ピクセルズトゥモーターズ ドットコム」)。

試し_01 記録は、ピクセルズトゥモーターズ ドットコムで、毎日公開中です!
できあがり: voice_eleven/締め直し  使った文字数 約32字

取り込んだあとの、締めの文の長さ(前後の無音を切ったあと)です。

研究のスキル一覧	3.27 秒(研究の記録は、毎日サイトで公開中です!)
Claude Codeへの頼み方	3.27 秒(研究の記録は、毎日サイトで公開中です!)
寝ている間に回す	3.27 秒(研究の記録は、毎日サイトで公開中です!)
Claudeに覚えてもらう	3.27 秒(研究の記録は、毎日サイトで公開中です!)
記事の公開は誰が	3.27 秒(研究の記録は、毎日サイトで公開中です!)
別のAIに疑わせる	3.27 秒(研究の記録は、毎日サイトで公開中です!)
並行で作る	3.27 秒(研究の記録は、毎日サイトで公開中です!)
Claudeのデザイン	3.27 秒(研究の記録は、毎日サイトで公開中です!)
全部ログに残す	4.50 秒(記録は、pixelstomotors.comで、毎日公開中です!)
このショートの作り方	3.27 秒(研究の記録は、毎日サイトで公開中です!)

書き出し直した10本と、最後の点検

10本を書き出し直したあと、もう一度点検をかけました。

== Claude Codeへの頼み方
被り 0 件
== 寝ている間に回す
被り 0 件
== 並行で作る
被り 0 件
== Claudeのデザイン
文字どうし: ◆ × NEW!  4.3〜5.7秒(1.5秒)
文字どうし: POINT × 重要  5.0〜20.9秒(4.0秒)
被り 2 件
== このショートの作り方
文字どうし: この部屋(Claude Co × 0  6.6〜6.9秒(0.4秒)
文字どうし: この部屋(Claude Co × 13  8.9〜10.1秒(1.3秒)
被り 2 件
== 記事の公開は誰が
被り 0 件
== Claudeに覚えてもらう
文字どうし: 動画のルールを書き足した回数 × 105  13.0〜13.8秒(0.9秒)
被り 1 件
== 別のAIに疑わせる
被り 0 件
== 研究のスキル一覧
エイイチの頭: ?  2.6〜3.5秒(1.0秒)
文字どうし: 7 × つの仕組み  4.5〜6.1秒(1.7秒)
被り 2 件
== 全部ログに残す
被り 0 件

残っているのは、上の表で「そのまま」にした誤検出とわざとの絵だけです。書き出したあとの動画も、0.9秒ごとのコマを並べて目で見て、被りが残っていないことを確かめました。

X の予約の動画の差し替え

X の予約(11月17〜26日)の動画を新しい版に差し替えました。前の版は R2 に残したまま、新しい名前で入れて、投稿文の x_video を書き換えています。動画が pixelstomotors.com/media/ から開けること(10本とも 206 で先頭が返る)と、予約の点検(sns_autopost.py check)が「問題ありません」になることを確かめました。

1回目(サイトへの入口と文字の被りを直した9本・11月7日):

入れる 9・入っている 1・名前の重なり 0・合計 31.9MB
  9/9
おわり

2回目(締めの声を「公開中です!」にした10本・11月7日):

入れる 10・入っている 0・名前の重なり 0・合計 35.6MB
  10/10
おわり

いまの予約の動画です。

予定表の id動画
BUTAI01-x
short_butai01_skills_v5.mp4
BUTAI02-x
short_butai02_tanomikata_v4.mp4
BUTAI03-x
short_butai03_yoru_v3.mp4
BUTAI04-x
short_butai04_oboeru_v4.mp4
BUTAI05-x
short_butai05_kokai_v4.mp4
BUTAI06-x
short_butai06_utagau_v4.mp4
BUTAI07-x
short_butai07_heiko_v3.mp4
BUTAI08-x
short_butai08_design_v3.mp4
BUTAI09-x
short_butai09_log_v2.mp4
BUTAI10-x
short_butai10_tsukurikata_v3.mp4

次に確かめること ― X での10本の見られ方

  • 11月17〜26日の X で、10本の再生と見られた長さを、同じ22:00の枠で出した AIあるある の14本と比べる。舞台型の構図が見られやすいのかを、ここで初めて数字で見る
  • 10本を YouTube のショートにも上げるかは、X の結果を見てエイイチが決める。上げるときのタイトルと説明文は、KIOXIA の videos/_ショート専用/{動画名}/ショート_タイトルと説明文.txt に用意してある
  • Unity の舞台のゆらぎの映像(stage_loop.mp4)は、まだ使っていない。背景が止まった絵で物足りなければ、ここから入れる