顔出しなし動画の自動化パイプライン実測:1本 $0.30、通しで 260 秒

キー1本、4ステップ。台本モデル、5 秒クリップ3本、ffmpeg 連結。15 秒の縦型動画が $0.3009、260 秒でできました。そして壊れるのは決まって3か所です。

顔出しなし動画の自動化パイプライン実測:1本 $0.30、通しで 260 秒

15 秒の縦型ショートが、台本から連結済みファイルまで $0.3009、260 秒。 4ステップ、API キー1本、Python でおよそ 60 行。面白いのは動くことではなく、毎日回そうとしたときに壊れるのがどの3か所か、です。

できるもの:   15 秒の縦型 9:16 MP4、496x864、H.264 + AAC
ステップ:     チャット1回 -> 動画ジョブ3本(並列)-> ffmpeg 連結
時間:         台本 5.7 秒 + クリップ 254.7 秒(並列)+ 連結 0.05 秒 = 260.4 秒
費用:         動画 $0.30 + 台本 $0.0009 = $0.3009
60 秒あたり:  同条件でおよそ $1.20 の生成費
含まないもの: ナレーション(このエンドポイントに TTS なし)、音楽、字幕、検品
計測:         2026-08-24、通しで1回

最終更新 2026-08-24。価格はその日の ofox モデルページのレートで、Seedance 2.0 Mini は 50% 割引中でした。月次予算を外挿する前にページを確認してください。

顔出しなし動画のパイプラインは実際いくらか

15 秒で 30 セント。台本モデルは端数です。

ステップモデル / ツール時間課金
ショットリストdeepseek/deepseek-v4-flash-07315.7 秒約 $0.0009
5 秒 × 3 本、480p 9:16bytedance/seedance-2.0-mini254.7 秒(実時間)$0.30
連結ffmpeg concat、ストリームコピー0.05 秒$0
合計260.4 秒$0.3009

台本の呼び出しは入力 317、出力 572 トークン(うち推論 349)で、単価は 100 万あたり $0.44 と $1.32。このパイプラインのテキスト側の判断は、実質すべて無料です。請求は全部が動画で、しかも秒数に比例します。 つまり効くレバーは「何秒作るか」と「どの解像度で作るか」だけです。

Seedance 2.0 Mini のレート、480p が1秒 $0.02、720p が $0.04 で計算すると、毎日 60 秒のショートを出すなら 480p で1日約 $1.20、720p で $2.40。1年続けると 480p で $438、720p で $876 の生成費です。議論すべきはクリップ単価ではなくこの数字です。

ステップ1:ニッチをショットリストに変える

JSON モードのチャット1回。仕事をするのは system プロンプトのスキーマです。

import json, requests

BASE = "https://api.ofox.ai/v1"
H = {"Authorization": "Bearer YOUR_OFOX_API_KEY"}

SYS = (
    "You write shot lists for faceless vertical short-form video. Reply with JSON only: "
    '{"title": str, "hook": str, "shots": [{"n": int, "narration": str, "video_prompt": str}]}. '
    "Exactly 3 shots. Each narration is one sentence a narrator reads in about 5 seconds. "
    "Each video_prompt describes a single continuous 5-second shot with camera movement, "
    "no on-screen text, no people, no watermark, vertical framing."
)

r = requests.post(f"{BASE}/chat/completions", headers=H, json={
    "model": "deepseek/deepseek-v4-flash-0731",
    "messages": [{"role": "system", "content": SYS},
                 {"role": "user", "content": "Niche: strange facts about deep-sea creatures. "
                                             "Audience: TikTok, 15 seconds total."}],
    "response_format": {"type": "json_object"},
    "temperature": 0.7,
})
script = json.loads(r.json()["choices"][0]["message"]["content"])

5.7 秒で返ってきたものをそのまま載せます。

