TikTok / Douyin ショート動画ジェネレーター
あなた(エージェント)はクリエイティブな作業、つまりスクリプト作成、シーン分割、検索キーワード、スタイル選択、品質レビューを行います。scripts/内のスクリプトは機械的な作業、つまり単語タイムスタンプ付きのTTS、アセット検索・ダウンロード、キャプションレンダリング、ffmpeg合成、ラウドネス正規化を行います。
すべてはコアのffmpegのみ(libass/drawtext不要)とPython venvで動作します。APIキーは不要です。PEXELS_API_KEY / PIXABAY_API_KEY 環境変数を設定すると(より良い)実際のストック動画クリップのロックが解除されます。
ワークフロー
0. 初期セットアップ(.venv/ と assets/fonts/ が存在する場合はスキップ)
bash scripts/setup.sh
1. 最初に事実を確認し、スクリプト+ストーリーボードを作成する
あなたの内部知識は古かったり間違っていたりする可能性があります — 未確認の主張を決して動画に入れないでください。 シーンのテキストを作成する前に、Web検索ツールを使用して、すべての具体的な主張(数字、統計、記録、価格、日付、順位、"初めて / 最大 / 唯一 / 最速" という記述、そして「今年/最新」のような時事性の高いもの)を確認してください。どれだけ自信があっても、です。ルール:
- 主張は、情報源が述べている通りにのみスクリプトに含めます — 情報源に合わせて表現を調整し、その逆はしてはいけません。
- 確認できない場合は、確認できる主張に置き換えるか、削除します。公開された動画に間違った数字が含まれることは、弱いフックよりも悪い結果を招きます。
- ストーリーボードの
"sources": [...]に依存したURLを記録してください。これらはreview/report.txtに反映され、ユーザーが動画を監査できるようになります。 - 本当にWebアクセスがない場合は、長年確立された教科書的な事実に留め、具体的な数値を避け、動画が未確認であることをユーザーに伝えてください。
スクリプトの公式(フックの種類、テンポ、シーン構造)については references/writing-guide.md を参照してください。その後、projects/<slug>/storyboard.json を作成します:
{
"title": "深海里最诡异的5种生物",
"lang": "zh",
"aspect": "9:16",
"voice": "zh-CN-YunjianNeural",
"rate": "+10%",
"caption_style": "karaoke",
"bgm": {"mood": "mystery", "gain_db": -16},
"hook": {"text": "深海禁区", "seconds": 2.3},
"scenes": [
{
"text": "你知道吗?在阳光永远照不到的深海,藏着比科幻电影更诡异的生物。",
"keywords": ["deep sea NOAA ocean exploration", "submarine dark ocean"],
"providers": ["openverse", "wikimedia"],
"badge": null,
"effect": "kb_in"
},
{
"text": "第一名,鮟鱇鱼……",
"keywords": ["humpback anglerfish", "anglerfish museum"],
"badge": "第1名"
}
]
}
フィールドリファレンス:
| フィールド | 値 | 備考 |
|---|---|---|
lang | zh | en | キャプショングルーピングとデフォルト音声を設定 |
aspect | 9:16 (デフォルト) | 16:9 | 1:1 | |
voice | 任意のedge-tts音声 | zh: zh-CN-YunjianNeural(磁性男声) zh-CN-XiaoxiaoNeural(女声) zh-CN-YunxiNeural(阳光男声); en: en-US-ChristopherNeural en-US-AriaNeural en-US-GuyNeural |
rate | 例: +10% | マーケティングアカウントのペース:zh +8%+15%, en +5%+10% |
caption_style | karaoke | pop | none | karaoke = 単語ごとのハイライト(推奨) |
bgm | {"mood": ...} | {"query": "スタイルワード"} | {"file": "path.mp3"} | {"mood":"none"} | デフォルトで mood を使用:厳選されたテーブル(upbeat funny inspiring chill tech mystery epic sad horror)は、無数のマーケティングアカウントチャンネルで使用されているMacLeodの定番曲そのものです。実績があり、安全で、プロジェクトごとに変化があります。コンテンツのスタイルに合うムードがない場合(またはユーザーがジャンルを指定した場合)にのみ query を使用します。実際のCCビートミュージック(ccMixterスタイルタグ + Openverse/Jamendo、ND/NCは除外)を検索し、各候補はビートトラッカーによってスクリーニングされます。確実な75~175 BPMのグルーブがない場合は採用されません。タグにマッピングされるスタイルワード:trap/phonk、hip hop、lofi/chill、edm/dance、epic/cinematic、quirky。両方を設定することも可能です。queryが最初に試され、moodがフォールバックになります。file = ユーザー自身のトラック |
bgm.vibe | "spedup" | "slowed" | 未設定 | 抖音のシグネチャーサウンド:spedup ≈ 1.25倍速でピッチ上昇(卡点/盘点视频の主流処理)、slowed = スロー+リバーブ(情感/氛围向け)。file を含む任意のBGMソースに適用されます。処理後にビートグリッドが再解析されるため、卡点は正確なままです |
beat_sync | true (デフォルト) | false | BGMがビート分析され、グリッドに自信がある場合、すべてのシーン/ショットのカットがビートグリッドにスナップされます(卡点)。VOが途切れることはなく、呼吸用のパッドのみが調整されます |
hook | {"text","seconds"} | 最初に表示される大きなタイトルカード。8文字/単語以内 |
sticky_title | {"text": ...} | 上部に表示されるオプションの永続的なトピックバー。デフォルトではオフ。ユーザーが明示的に要求した場合のみ追加してください |
sfx | true (デフォルト) | false | シーン切り替え時のウィッシュ音 |
シーン keywords | 英語の、具体的な名詞クエリのリスト | 各エントリ = 1つのショット(ビジュアル);動画は約3秒ごとに新しいビジュアルにカットされるため、約4秒を超えるシーンでは2~3のクエリを指定してください(少ないクエリを指定した場合、自動的にクエリが循環されて追加のショットが追加されます) |
シーン badge | 例: "第1名" / "TOP 1" | シーン開始時に表示される大きなスタンプラベル。リスト記事で使用します |
シーン providers | リスト | キー不要の画像:openverse wikimedia nasa;キー不要の実際の動画:wikimedia_video (Commonsクリップ、サーバートランスコード) nasa_video (PD宇宙/科学) archive_video (Prelingerパブリックドメイン歴史映画);キーあり:pexels_video pexels_photo pixabay_video |
シーン effect | auto kb_in kb_out pan_left pan_right static | 最初のショットのKen Burnsモーション。後続のショットは自動的に循環します |
シーン emphasis | 部分文字列のリスト | 永続的にハイライトされる単語(popスタイル) |
シーン media | ファイルパス | 検索をスキップし、自分でダウンロードしたファイルなどを使用します |
目安(公開基準): 合計45~75秒、6~9シーン、1シーン1アイデア、1シーン2~3ショット。 シーンテキストは中国語20~45文字 / 英語14~30単語。40秒未満や、シーン全体が単一ショットで構成されていると、薄っぺらく感じられます。そのような動画は納品しないでください。
2. パイプラインを実行する
.venv/bin/python scripts/pipeline.py projects/<slug>
またはステージごとに: tts.py → assets.py → bgm.py → compose.py → check.py。
3. レビュー — これが品質を左右します(必須)
無料画像検索は不完全です。必ずあなたの画像ツールで以下の2つのファイルを表示し、人間の編集者の目で評価してください:
-
projects/<slug>/media/assets_sheet.jpg— アセットステージの後。 ショットには01a 01b 02a …とラベルが付けられています。ナレーションと明らかに一致しないショットがあれば、それを再取得してください:.venv/bin/python scripts/assets.py projects/<slug> --scene 3 --shot 2 --keywords "better english nouns"(再取得すると、拒否されたアセットは自動的にブラックリストに登録されます。すべてのシーンが一致するまで繰り返します。自分のツールで画像を自分でダウンロードし、シーンの
mediaに指定することもできます。)パイプラインはまた、各ショットのソースタイトルをクエリに対してテキスト監査し、
[!] OFF-TOPICフラグを出力します。フラグが立ったショットを視覚的に確認して実際に正しい場合(例えば、タイトルはないが完璧な写真)、media/manifest.jsonの該当ショットに"approved": trueを設定してクリアしてください。あなたの目がテキスト監査よりも優先されます。盲目的に承認しないでください。 -
projects/<slug>/review/contact_sheet.jpg— compose+checkの後。 確認事項:キャプションが読みやすく同期しているか、間違った/醜いフレームがないか、フックが表示されているか。問題を修正し(storyboardを編集 → composeを再実行、これは高速です)、まるでマーケティングアカウントの編集者が実際に公開するような動画になるまで繰り返します。
review/report.txt には、長さ/ラウドネスのチェックと、すぐに貼り付け可能な帰属ブロック(CC-BYソース+音楽クレジット)が含まれています。final.mp4 と共に必ずユーザーに提供してください。
アセット検索のヒント(最大の品質向上策)
- キーワードは英語で、1~4語、具体的で目に見える名詞(「humpback anglerfish」、「scuba diver silhouette」)に限定し、「mystery」や「success」のような抽象的な概念は避けてください。
wikimediaは動物/科学/歴史/場所に最適です。openverse(Flickrなど) はライフスタイル/風景/雰囲気に、nasaは宇宙に適しています。キーはpexels_video/pixabay_videoの実際の映像をアンロックします。利用可能な場合はこれらを優先してください。- 曖昧さを排除するために文脈語を追加します:「NOAA」、「museum」、「aquarium」、「macro」。
- シーンが失敗し続ける場合は、単語を変えるだけでなく、ビジュアルコンセプト自体を変更してください(例:「5% explored」には「statistics」ではなく、ダイバーのシルエットを表示する)。
wikimedia_videoの検索は否定語をサポートしています。Commonsの天気/宇宙クエリは衛星ループで溢れかえるため、例えば"lightning storm -CIRA -satellite -JPSS"と記述します。非英語の単語は追加の映像をアンロックします(「Blitz Gewitter」、「tormenta rayos」)。一般的な名詞よりも、名前のある被写体(「Fagradalsfjall lava drone」)を優先し、常にシート内の動画サムネイルを目視で確認してください。埋め込まれたキャプション、ウォーターマーク、チュートリアル、CGIプロモーションに注意してください。
トラブルシューティング
edge-ttsのネットワークエラー:4回再試行します。それでも失敗する場合はtts.pyを再実行してください。- BGMのダウンロードに失敗:
bgm.pyを再実行するか(再試行+キャッシュ)、--mood noneを指定するか、mp3をassets/bgm/にドロップしてbgm.fileを設定してください。 - BGMのスタイルが合わない:クエリを調整する(
bgm.py <dir> --query "..."してから--skip-tts --skip-assetsで再合成)。本当の今話題のサウンドが必要な場合は、mood: none(または低ゲイン)で納品し、アップロード時にTikTok/抖音のアプリ内ライセンス音楽ライブラリからトレンドトラックを追加するようユーザーに伝えてください。これは合法であり、アルゴリズム的にも有利です。シーンのペースは変わらないため、カットのタイミングは依然として正確です。 check.pyが「カットがビートに乗っている」行を出力します。ビート同期がスキップされた場合(グリッドの信頼性が低い、例:ビートのないアンビエントミュージック)、より安定したトラック(--query "trap beat"など)を選んで再合成してください。- プロバイダーがエラーを返したり空だったりするのは問題ありません。他のプロバイダーがカバーします。シーンごとのログを確認してください。
- ストーリーボード編集後の再合成は低コストです(pipeline.py で
--skip-tts --skip-assetsを指定するか、compose.py を直接実行します)。シーンのテキストを変更するにはtts.pyの再実行が必要です。 - キャプション内の絵文字はmacOS(Apple Color Emoji)ではレンダリングされます。Linuxでは、NotoColorEmojiがインストールされていない限りドロップされます。絵文字に意味を依存させないでください。
納品
ユーザーに以下を提供します:final.mp4、review/report.txt からの帰属ブロック、そして(要求された場合)カバー画像として review/cover.jpg。