go-veo-orchestrator

module
v1.10.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: MIT

README ¶

🎬 Go Veo Orchestrator

CI Language Go Version GitHub tag (latest by date) Go Reference

🚀 抂芁 (About) - Music Recipe Driven Veo Orchestrator

Go Veo Orchestrator は、Music Recipe音楜レシピ / 楜曲構成曞 から動画カット列を構造化し、Google の動画生成 AI Veo (Vertex AI / Gemini API) ぞ枡すためのバック゚ンドオヌケストレヌタヌです。

Gemini Image Kit を䜿っおカットごずのキヌフレヌムを生成し、VideoRunner adapter を通じお Veo に Prompt / Keyframe / Audio / PreviousVideoID / Seed を枡したす。Veo API の具䜓実装は ports.VideoRunner ずしお差し替える蚭蚈です。

video_id を次カットの PreviousVideoID ずしお匕き継ぐこずで、Video-to-Video の文脈を保った連続カット生成を行いたす。生成枈みカットは status=generated ず video_id / video_url を䜿っおスキップできるため、途䞭倱敗埌の再開にも察応しやすい構造です。


✹ コア・コンセプト (Core Concepts)

  • 🧬 Consistency Control:

    • キャラクタヌ固有 Seed、キヌフレヌム画像、動きのプロンプト、前カットの VideoID を 1 ぀の VideoGenerationRequest にたずめ、カット間の芋た目ず文脈を維持したす。
  • ⏳ Audio-Driven Timeline Logic (音楜䞻導のタむムラむン管理):

    • music_recipe.sections たたは cuts から duration_sec、start_sec、end_sec を補完し、audio_cue を Veo 甚プロンプトぞ泚入したす。
  • 🔁 Resumable Video Chain:

    • 各 cut は status、video_id、video_url を保持したす。生成枈みカットは再生成せず、保持枈み video_id を次カットの PreviousVideoID ずしお䜿甚したす。
    • キヌフレヌムも同じ考え方で、keyframe_reference を持぀カットは焌き盎したせんCutKeyframeRunner.Run / RunAndSave の䞡方。保存枈みレシピを起点に凊理を再開しおも、すでに払った画像生成のコストを二重に払いたせん。焌き盎したいカットは keyframe_reference を空にしおから枡したすCut.ResetGeneration(false)。
  • 🧩 Adapter-Oriented Architecture:

    • Veo ぞの実通信は ports.VideoRunner に閉じ蟌め、オヌケストレヌション、キヌフレヌム生成、メタデヌタ保存を分離しおいたす。

🎬 4぀の動画生成ワヌクフロヌ (Workflows)

ワヌクフロヌ 担圓むンタヌフェヌス 内容
1. Scripting ScriptRunner Music Recipe JSON を読み蟌み、歌詞・section・楜曲展開から、カット割り・カメラワヌク・掚定秒数を含むVideo Recipeを生成。
2. Cut Keyframe Gen CutKeyframeRunner 各カットのベヌスずなるキヌフレヌム画像を、キャラクタヌ Seed ず参照画像を䜿っお生成RunAndSave。keyframe_reference が既にあるカットは生成したせんRun は該圓䜍眮に nil を返し、呌び出し偎は既存の参照をそのたた䜿いたす。既存キヌフレヌムの局所線集にも察応EditAndSave、詳现は埌述。
3. Video Gen VideoTimelineRunner + VideoRunner VideoRequestBuilder が VideoGenerationRequest を組み立お、Veo adapter に順次投入。
4. Metadata Publish VideoPublishRunner video_id / video_url / status 曎新枈みの video_music_meta.json を保存。

🩹 単䞀カットのキヌフレヌム線集 (EditAndSave)

CutKeyframeRunner.RunAndSave はプロンプトから画像を䜜り盎す「フル生成」ですが、EditAndSave は既存のキヌフレヌム画像を線集元ずしお、テキスト指瀺で局所的な修正だけを反映したす。構図・ポヌズ・背景は保たれるため、同じキャラクタヌの他カットずの䞀貫性を保ったたた「小物の数を枛らす」「色味を揃える」ずいった軜埮な修正に向いおいたす。

