Merge pull request #2018 from feitianbubu/pr/add-jimeng-vidu-openai-sdk
即梦和vidu支持 OpenAI sdk生成和查询视频
This commit is contained in:
commit
5feb22d8fb
@ -11,6 +11,23 @@ import (
|
|||||||
|
|
||||||
type TaskStatus string
|
type TaskStatus string
|
||||||
|
|
||||||
|
func (t TaskStatus) ToVideoStatus() string {
|
||||||
|
var status string
|
||||||
|
switch t {
|
||||||
|
case TaskStatusQueued, TaskStatusSubmitted:
|
||||||
|
status = commonRelay.VideoStatusQueued
|
||||||
|
case TaskStatusInProgress:
|
||||||
|
status = commonRelay.VideoStatusInProgress
|
||||||
|
case TaskStatusSuccess:
|
||||||
|
status = commonRelay.VideoStatusCompleted
|
||||||
|
case TaskStatusFailure:
|
||||||
|
status = commonRelay.VideoStatusFailed
|
||||||
|
default:
|
||||||
|
status = commonRelay.VideoStatusUnknown // Default fallback
|
||||||
|
}
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TaskStatusNotStart TaskStatus = "NOT_START"
|
TaskStatusNotStart TaskStatus = "NOT_START"
|
||||||
TaskStatusSubmitted = "SUBMITTED"
|
TaskStatusSubmitted = "SUBMITTED"
|
||||||
|
|||||||
@ -158,7 +158,12 @@ func (a *TaskAdaptor) DoResponse(c *gin.Context, resp *http.Response, info *rela
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"task_id": jResp.Data.TaskID})
|
ov := relaycommon.NewOpenAIVideo()
|
||||||
|
ov.ID = jResp.Data.TaskID
|
||||||
|
ov.TaskID = jResp.Data.TaskID
|
||||||
|
ov.CreatedAt = time.Now().Unix()
|
||||||
|
ov.Model = info.OriginModelName
|
||||||
|
c.JSON(http.StatusOK, ov)
|
||||||
return jResp.Data.TaskID, responseBody, nil
|
return jResp.Data.TaskID, responseBody, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +405,30 @@ func (a *TaskAdaptor) ParseTaskResult(respBody []byte) (*relaycommon.TaskInfo, e
|
|||||||
return &taskResult, nil
|
return &taskResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *TaskAdaptor) ConvertToOpenAIVideo(originTask *model.Task) (*relaycommon.OpenAIVideo, error) {
|
||||||
|
var jimengResp responseTask
|
||||||
|
if err := json.Unmarshal(originTask.Data, &jimengResp); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unmarshal jimeng task data failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
openAIVideo := relaycommon.NewOpenAIVideo()
|
||||||
|
openAIVideo.ID = originTask.TaskID
|
||||||
|
openAIVideo.Status = originTask.Status.ToVideoStatus()
|
||||||
|
openAIVideo.SetProgressStr(originTask.Progress)
|
||||||
|
openAIVideo.SetMetadata("url", jimengResp.Data.VideoUrl)
|
||||||
|
openAIVideo.CreatedAt = originTask.CreatedAt
|
||||||
|
openAIVideo.CompletedAt = originTask.UpdatedAt
|
||||||
|
|
||||||
|
if jimengResp.Code != 10000 {
|
||||||
|
openAIVideo.Error = &relaycommon.OpenAIVideoError{
|
||||||
|
Message: jimengResp.Message,
|
||||||
|
Code: fmt.Sprintf("%d", jimengResp.Code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return openAIVideo, nil
|
||||||
|
}
|
||||||
|
|
||||||
func isNewAPIRelay(apiKey string) bool {
|
func isNewAPIRelay(apiKey string) bool {
|
||||||
return strings.HasPrefix(apiKey, "sk-")
|
return strings.HasPrefix(apiKey, "sk-")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,13 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/QuantumNous/new-api/model"
|
"github.com/QuantumNous/new-api/model"
|
||||||
|
|
||||||
"github.com/bytedance/gopkg/util/logger"
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -190,8 +188,12 @@ func (a *TaskAdaptor) DoResponse(c *gin.Context, resp *http.Response, info *rela
|
|||||||
taskErr = service.TaskErrorWrapperLocal(fmt.Errorf(kResp.Message), "task_failed", http.StatusBadRequest)
|
taskErr = service.TaskErrorWrapperLocal(fmt.Errorf(kResp.Message), "task_failed", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kResp.TaskId = kResp.Data.TaskId
|
ov := relaycommon.NewOpenAIVideo()
|
||||||
c.JSON(http.StatusOK, kResp)
|
ov.ID = kResp.Data.TaskId
|
||||||
|
ov.TaskID = kResp.Data.TaskId
|
||||||
|
ov.CreatedAt = time.Now().Unix()
|
||||||
|
ov.Model = info.OriginModelName
|
||||||
|
c.JSON(http.StatusOK, ov)
|
||||||
return kResp.Data.TaskId, responseBody, nil
|
return kResp.Data.TaskId, responseBody, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,31 +373,17 @@ func (a *TaskAdaptor) ConvertToOpenAIVideo(originTask *model.Task) (*relaycommon
|
|||||||
return nil, errors.Wrap(err, "unmarshal kling task data failed")
|
return nil, errors.Wrap(err, "unmarshal kling task data failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
convertProgress := func(progress string) int {
|
openAIVideo := relaycommon.NewOpenAIVideo()
|
||||||
progress = strings.TrimSuffix(progress, "%")
|
openAIVideo.ID = originTask.TaskID
|
||||||
p, err := strconv.Atoi(progress)
|
openAIVideo.Status = originTask.Status.ToVideoStatus()
|
||||||
if err != nil {
|
openAIVideo.SetProgressStr(originTask.Progress)
|
||||||
logger.Warnf("convert progress failed, progress: %s, err: %v", progress, err)
|
openAIVideo.CreatedAt = klingResp.Data.CreatedAt
|
||||||
}
|
openAIVideo.CompletedAt = klingResp.Data.UpdatedAt
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
openAIVideo := &relaycommon.OpenAIVideo{
|
|
||||||
ID: klingResp.Data.TaskId,
|
|
||||||
Object: "video",
|
|
||||||
//Model: "kling-v1", //todo save model
|
|
||||||
Status: string(originTask.Status),
|
|
||||||
CreatedAt: klingResp.Data.CreatedAt,
|
|
||||||
CompletedAt: klingResp.Data.UpdatedAt,
|
|
||||||
Metadata: make(map[string]any),
|
|
||||||
Progress: convertProgress(originTask.Progress),
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理视频 URL
|
|
||||||
if len(klingResp.Data.TaskResult.Videos) > 0 {
|
if len(klingResp.Data.TaskResult.Videos) > 0 {
|
||||||
video := klingResp.Data.TaskResult.Videos[0]
|
video := klingResp.Data.TaskResult.Videos[0]
|
||||||
if video.Url != "" {
|
if video.Url != "" {
|
||||||
openAIVideo.Metadata["url"] = video.Url
|
openAIVideo.SetMetadata("url", video.Url)
|
||||||
}
|
}
|
||||||
if video.Duration != "" {
|
if video.Duration != "" {
|
||||||
openAIVideo.Seconds = video.Duration
|
openAIVideo.Seconds = video.Duration
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ func (a *TaskAdaptor) DoRequest(c *gin.Context, info *relaycommon.RelayInfo, req
|
|||||||
return channel.DoTaskApiRequest(a, c, info, requestBody)
|
return channel.DoTaskApiRequest(a, c, info, requestBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *TaskAdaptor) DoResponse(c *gin.Context, resp *http.Response, _ *relaycommon.RelayInfo) (taskID string, taskData []byte, taskErr *dto.TaskError) {
|
func (a *TaskAdaptor) DoResponse(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) (taskID string, taskData []byte, taskErr *dto.TaskError) {
|
||||||
responseBody, err := io.ReadAll(resp.Body)
|
responseBody, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
taskErr = service.TaskErrorWrapper(err, "read_response_body_failed", http.StatusInternalServerError)
|
taskErr = service.TaskErrorWrapper(err, "read_response_body_failed", http.StatusInternalServerError)
|
||||||
@ -154,7 +155,12 @@ func (a *TaskAdaptor) DoResponse(c *gin.Context, resp *http.Response, _ *relayco
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(http.StatusOK, vResp)
|
ov := relaycommon.NewOpenAIVideo()
|
||||||
|
ov.ID = vResp.TaskId
|
||||||
|
ov.TaskID = vResp.TaskId
|
||||||
|
ov.CreatedAt = time.Now().Unix()
|
||||||
|
ov.Model = info.OriginModelName
|
||||||
|
c.JSON(http.StatusOK, ov)
|
||||||
return vResp.TaskId, responseBody, nil
|
return vResp.TaskId, responseBody, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,3 +262,30 @@ func (a *TaskAdaptor) ParseTaskResult(respBody []byte) (*relaycommon.TaskInfo, e
|
|||||||
|
|
||||||
return taskInfo, nil
|
return taskInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *TaskAdaptor) ConvertToOpenAIVideo(originTask *model.Task) (*relaycommon.OpenAIVideo, error) {
|
||||||
|
var viduResp taskResultResponse
|
||||||
|
if err := json.Unmarshal(originTask.Data, &viduResp); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "unmarshal vidu task data failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
openAIVideo := relaycommon.NewOpenAIVideo()
|
||||||
|
openAIVideo.ID = originTask.TaskID
|
||||||
|
openAIVideo.Status = originTask.Status.ToVideoStatus()
|
||||||
|
openAIVideo.SetProgressStr(originTask.Progress)
|
||||||
|
openAIVideo.CreatedAt = originTask.CreatedAt
|
||||||
|
openAIVideo.CompletedAt = originTask.UpdatedAt
|
||||||
|
|
||||||
|
if len(viduResp.Creations) > 0 && viduResp.Creations[0].URL != "" {
|
||||||
|
openAIVideo.SetMetadata("url", viduResp.Creations[0].URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if viduResp.State == "failed" && viduResp.ErrCode != "" {
|
||||||
|
openAIVideo.Error = &relaycommon.OpenAIVideoError{
|
||||||
|
Message: viduResp.ErrCode,
|
||||||
|
Code: viduResp.ErrCode,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return openAIVideo, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -551,24 +551,3 @@ func RemoveDisabledFields(jsonData []byte, channelOtherSettings dto.ChannelOther
|
|||||||
}
|
}
|
||||||
return jsonDataAfter, nil
|
return jsonDataAfter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type OpenAIVideo struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
TaskID string `json:"task_id,omitempty"` //兼容旧接口 待废弃
|
|
||||||
Object string `json:"object"`
|
|
||||||
Model string `json:"model"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
Progress int `json:"progress"`
|
|
||||||
CreatedAt int64 `json:"created_at"`
|
|
||||||
CompletedAt int64 `json:"completed_at,omitempty"`
|
|
||||||
ExpiresAt int64 `json:"expires_at,omitempty"`
|
|
||||||
Seconds string `json:"seconds,omitempty"`
|
|
||||||
Size string `json:"size,omitempty"`
|
|
||||||
RemixedFromVideoID string `json:"remixed_from_video_id,omitempty"`
|
|
||||||
Error *OpenAIVideoError `json:"error,omitempty"`
|
|
||||||
Metadata map[string]any `json:"metadata,omitempty"`
|
|
||||||
}
|
|
||||||
type OpenAIVideoError struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
Code string `json:"code"`
|
|
||||||
}
|
|
||||||
|
|||||||
52
relay/common/relay_video.go
Normal file
52
relay/common/relay_video.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
VideoStatusUnknown = "unknown"
|
||||||
|
VideoStatusQueued = "queued"
|
||||||
|
VideoStatusInProgress = "in_progress"
|
||||||
|
VideoStatusCompleted = "completed"
|
||||||
|
VideoStatusFailed = "failed"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OpenAIVideo struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
TaskID string `json:"task_id,omitempty"` //兼容旧接口 待废弃
|
||||||
|
Object string `json:"object"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
Status string `json:"status"` // Should use VideoStatus constants: VideoStatusQueued, VideoStatusInProgress, VideoStatusCompleted, VideoStatusFailed
|
||||||
|
Progress int `json:"progress"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
CompletedAt int64 `json:"completed_at,omitempty"`
|
||||||
|
ExpiresAt int64 `json:"expires_at,omitempty"`
|
||||||
|
Seconds string `json:"seconds,omitempty"`
|
||||||
|
Size string `json:"size,omitempty"`
|
||||||
|
RemixedFromVideoID string `json:"remixed_from_video_id,omitempty"`
|
||||||
|
Error *OpenAIVideoError `json:"error,omitempty"`
|
||||||
|
Metadata map[string]any `json:"metadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *OpenAIVideo) SetProgressStr(progress string) {
|
||||||
|
progress = strings.TrimSuffix(progress, "%")
|
||||||
|
m.Progress, _ = strconv.Atoi(progress)
|
||||||
|
}
|
||||||
|
func (m *OpenAIVideo) SetMetadata(k string, v any) {
|
||||||
|
if m.Metadata == nil {
|
||||||
|
m.Metadata = make(map[string]any)
|
||||||
|
}
|
||||||
|
m.Metadata[k] = v
|
||||||
|
}
|
||||||
|
func NewOpenAIVideo() *OpenAIVideo {
|
||||||
|
return &OpenAIVideo{
|
||||||
|
Object: "video",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type OpenAIVideoError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user