{"title": "Deep Sea Oddities",
 "hook": "You won't believe what lives in the deep sea.",
 "shots": [
   {"n": 1, "narration": "The anglerfish lures prey with a glowing light attached to its head.",
    "video_prompt": "Slow push-in on a bioluminescent anglerfish in the dark deep sea, its glowing lure bobbing gently, marine snow drifting through the beam, vertical framing."},
   {"n": 2, "narration": "The barreleye fish has a transparent head to see through its own skull.",
    "video_prompt": "Side tracking shot of a barreleye fish with a transparent head, its green eyes visible inside, floating in a dark blue abyss, subtle light from above, vertical framing."}]}

真似する価値のある細部が2つ。各ショットに n を持たせておけば、並列 map のあとで配列順が保たれるかを気にせず shot1.mp4 と名付けられます。そして否定条件(画面上のテキストなし、人物なし、ウォーターマークなし)を system プロンプトに書いておけば、3つの動画プロンプト全部に効いて、同じことを3回書かずに済みます。レスポンス形式そのものは DeepSeek の JSON モードガイドにあります。

ナレーションの行だけは、まだ行き場がありません。これは覚えておいてください。

ステップ2:クリップを並列で生成する

3本まとめて投げて、待つのは1回。 動画エンドポイントは非同期なので、送信とポーリングをスレッドプールに載せるだけです。

from concurrent.futures import ThreadPoolExecutor
import time

TERMINAL = {"completed", "failed", "cancelled", "expired"}

def make_clip(shot):
    job = requests.post(f"{BASE}/videos", headers=H, json={
        "model": "bytedance/seedance-2.0-mini",
        "prompt": shot["video_prompt"] + " Vertical 9:16 framing. No text, no watermark.",
        "duration": 5, "resolution": "480p", "aspect_ratio": "9:16",
    }).json()                                   # 202 + id + polling_url
    while True:
        s = requests.get(job["polling_url"], headers=H).json()
        if s["status"] in TERMINAL:
            break
        time.sleep(3)
    open(f"shot{shot['n']}.mp4", "wb").write(requests.get(s["unsigned_urls"][0]).content)
    return s["usage"]                            # {'video_seconds': 5, 'video_cost': '0.1000000000'}

with ThreadPoolExecutor(max_workers=3) as ex:
    usages = list(ex.map(make_clip, script["shots"]))

生成された3本のクリップから1フレームずつ抜いた縦型の画像。発光するチョウチンアンコウ、青い水中の大きな目の魚、波打つ海底の上にいる小さな白いタコ。それぞれ 85.1、126.7、253.2 秒、1本 10 セントと注記されている

3本はそれぞれ 85.1、126.7、253.2 秒で完了しました。同じモデル、同じ尺、同じ解像度、同じ秒に送信して、です。並列の実時間は 254.7 秒、直列なら 465.0 秒だったので、プールで約 45% 短縮され、それでもいちばん遅い1本がペースを決めました。

completed を見たワーカーの中でファイルを落としてください。 unsigned_urls の署名は 24 時間で、このモデルにフォールバックできる2本目の URL はありません。非同期まわりの残りの罠は動画ポーリングの実測記事にまとめています。

ステップ3:クリップを連結する

条件が揃っているときに限り、ffmpeg concat のストリームコピー。

printf "file 'shot1.mp4'\nfile 'shot2.mp4'\nfile 'shot3.mp4'\n" > list.txt
ffmpeg -y -f concat -safe 0 -i list.txt -c copy short.mp4

これは 0.05 秒で終わり、15.296 秒・496x864・4.4 MB のファイルができました。ストリームコピーが効くのは、3本とも形式が同一だったからです。24 fps の H.264、32 kHz ステレオ AAC、同じ寸法。ffmpeg concat demuxer が求めているのはまさにそれです。

concat のリストファイル、100 分の数秒で終わる ffmpeg 連結、15.296 秒 496x864 h264 と報告する ffprobe、3本の元クリップの平均音量を -35.0、-27.0、-24.3 dBFS と表示する volumedetect が並ぶターミナル画面