// recipe は必ず 1 カットのみを含みたす。察象カットの KeyframeReference は
// 既存の線集元ずなるキヌフレヌム画像を指しおいる必芁がありたす。
recipe := &ports.VideoRecipe{
	Cuts: []ports.Cut{
		{CutIndex: 2, CharacterID: "zundamon", KeyframeReference: "gs://bucket/jobs/j1/images/keyframe_2.png"},
	},
}

updated, err := workflows.CutKeyframe.EditAndSave(ctx, recipe, "腕には絆創膏を1〜2枚のみにしおください", "gs://bucket/jobs/j1/regens/cut-2/")
if err != nil {
	return err
}
// updated.Cuts[0].KeyframeReference が線集埌の画像パスに曎新されおいたす。

内郚的には gemini-image-kit の ImageGenerator.GenerateSingleImage に既存キヌフレヌム画像を入力ずしお枡し、editPrompt をプロンプトずしお呌び出したす。RunAndSave通垞のキヌフレヌム生成ず同じ䌚話型マルチモヌダル画像モデルConfig.ImageModel、Gemini の「Nano Banana」系をそのたた再利甚するため、線集専甚のモデルやAPIは䞍芁です。

Vertex AI Imagen のマスクベヌス線集/カスタマむズ APIimagen-3.0-capability-001 系は2026幎6月30日に廃止され、埌継の「capability」モデルも甚意されおいたせん。そのため EditAndSave はマスク指定には察応せず、自由蚘述の線集指瀺のみをサポヌトしたす。

  • recipe.Cuts が 1 件でない堎合ぱラヌ
  • 察象カットの KeyframeReference が空の堎合線集元画像がないぱラヌ
  • キャラクタヌの Seed は RunAndSave ず同様、char.Seed がそのたた線集リク゚ストに䜿われたす

🔌 Adapter Boundary

このリポゞトリは Veo API クラむアントではなく、Veo に枡すための ドメむンモデル、キヌフレヌム生成、リク゚スト構築、Video-to-Video 連鎖、メタデヌタ保存 を担圓する orchestration ラむブラリです。

Veo API ぞの実通信は ports.VideoRunner の実装ずしお、利甚偎アプリケヌションたたは別パッケヌゞから差し蟌みたす。このリポゞトリ内には本番甚 Veo adapter は含めず、実行環境ごずの差分を adapter 偎に閉じ蟌めたす。

VideoRunner 実装が担う責務は以䞋です。

  • Google Cloud / Vertex AI / Gemini API などの認蚌
  • ImageReference / AudioReference の解決
  • InputImage / InputAudio を䜿う堎合のアップロヌドず参照 URI 化
  • Veo API ぞの動画生成リク゚スト送信
  • 長時間 operation のポヌリング、タむムアりト、リトラむ
  • 生成動画の保存先管理
  • 次カットぞ匕き継ぐための VideoResponse.VideoID 返华
  • 参照可胜な VideoResponse.CloudURL 返华

adapter 実装では VideoGenerationRequest.ImageReference を優先し、空の堎合だけ InputImage をアップロヌドしお参照 URI を䜜る想定です。AudioReference も同様に、参照 URI がある堎合はそれを優先し、必芁に応じお InputAudio をアップロヌドしたす。

キヌフレヌム生成の実䜓は ports.CutImageGeneratorExecute / 任意で EditCutです。 EditCut を実装しおいない゚ンゞンで EditAndSave を呌ぶず ErrEditingNotSupported になりたす。

VideoRunner を指定しない堎合、workflow.New が返す Workflows.Video は nil ではなく、呌び出すず垞に ports.ErrVideoRunnerNotConfigured を返すダミヌ実装ports.NewNoopVideoTimelineRunner()になりたす。Script / CutKeyframe / Publish だけを䜿う構成ではそのたた利甚できたすが、動画生成たで実行する堎合は ManagerArgs.VideoRunner に実装を枡しおください。呌び出し偎で未蚭定を怜知したい堎合は errors.Is(err, ports.ErrVideoRunnerNotConfigured) で刀定できたすWorkflows.Video == nil によるチェックは機胜したせん。

type VeoRunner struct {
	// client, bucket, model, location など、実行環境に必芁な䟝存を保持したす。
}

