fix(media): 媒体恢复 - 保留音频多结果并兼容单数响应

This commit is contained in:
ddcat666
2026-09-30 14:38:40 +08:00
parent b080674524
commit 4c0aa682a5
2 changed files with 38 additions and 3 deletions

View File

@@ -110,9 +110,6 @@ func recoverProtocolMedia(ctx context.Context, config providerConfig, mode strin
if len(references) == 0 || len(references) > 32 {
return nil, true, &mediaRecoveryError{stage: "checkpoint", cause: errors.New("生成结果数量超过恢复限制")}
}
if mode != "image" {
references = references[:1]
}
if task.MediaRecoveryJSON != "" {
result, err := s.resumeTaskMedia(ctx, task)
return result, true, err
@@ -246,6 +243,10 @@ func (s *Service) materializeTaskMedia(ctx context.Context, task *model.Task, co
result = map[string]interface{}{"mode": checkpoint.Mode}
if checkpoint.Mode == "image" {
result["images"] = items
} else if checkpoint.Mode == "audio" {
result["audios"] = items
// Keep the legacy singular field for clients that render one audio result.
result["audio"] = items[0]
} else {
result[checkpoint.Mode] = items[0]
}

View File

@@ -409,3 +409,37 @@ func TestMediaRecoveryExpiredLeaseAndStagingLimits(t *testing.T) {
t.Fatal("staging budget exceeded")
}
}
func TestMediaRecoveryAudioKeepsAllReturnedResults(t *testing.T) {
t.Setenv("CANVAS_ALLOWED_PRIVATE_UPSTREAM_HOSTS", "127.0.0.1")
s, db := newMediaRecoveryTestService(t)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "audio/mpeg")
_, _ = w.Write([]byte("audio-result"))
}))
defer server.Close()
expires := time.Now().Add(time.Hour)
input, err := json.Marshal(canvasGenerationInput{Mode: "audio", Config: providerConfig{BaseURL: server.URL}, Prompt: "test"})
if err != nil {
t.Fatal(err)
}
task := &model.Task{ID: newID(), UserID: "media-user", Type: "canvas_audio", Status: model.TaskStatusRunning, InputJSON: string(input), LeaseOwner: "worker-a", LeaseExpiresAt: &expires, RouteRun: 1, CreatedAt: time.Now()}
if err := db.Create(task).Error; err != nil {
t.Fatal(err)
}
ctx := context.WithValue(withProviderAnalytics(context.Background(), s, *task), mediaExecutionTaskKey{}, *task)
result, handled, recoveryErr := recoverProtocolMedia(ctx, providerConfig{BaseURL: server.URL}, "audio", []protocol.MediaReference{
{URL: server.URL + "/voice.wav", MIMEType: "audio/mpeg"},
{URL: server.URL + "/emotion.wav", MIMEType: "audio/mpeg"},
})
if !handled || recoveryErr != nil {
t.Fatalf("handled=%v err=%v", handled, recoveryErr)
}
audios, ok := result["audios"].([]interface{})
if !ok || len(audios) != 2 {
t.Fatalf("audios=%#v result=%#v", result["audios"], result)
}
if _, ok := result["audio"]; !ok {
t.Fatal("legacy singular audio result missing")
}
}