feat: veo3.1 拆分 fast/standard, seedance双模型, per_second定价, 子号过滤, 随机种子, UI优化

This commit is contained in:
2026-08-03 20:27:20 +08:00
parent e90aeecea3
commit 7f4701d362
8 changed files with 238 additions and 77 deletions
+50 -13
View File
@@ -2,8 +2,8 @@ package adobe
import (
"encoding/json"
"math/rand"
"strings"
"time"
)
type modelSpec struct {
@@ -68,7 +68,7 @@ func ResolveModelSpec(modelID string) modelSpec {
func buildImage5Payload(prompt, aspectRatio, resolution string, blobIDs []string) map[string]any {
p := map[string]any{
"n": 1,
"seeds": []int{int(time.Now().Unix()) % 999999},
"seeds": []int{rand.Intn(999999)},
"output": map[string]any{"storeInputs": true},
"prompt": prompt,
"referenceBlobs": []any{},
@@ -125,7 +125,7 @@ func buildGPTImagePayloads(spec modelSpec, prompt, ratio, resolution string, blo
"modelVersion": spec.UpstreamModelVersion,
"n": 1,
"prompt": prompt,
"seeds": []int{int(time.Now().Unix()) % 999999},
"seeds": []int{rand.Intn(999999)},
"output": map[string]any{"storeInputs": true},
"referenceBlobs": []any{},
"generationMetadata": map[string]any{"module": "text2image", "submodule": "ff-image-generate"},
@@ -151,7 +151,7 @@ func buildFluxPayloads(spec modelSpec, prompt, ratio string, blobIDs []string) [
"n": 1,
"prompt": prompt,
"size": map[string]any{"width": size[0], "height": size[1]},
"seeds": []int{int(time.Now().Unix()) % 999999},
"seeds": []int{rand.Intn(999999)},
"output": map[string]any{"storeInputs": true},
"referenceBlobs": []any{},
"modelSpecificPayload": map[string]any{
@@ -182,7 +182,7 @@ func buildDefaultPayloads(spec modelSpec, prompt, ratio, resolution string, blob
"n": 1,
"prompt": prompt,
"size": map[string]any{"width": size[0], "height": size[1]},
"seeds": []int{int(time.Now().Unix()) % 999999},
"seeds": []int{rand.Intn(999999)},
"groundSearch": false,
"output": map[string]any{"storeInputs": true},
"generationMetadata": map[string]any{
@@ -252,7 +252,7 @@ func cloneMap(in map[string]any) map[string]any {
}
func BuildVideoPayload(engine, prompt, aspectRatio string, durationSeconds int, resolution, referenceMode, upstreamModel string, blobIDs []string) map[string]any {
seedVal := int(time.Now().Unix()) % 999999
seedVal := rand.Intn(999999)
engine = defaultString(engine, "sora2")
resolution = defaultString(resolution, "720p")
aspectRatio = defaultString(aspectRatio, "16:9")
@@ -299,9 +299,6 @@ func BuildVideoPayload(engine, prompt, aspectRatio string, durationSeconds int,
if engine == "veo31-standard" {
modelVersion = "3.1-generate"
}
// Shape mirrors a captured working firefly.adobe.com video request: flat
// top-level duration / negativePrompt / generateAudio, submodule set, and
// NO `n` / NO modelSpecificPayload (sending those got 403).
payload := map[string]any{
"modelId": "veo",
"modelVersion": modelVersion,
@@ -310,7 +307,7 @@ func BuildVideoPayload(engine, prompt, aspectRatio string, durationSeconds int,
"prompt": prompt,
"negativePrompt": "",
"duration": durationSeconds,
"generateAudio": false,
"generateAudio": true,
"generationMetadata": map[string]any{
"module": "text2video",
"submodule": "ff-video-generate",
@@ -320,9 +317,49 @@ func BuildVideoPayload(engine, prompt, aspectRatio string, durationSeconds int,
}
if len(blobIDs) > 0 {
payload["generationMetadata"] = map[string]any{"module": "image2video", "submodule": "ff-video-generate"}
refs := make([]any, 0, min(len(blobIDs), 2))
for idx, id := range blobIDs[:min(len(blobIDs), 2)] {
refs = append(refs, map[string]any{"id": id, "usage": "general", "promptReference": idx + 1})
refs := make([]any, 0, min(len(blobIDs), 3))
if referenceMode == "frame" {
for idx, id := range blobIDs[:min(len(blobIDs), 3)] {
refs = append(refs, map[string]any{"id": id, "usage": "frame", "order": idx + 1})
}
} else {
for _, id := range blobIDs[:min(len(blobIDs), 3)] {
refs = append(refs, map[string]any{"id": id, "usage": "asset"})
}
}
payload["referenceBlobs"] = refs
}
return payload
case "seedance-fast", "seedance-2.0":
modelVersion := "seedance_2.0"
if engine == "seedance-fast" {
modelVersion = "seedance_2.0_fast"
}
payload := map[string]any{
"modelId": "seedance",
"modelVersion": modelVersion,
"size": videoSize(aspectRatio, resolution),
"seeds": []int{seedVal},
"prompt": prompt,
"negativePrompt": "",
"duration": durationSeconds,
"generateAudio": true,
"generationSettings": map[string]any{"aspectRatio": aspectRatio},
"generationMetadata": map[string]any{"module": "text2video", "submodule": "ff-video-generate"},
"output": map[string]any{"storeInputs": true},
"referenceBlobs": []any{},
}
if len(blobIDs) > 0 {
payload["generationMetadata"] = map[string]any{"module": "image2video", "submodule": "ff-video-generate"}
refs := make([]any, 0, min(len(blobIDs), 9))
if referenceMode == "frame" {
for idx, id := range blobIDs[:min(len(blobIDs), 9)] {
refs = append(refs, map[string]any{"id": id, "usage": "frame", "order": idx + 1})
}
} else {
for _, id := range blobIDs[:min(len(blobIDs), 9)] {
refs = append(refs, map[string]any{"id": id, "usage": "asset"})
}
}
payload["referenceBlobs"] = refs
}