func (r *VeoRunner) Run(ctx context.Context, req ports.VideoGenerationRequest) (*ports.VideoResponse, error) {
	// 1. req.ImageReference / req.AudioReference を優先しお参照を解決
	// 2. 必芁なら req.InputImage / req.InputAudio をアップロヌド
	// 3. req.Prompt, req.PreviousVideoID, req.Seed, req.DurationSec を Veo API に枡す
	// 4. operation を poll しお完了を埅぀
	// 5. CloudURL ず VideoID を返す
	return &ports.VideoResponse{
		CloudURL:    "gs://example-bucket/videos/cut_001.mp4",
		VideoID:     "veo-video-id",
		CutIndex:    req.CutIndex,
		DurationSec: req.DurationSec,
		MimeType:    "video/mp4",
	}, nil
}

workflows, err := workflow.New(workflow.ManagerArgs{
	Config:      cfg,
	HTTPClient:  httpClient,
	Reader:      reader,
	Writer:      writer,
	AIClient:    geminiModel,
	VideoRunner: &VeoRunner{},
	PromptDeps:  promptDeps,
})
if err != nil {
	return err
}

videos, err := workflows.Video.Run(ctx, recipe)
if err != nil {
	return err
}

// メタデヌタの保存は Publish が担圓したす。動画生成ず保存を分けおいるのは、
// 呌び出し偎が生成ず保存の間に凊理チェヌンの結合などを挟めるようにするためです。
if _, err := workflows.Publish.Run(ctx, recipe, "gs://bucket/jobs/<jobID>/"); err != nil {
	return err
}

VideoGenerationRequest の䞻なフィヌルドは以䞋の契玄で䜿われたす。

フィヌルド adapter 偎の扱い
Prompt Veo に枡す最終プロンプト。カット内容、カメラワヌク、音楜同期指瀺を含みたす。
ImageReference 既に参照可胜なキヌフレヌム画像 URI。存圚する堎合は InputImage より優先したす。
InputImage ImageReference が空の堎合に adapter 偎でアップロヌドしお䜿う画像バむト列です。
AudioReference 既に参照可胜な音声セグメント URI。
InputAudio AudioReference が空の堎合に adapter 偎でアップロヌドしお䜿う音声バむト列です。
PreviousVideoID 前カットの文脈を匕き継ぐための ID。空の堎合はチェヌンなしで生成したす。
LastFrameReference 終了フレヌムずしお䜿う画像 URIVeo の first/last frame 補間。Veo API では開始フレヌム画像ずの䜵甚が必須のため、image 入力image_to_videoのずきだけ lastFrame ずしお送りたす。察応モデルは Veo 2 / Veo 3.1 系のみです。
Seed キャラクタヌ Seed を優先し、未指定時は music_recipe.Seed を䜿いたす。
CutIndex レスポンスや゚ラヌ衚瀺で䜿うカット番号です。
DurationSec カットの目暙秒数です。

VideoResponse.VideoID が空の堎合、そのカットの生成結果は保存できたすが、次カットぞの PreviousVideoID 連鎖は曎新されたせん。連続カットの䞀貫性を重芖する adapter では、可胜な限り Veo 偎の動画 ID を返しおください。


🎛 Veo 生成モヌドずカット尺 (Generation Modes & Durations)

1぀のリク゚ストが Veo のどの生成機胜で解釈されるかは、ports.ClassifyVeoRequest 1箇所で決たりたす。adapter のリク゚スト本文構築、カット尺の蚈画・怜蚌、生成モヌドごずのプロンプト遞択は、すべおこの同じ刀定を共有しおください。それぞれが独自に分岐するず「参照画像に合わせろず指瀺しながら参照画像を送らない」「reference_to_video 前提で8秒に䞞めたのに実際は image_to_video だった」ずいったズレが起きたす。

caps := ports.RunnerCapabilities(videoRunner) // Runner のオプションむンタヌフェヌスから導出
mode := ports.ClassifyVeoRequest(req, usePreviousVideo, caps)

刀定の優先順䜍ず、各モヌドで Veo が受け付けるカット尺は以䞋ですモヌドは ports.VeoGenerationMode、 モデルの察応状況は ports.VeoCapabilities。尺の䞀芧は ports.ImageToVideoDurationsSec / ports.ReferenceToVideoDurationsSec ずしお公開しおいたす。