この回に生成された3本の連結とレベル確認です。

バッチが混ざった瞬間に成り立たなくなります。1080p の Seedance 2.5 クリップは H.264 ではなく HEVC で返ってくるので、-c copy で H.264 と連結しても期待どおりにはなりません。1本の動画につきモデルと解像度を固定するか、再エンコードしてください。

ffmpeg -y -f concat -safe 0 -i list.txt -c:v libx264 -c:a aac -r 24 short.mp4

算数にも注意です。5.041 秒が3本で 15.000 秒にはなりません。プラットフォームや編集側が厳密な尺を要求するなら、連結後にトリムしてください。

なぜナレーション工程がないのか

このエンドポイントに音声合成モデルがなく、クリップ自身の音はナレーションではないからです。 これは動画 API で作る顔出しなしパイプラインすべてに共通する正直な欠落で、たいていは言葉を濁されます。

得られるのはモデル生成の環境音。得られないのは、台本モデルが書いたナレーションを読む声です。しかもその環境音には別の問題があります。

クリップ平均音量ピーク
ショット1-35.0 dBFS-19.2 dBFS
ショット2-27.0 dBFS-12.8 dBFS
ショット3-24.3 dBFS-7.4 dBFS

1バッチの中で 11 dB 近い開き。 これは volumedetect の RMS 値で LUFS ではないので、プラットフォームのラウドネス目標と直接比べないでください。効いてくるのはクリップ間の差で、そのまま連結するとカットごとに音量の段差が聞こえます。loudnorm を1回かければ均せます。

ffmpeg -i short.mp4 -af loudnorm=I=-14:TP=-1.5:LRA=11 -c:v copy short_normalised.mp4

声そのものには3つの道があり、どれもこの API ではありません。ナレーションを専用の TTS プロバイダーに送ってミックスする、自分で録る、あるいは声をあきらめて字幕として焼き込む。ショート動画がどれだけミュートで見られているかを考えれば、字幕は劣った選択肢ではありません。

毎日更新のチャンネルに広げると何が壊れるか

痛い順に3つ。

時間のばらつきがスケジューラを壊します。 同一リクエストで3倍の開きがあるということは、08:00 にレンダリングして 08:05 に公開する cron は、いつか何も公開しません。先にレンダリングし、出力をキューに積み、キューから公開してください。

台本のファクトチェックを誰もしていません。 ショット2 は透明な頭を持つデメニギスを求めました。返ってきたのは目の大きい魚で、透明なドームはありません。そのトピックを検索した視聴者にはまさに気づかれる形で間違っています。台本モデルは正しい文を書き、動画モデルはそれをゆるく絵にした。そのずれを捕まえる工程がこのパイプラインには存在しません。1日1本なら目視できます。10 本になれば無理です。

プラットフォームのポリシーはレンダリングの問題ではありません。 YouTube のチャンネル収益化ポリシーはオリジナルで真正なコンテンツを求め、大量生産や反復的な素材を名指しします。その上にパートナープログラムの参加資格が乗り、API 投稿側は TikTok のコンテンツ共有ガイドラインが扱います。生成は制作ツールです。編集上の判断、具体性、そして誰かが見る理由は、依然としてこちらが用意する部分であり、API が売っていない部分です。

そこを踏まえて使えば、このパイプラインは十分に元が取れます。「15 秒の映像つきショートを作る」を午後まるごとから4分と 30 セントに変えるので、試す価値のあることの範囲が変わります。ステップ2 に入れるモデルの選び方は用途から動画生成 API を選ぶ、Mini に留まる費用対効果の議論は Seedance のティア比較にあります。

台本モデルと動画モデルでキーを1本にまとめるには