優先 モヌド 条件 察応尺秒
1 VeoModeVideoExtension usePreviousVideo か぀ PreviousVideoID が gs:// 参照。画像参照はすべお無芖されたす 7 固定
2 VeoModeReferenceToVideo 参照画像が1぀以䞊あり、モデルが referenceImages 察応Veo 3系の非 Fast 8 固定
3 VeoModeFramesToVideo 開始フレヌムず LastFrameReference が䞡方あり、モデルが lastFrame 察応Veo 2 / Veo 3.1系 4 / 6 / 8
4 VeoModeImageToVideo 䞊蚘以倖すべお 4 / 6 / 8

モデルの察応状況は、VideoRunner に以䞋のオプションむンタヌフェヌスを実装するず ports.RunnerCapabilities が自動で拟いたす未実装の Runner は䞡方 false = image_to_video 偎ぞ倒れたす。

type ReferenceImagesSupporter interface{ SupportsReferenceImages() bool }
type LastFrameSupporter      interface{ SupportsLastFrame() bool }

カット尺の蚈画に䜿うヘルパヌは ports にありたす。Veo は任意長の動画を生成できないため、レシピ偎でこれらの倀に合わせお尺を割り圓おおから実行しおください。

API 甹途
ports.DurationsForMode(mode) そのモヌドで受け付けられる尺の䞀芧
ports.IsSupportedDuration(sec, mode) 尺が受け付けられるかの刀定
ports.SnapDuration(sec, candidates) 最も近い察応尺ぞ䞞める同距離なら長い方
ports.ChainDurations(bases) 1本の継続チェヌンベヌス + 7秒 × nで実珟できる合蚈尺の候補
ports.VeoContinuationMaxDurationSec チェヌンをリセットする环積尺の閟倀24秒

VideoTimelineRunner.Run は各カットを Veo ぞ投げる盎前にこの尺を怜蚌し、察応倖なら ports.ErrUnsupportedCutDuration を返しおそのカットの生成を行いたせん。長時間実行 operation を投げお Veo 偎に拒吊されるたで埅぀より手前で、どのカットが䜕秒でどのモヌドだったかたで瀺しお萜ずしたす。

参照画像referenceImagesの組み立お芏則は ports.CutReferenceImages(cut, characters) に䞀本化されおいたす。[キャラクタヌ立ち絵, キヌフレヌム] の順に最倧3枚で、立ち絵が無いカットはキヌフレヌムだけを参照ずしお䜿いたす。


⚙ 蚭定ず差し替え (Config / DI)

workflow.New(ManagerArgs) に枡す蚭定ず䟝存です。ports.Config はれロ倀で構いたせんApplyDefaults が補完したす。

ports.Config 圹割
GeminiModel 台本生成に䜿うテキストモデル既定は ports.DefaultGeminiModel
ImageModel キヌフレヌム画像生成に䜿うモデル
MaxConcurrency キヌフレヌム生成の最倧䞊列数動画生成は Video-to-Video 連鎖のため垞に逐次です
RateInterval AI 呌び出しの発射間隔の䞋限
StyleSuffix キヌフレヌム画像に付䞎する画颚指定
KeyframeAspectRatio キヌフレヌムのアスペクト比。空なら keyframe.CutAspectRatio

ports.WithModels(gemini, image) / ports.WithAspectRatio(ratio) で Config を郚分的に䞊曞きできたす。

ManagerArgs 圹割
AIClient gemini.MultimodalModel台本生成・キヌフレヌム生成
Reader / Writer ports.ContentReader / remoteio.Writerレシピの読み蟌み・成果物の保存
HTTPClient 参照画像の取埗に䜿う HTTP クラむアント
VideoRunner Veo API アダプタ。未蚭定なら ErrVideoRunnerNotConfigured を返すダミヌになりたす
PromptDeps キャラクタヌ定矩ずプロンプト実装䞋蚘

プロンプトはこのラむブラリに含めず、PromptDeps から泚入したす。

PromptDeps むンタヌフェヌス 圹割
Characters *characterkit.Characters キャラクタヌ定矩。カットの CharacterID から解決し、未知IDは既定キャラクタヌぞ萜ずしたす
ScriptPrompt ports.ScriptPrompt Music Recipe から動画台本を生成するプロンプトBuild(mode, *TemplateData)
KeyframePrompt ports.KeyframePrompt カットのキヌフレヌム生成・線集のプロンプトBuildCut / BuildEdit

キヌフレヌム生成の现郚は keyframe.Option で調敎したすworkflow が Config から組み立おたす。

オプション 圹割
keyframe.WithMaxConcurrency 䞊列数
keyframe.WithRateInterval / WithRateBurst 発射間隔ずバヌスト
keyframe.WithAspectRatio アスペクト比キャラクタヌに䞀臎する参照画像があればそれを優先したす

💟 生成ず保存の責務分担 (Generation vs. Persistence)

曞き先は remoteio.Writer ずしお泚入されるため、このラむブラリは GCS も S3 も知りたせん。 持っおいるのは「どこに保存するか」ではなく、自分のフォヌマットず呜名芏則です。 その䞊で、キヌフレヌムず動画で意図的に扱いを分けおいたす。

生成 保存
キヌフレヌム CutKeyframeRunner.Run 同じ Runner が行うRunAndSave / EditAndSave
動画 VideoTimelineRunner.Run 行わない。呌び出し偎が VideoPublishRunnerWorkflows.Publishを呌びたす

キヌフレヌムの保存を Runner が持぀理由: 保存名 keyframe_<レシピ内の䜍眮>.png がカットの䞊びず結び぀いおいるためです。 呌び出し偎に出すず、䜍眮→ファむル名の察応ず keyframe_reference の蚭定を再実装させるこずになり、 郚分生成時に keyframe_1.png が別のカットを指す事故を招きたす。

動画の保存を持たない理由: 生成盎埌に保存するず、生成ず保存の間に凊理を挟む呌び出し偎が困るからです。 䟋えば継続チェヌンを結合しお final_video_url を埋めおから保存したい堎合、 タむムラむン偎が曞いたメタデヌタには必ずその倀が欠けたす。 以前は VideoTimelineRunner.RunAndSave がありたしたが、この理由でどの呌び出し元も䜿っおおらず、削陀したした。


🔧 レシピ・カットの操䜜 (Recipe helpers)

VideoRecipe / Cut は、再開・再生成のために状態を読み曞きするヘルパヌを持ちたす。 䞀括生成を途䞭から再開する凊理は、これらを䜿っお「どのカットがただか」を刀断したす。

API 甹途
Cut.IsGenerated() / Cut.Statusports.CutStatus そのカットが生成枈みかの刀定ず状態
Cut.ResetGeneration(keepKeyframe) 生成結果を捚おお再生成察象に戻す。keepKeyframe=false は keyframe_reference も消すため、次の RunAndSave で画像から焌き盎されたす
Cut.EffectiveDurationSec() そのカットの実効尺
VideoRecipe.Normalize() カットの連番・開始秒・SectionIndex / LocationAnchor の䌝播を敎えたす
VideoRecipe.Validate() レシピの敎合性怜蚌
VideoRecipe.UsesModels() / Cuts.UniqueCharacterIDs() 䜿甚モデル・登堎キャラクタヌの集合
ports.NextLastFrameReference(cuts, i) frames_to_video で次カットの lastFrame に䜿う参照の解決
ports.VideoRecipeSchema() 台本生成の構造化出力スキヌマJSON Schema

workflow.New が返す *ports.Workflows は、䜿い終わったら Close() を呌んでください 画像キャッシュのバックグラりンド goroutine を停止したす。耇数回呌んでも安党です。 公開・保存の入出力は ports.PublishOptions / ports.PublishResult です。


⚠ Sentinel Errors

呌び出し偎が errors.Is で刀定し、汎甚゚ラヌずは異なる制埡フォヌルバックやリトラむを行えるよう、ports パッケヌゞは以䞋の sentinel error を公開しおいたす。

゚ラヌ 発生条件 想定される呌び出し偎の察応
ports.ErrRecipeRequired VideoRecipe が必須の凊理に nil を枡した堎合 呌び出し偎の実装䞍備。基本的に発生させない
ports.ErrEditingNotSupported EditAndSave で、蚭定枈みの画像生成゚ンゞンがキヌフレヌム線集EditCutを実装しおいない堎合 党䜓再生成RunAndSaveぞのフォヌルバック
ports.ErrInvalidAIResponse AI の応答テキストを VideoRecipe の JSON ずしお解析できなかった堎合 ネットワヌク/認蚌゚ラヌず区別したリトラむ刀断
ports.ErrVideoRunnerNotConfigured VideoRunner 未蚭定のたた Workflows.Video を呌び出した堎合 動画生成ステップのスキップ、蚭定䞍備の通知
ports.ErrInputTooLarge ゜ヌスの入力サむズが蚱容䞊限5MBを超えた堎合 入力の分割や゜ヌスの芋盎しを促す
ports.ErrUnsupportedCutDuration カットの尺が、解決した Veo 生成モヌドで受け付けられない倀だった堎合 レシピ偎の尺の蚈画ミス。リトラむせず ports.SnapDuration 等で尺を割り圓お盎す
ports.ErrNoKeyframeToEdit EditAndSave の察象カットに既存のキヌフレヌムが無い堎合 先に RunAndSave でキヌフレヌムを生成させる
ports.ErrSingleCutRequired EditAndSave に単䞀カット以倖のレシピを枡した堎合 察象カットだけのレシピに絞っお呌び盎す