このパイプラインはまったく種類の違う2つのモデルに触れます。厳密な JSON を返す必要のあるテキストモデルと、非同期で動き秒単位で課金される動画モデル。ネイティブにやればプロバイダー2社、SDK 2つ、ダッシュボード2つ、請求書2通、そのうえテキスト側のベンダーには動画モデルがなく、動画側のベンダーのテキストモデルは JSON が得意ではない、という発見が待っています。

この記事の2つの呼び出しは同じベース URL に同じキーで飛んでいます。ショットリストが /v1/chat/completions、クリップが /v1/videos。スクリプトが 60 行で済む理由はそれだけです。両方の形を出しているので ofox で動かしていますが、同じことをするゲートウェイなら何でも構いません。踏み切る前に確認すべきは、テキスト側が response_format をきちんとサポートしているかです。JSON を期待した場所に散文が返るパイプラインは、毎回ステップ1で落ちます。他の3ステップを作る前に、1回の呼び出しでそこを試してください。

参考資料

よくある質問

API で顔出しなしのショート動画を作るといくらかかりますか?
15 秒の縦型ショートで $0.3009 でした。内訳は Seedance 2.0 Mini の 5 秒 480p クリップ3本が1秒 $0.02 で $0.30、台本の呼び出しが DeepSeek V4 Flash でおよそ $0.0009。長さに比例するので、60 秒のショートなら生成費はおよそ $1.20 です。ナレーション、音楽のライセンス、自分の時間は含みません。
パイプライン全体でどれくらいかかりますか?
15 秒のショートで実時間 260 秒です。台本が 5.7 秒、3本のクリップが並列で 254.7 秒、ffmpeg の連結が 0.05 秒。直列なら 465 秒かかっていたので、まとめて投げたことで実時間を約 45% 削れました。
台本と動画を同じ API キーで賄えますか?
両方を提供するゲートウェイなら可能です。台本の呼び出しは /v1/chat/completions、クリップは /v1/videos で、ベース URL もキーも同じでした。これがこのパイプラインを、ベンダー SDK 2つと請求2件のプロジェクトではなく 60 行のスクリプトにしている部分です。
生成されたクリップに音は付きますか?
モデルが生成した AAC トラックが付きますが、小さくてばらつきます。同一バッチの3本を ffmpeg の volumedetect で測ると平均レベルは -35.0、-27.0、-24.3 dBFS で、差は 11 dB 近くありました。これは LUFS ではなく RMS の値なのでプラットフォームのラウドネス目標と直接比べないでください。ただしクリップ間のこの差だけでも、公開前にラウドネス正規化が必要だと分かります。
このパイプラインに音声合成の工程はありますか?
このゲートウェイにはありません。あるふりをするのが顔出しなしチャンネル解説でいちばんよくある嘘です。ナレーション文は台本モデルがテキストで出すので、別の TTS プロバイダーに送るか、画面上の字幕として焼き込むかになります。動画エンドポイントがナレーションを読み上げることはありません。
ffmpeg のストリームコピーで連結できますか?
すべてのクリップでコーデック、解像度、音声パラメータが揃っているときだけです。今回の 480p クリップ3本はいずれも 24 fps の H.264 と 32 kHz の AAC だったので、-c copy の連結は 0.05 秒で終わりました。1080p の Seedance 2.5 クリップ(HEVC で返る)が混ざるとストリームコピーは通らなくなります。
同じ条件のクリップで生成時間はどれくらい安定しますか?
あまり安定しません。今回の3本は同じ秒に、同じモデル・同じ尺・同じ解像度で投げて、85.1、126.7、253.2 秒で終わりました。スケジューラを作るなら、いちばん遅い1本がバッチの完了時刻を決めると仮定するしかありません。
この作り方の動画は YouTube で収益化できますか?
それだけでは無理です。YouTube の収益化ポリシーはオリジナルで真正なコンテンツを求め、大量生産や反復的な素材を名指しで挙げています。生成は制作ツールであって免除条項ではないので、編集も文章も視点も自分のものである必要があります。