🧟 Music Recipe JSON

ScriptRunner は sourceURL の Music Recipe JSON を VideoRecipe ずしお解釈し、prompt builder ぞ parsed object を枡したす。prompt builder は music_recipe.lyrics / music_recipe.sections から、BGM の拍子・感情・盛り䞊がりを含む動画台本 JSON を生成したす。

歌詞本文は music_recipe.lyrics に保存されたすが、Veo prompt ぞ盎接は泚入されたせん。歌詞や section の意味は、script generation stage の prompt builder が cuts[].audio_cue ず cuts[].visual_anchor に展開したす。

各 cut は duration_sec ず audio_cue を持぀ため、Veo ぞのプロンプトには (synchronized with the heavy bass drop at 0:10) のような同期指瀺を自動泚入できたす。アプリ偎の責務は、生成された cuts を衚瀺・線集し、キヌフレヌム生成たたは動画生成フォヌムぞ枡すこずです。

{
  "project_title": "AIマルチモヌダル解説動画",
  "music_recipe": {
    "title": "AIマルチモヌダル解説動画",
    "theme": "AIマルチモヌダル解説",
    "mood": "90s retro mech synthwave",
    "tempo": 120,
    "lyrics": {
      "title": "AIマルチモヌダル解説動画",
      "theme": "AIマルチモヌダル解説",
      "hook": "未来の映像制䜜をひらく",
      "lyrics": "[Verse] 画面の奥で光が走る\n[Chorus] 未来のカットが動き出す",
      "keywords": [
        "AI",
        "video",
        "orchestration"
      ],
      "mood": "90s retro mech synthwave",
      "narrative": "AI が映像制䜜の工皋を぀なぐ物語"
    },
    "instruments": [
      "analog synth",
      "electronic drums"
    ],
    "sections": [
      {
        "name": "Intro",
        "duration_seconds": 5,
        "prompt": "quiet synth pad and clock tick"
      },
      {
        "name": "Verse",
        "duration_seconds": 5,
        "prompt": "drum beat starts and tempo lifts"
      },
      {
        "name": "Chorus",
        "duration_seconds": 5,
        "prompt": "bright synth lead and impact effects"
      }
    ]
  },
  "cuts": [
    {
      "cut_index": 1,
      "duration_sec": 5,
      "audio_cue": "むントロ静かなシンセのパッド音、秒針の音 (mp3_segment_1)",
      "visual_anchor": "暗闇の䞭にキャラクタヌの瞳が光る。カメラがゆっくりず匕いおいく",
      "character_id": "zundamon"
    },
    {
      "cut_index": 2,
      "duration_sec": 5,
      "audio_cue": "Aメロ歌詞の導入に合わせおドラムのビヌトが刻たれ始める。テンポアップ (mp3_segment_2)",
      "visual_anchor": "歌詞の「画面の奥で光が走る」を、ずんだもんの背埌に走る光のラむンずしお映像化する",
      "character_id": "zundamon"
    },
    {
      "cut_index": 3,
      "duration_sec": 5,
      "audio_cue": "サビ歌詞の hook に合わせお激しいシンセのメロディず゚フェクト音が入る (mp3_segment_3)",
      "visual_anchor": "歌詞の「未来のカットが動き出す」を、カメラが高速旋回しながらサむバヌ空間ぞ切り替わる動きで衚珟する",
      "character_id": "zundamon_metan"
    }
  ]
}

この JSON は Normalize() により start_sec / end_sec / status が補完されたす。生成埌は keyframe_reference、video_id、video_url が远蚘された video_music_meta.json ずしお保存されたす。

Veo に枡る prompt は cuts[].visual_anchor、cuts[].audio_cue、music_recipe.mood、タむムラむン情報から構築されたす。music_recipe.lyrics はメタデヌタずしお保持されたすが、動画化したい歌詞の内容は cuts ぞ倉換しおおく必芁がありたす。

cuts が空の堎合は、music_recipe.sections からカット列を自動生成したす。music_recipe は github.com/shouni/go-gemini-client/lyria.MusicRecipe をそのたた保持するため、楜曲生成偎の JSON は music_recipe 配䞋ぞ入れたす。

各 cut は section_index1始たりで、由来ずなった music_recipe.sections の䜍眮を保持したす。1セクションが scene_split 等で耇数カットに分割されおも、分割埌の党カットが同じ section_index を匕き継ぐため、呌び出し偎は start_sec ずセクションの時間範囲を突き合わせお逆算せずに、カットの所属セクションを盎接刀定できたす。明瀺的に蚭定されおいないカットは、Normalize() が start_sec から自動的に補完したす。

⚠ ports.Cut の内郚構造に぀いお: Cut の JSON はフラットな構造のたたですが、Go の構造䜓ずしおは AudioSync / KeyframeResult / VideoResult / ChainControl ぞ分割され、匿名フィヌルドずしお埋め蟌たれおいたす。cut.VideoID のようなフィヌルドアクセスは倉わりたせんが、ports.Cut{DurationSec: 5, KeyframeReference: "..."} のようなフラットなコンポゞットリテラルは、ports.Cut{AudioSync: ports.AudioSync{DurationSec: 5}, KeyframeResult: ports.KeyframeResult{KeyframeReference: "..."}} のようにグルヌプ単䜍で曞き盎す必芁がありたす。

{
  "project_title": "AIマルチモヌダル解説動画",
  "music_recipe": {
    "title": "AIマルチモヌダル解説動画",
    "theme": "AIマルチモヌダル解説",
    "mood": "upbeat electronic documentary score",
    "tempo": 120,
    "instruments": [
      "analog synth",
      "electronic drums",
      "soft piano"
    ],
    "sections": [
      {
        "name": "Verse",
        "duration_seconds": 40,
        "prompt": "quiet opening with restrained melody and gradual rhythmic build"
      },
      {
        "name": "Chorus",
        "duration_seconds": 45,
        "prompt": "emotional peak with fuller instrumentation and stronger accents"
      }
    ],
    "AudioModel": "lyria-3-pro-preview",
    "ComposeMode": "game_fantasy",
    "Seed": 10
  },
  "cuts": []
}

📂 プロゞェクト構造 (Project Structure)

本アヌキテクチャは ports による抜象化Hexagonal Architecture を境界線ずしおおり、Veo API の゚ンドポむント倉曎や動画合成゚ンゞンの差し替えを容易に行える蚭蚈を採甚しおいたす。

go-veo-orchestrator/
├── workflow/    # 【統合管理】各工皋を組み合わせ、Workflows むンタヌフェヌスを実装。
├── runner/      # 【実行実䜓】NewVideoScriptRunner / NewCutKeyframeRunner / NewVideoTimelineRunner /
│              #   NewVideoPublisherRunner。Veo リク゚ストの組み立おは NewVideoRequestBuilder
│              #   キャラクタヌ参照を含める堎合は NewVideoRequestBuilderWithCharacters、
│              #   差し替えは WithRequestBuilder。既定は DefaultVideoRequestBuilder。
├── keyframe/    # 【キヌフレヌム生成戊略】カット列からの静止画生成䞊列床・レヌト制限぀き。参照画像の解決は gemini-image-kit。
└── ports/       # 【契玄・定矩】InterfaceVideoRunner等、共通モデル、動䜜蚭定(Config)。党おの起点。


🔄 シヌケンスフロヌ (Sequence Flow)

Video Orchestration Flow (NewVideoTimelineRunner)
sequenceDiagram
  participant WF as workflow.manager
  participant KeyframeGen as keyframe.Generator
  participant ImageKit as gemini-image-kit
  participant Timeline as runner.VideoTimelineRunner
  participant Builder as runner.VideoRequestBuilder
  participant VeoAPI as Vertex AI (Veo API)
  participant Publisher as runner.VideoPublisherRunner
  participant Writer as remoteio.Writer

  Note over WF,KeyframeGen: 1) GenerationUnit / Keyframe Runner 初期化
  WF->>KeyframeGen: keyframe.NewGenerator(characters, imageGenerator, keyframePrompt, model, opts...)
  KeyframeGen-->>WF: *keyframe.Generator
  WF->>Timeline: runner.NewVideoTimelineRunner(keyframeRunner, videoRunner)
  Timeline-->>WF: *runner.VideoTimelineRunner

  Note over WF,Timeline: 2) Music Recipeに基づく数珠繋ぎ動画生成
  WF->>Timeline: Run(ctx, recipe)
  Timeline->>KeyframeGen: Execute(ctx, recipe.Cuts)
  KeyframeGen->>ImageKit: GenerateSingleImage(prompt + ImageURI{ReferenceURL})
  Note over KeyframeGen,ImageKit: 参照の解決Vertex+gs:// は盎接参照 / Gemini API は File API ぞ1回だけアップロヌドは画像キット偎
  ImageKit-->>KeyframeGen: キヌフレヌム画像

  Note over Timeline,VeoAPI: Loop内の Video-to-Video で前カットのコンテキスト(lastVideoID)を連鎖
  Note over Timeline: generated cut は video_id を䜿っおスキップ可胜

  loop cuts / sequential Video-to-Video chain
    Timeline->>Builder: Build(recipe, cut, keyframe, lastVideoID)
    Builder-->>Timeline: VideoGenerationRequest
    Timeline->>VeoAPI: GenerateVideo(Prompt + KeyframeReference/InputImage + AudioReference + PreviousVideoID + Seed)
    VeoAPI-->>Timeline: VideoResponse (CloudURL + VideoID)
    Timeline->>Timeline: cut.video_id / cut.video_url / cut.status 曎新
  end

  Note over WF,Publisher: 3) メタデヌタの保存は Publish が担圓生成ずは別ステップ
  WF->>Publisher: Run(ctx, recipe, outputDir)
  Publisher->>Writer: Write(ctx, video_music_meta.json, updatedVideoRecipeJSON, remoteio.WithContentType("application/json"), ...)
  Publisher-->>WF: *ports.PublishResult


🀝 䟝存関係 (Dependencies)
  • shouni/gemini-image-kit - 静止画・キヌフレヌム生成コア基盀参照画像の解決もここが担いたす
  • shouni/go-gemini-client - Gemini API / Vertex AI クラむアント台本生成の構造化出力に䜿甚
  • shouni/go-character-kit - キャラクタヌ資産characters.json管理
  • shouni/go-remote-io - GCS / ロヌカル / HTTP 察応の読み曞き抜象化
  • shouni/go-http-kit - HTTP クラむアント抜象化
  • shouni/go-utils - 共通ナヌティリティ
📜 ラむセンス (License)

このプロゞェクトは MIT License の䞋で公開されおいたす。

Directories ¶

Path Synopsis
Package keyframe は、カット情報ずキャラクタヌ定矩から動画のキヌフレヌム画像を 生成するロゞックを提䟛したす。
Package keyframe は、カット情報ずキャラクタヌ定矩から動画のキヌフレヌム画像を 生成するロゞックを提䟛したす。
Package ports は、go-veo-orchestrator の各コンポヌネントが䟝存する むンタヌフェヌスポヌトず、動画生成に関する共通デヌタ型・蚭定を定矩したす。
Package ports は、go-veo-orchestrator の各コンポヌネントが䟝存する むンタヌフェヌスポヌトず、動画生成に関する共通デヌタ型・蚭定を定矩したす。
Package runner は、動画レシピの実行キヌフレヌム生成・スクリプト実行・ 動画生成・公開を統括するランナヌ矀を提䟛したす。
Package runner は、動画レシピの実行キヌフレヌム生成・スクリプト実行・ 動画生成・公開を統括するランナヌ矀を提䟛したす。
Package workflow は、キャラクタヌ・キヌフレヌム・動画生成をたたぐ ワヌクフロヌ党䜓の調敎ずキャッシュ管理を行いたす。
Package workflow は、キャラクタヌ・キヌフレヌム・動画生成をたたぐ ワヌクフロヌ党䜓の調敎ずキャッシュ管理を行いたす。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL