mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-19 05:57:28 +00:00
- Added Gemini video generation configuration structures and payloads. - Introduced functions for parsing and resolving video duration and resolution from metadata. - Enhanced the Vertex adaptor to support Gemini video generation requests and billing estimation based on duration and resolution. - Updated model pricing settings for new Gemini video models.
101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
package gemini
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/QuantumNous/new-api/constant"
|
|
relaycommon "github.com/QuantumNous/new-api/relay/common"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const maxVeoImageSize = 20 * 1024 * 1024 // 20 MB
|
|
|
|
// ExtractMultipartImage reads the first `input_reference` file from a multipart
|
|
// form upload and returns a VeoImageInput. Returns nil if no file is present.
|
|
func ExtractMultipartImage(c *gin.Context, info *relaycommon.RelayInfo) *VeoImageInput {
|
|
mf, err := c.MultipartForm()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
files, exists := mf.File["input_reference"]
|
|
if !exists || len(files) == 0 {
|
|
return nil
|
|
}
|
|
fh := files[0]
|
|
if fh.Size > maxVeoImageSize {
|
|
return nil
|
|
}
|
|
file, err := fh.Open()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
defer file.Close()
|
|
|
|
fileBytes, err := io.ReadAll(file)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
mimeType := fh.Header.Get("Content-Type")
|
|
if mimeType == "" || mimeType == "application/octet-stream" {
|
|
mimeType = http.DetectContentType(fileBytes)
|
|
}
|
|
|
|
info.Action = constant.TaskActionGenerate
|
|
return &VeoImageInput{
|
|
BytesBase64Encoded: base64.StdEncoding.EncodeToString(fileBytes),
|
|
MimeType: mimeType,
|
|
}
|
|
}
|
|
|
|
// ParseImageInput parses an image string (data URI or raw base64) into a
|
|
// VeoImageInput. Returns nil if the input is empty or invalid.
|
|
// TODO: support downloading HTTP URL images and converting to base64
|
|
func ParseImageInput(imageStr string) *VeoImageInput {
|
|
imageStr = strings.TrimSpace(imageStr)
|
|
if imageStr == "" {
|
|
return nil
|
|
}
|
|
|
|
if strings.HasPrefix(imageStr, "data:") {
|
|
return parseDataURI(imageStr)
|
|
}
|
|
|
|
raw, err := base64.StdEncoding.DecodeString(imageStr)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return &VeoImageInput{
|
|
BytesBase64Encoded: imageStr,
|
|
MimeType: http.DetectContentType(raw),
|
|
}
|
|
}
|
|
|
|
func parseDataURI(uri string) *VeoImageInput {
|
|
// data:image/png;base64,iVBOR...
|
|
rest := uri[len("data:"):]
|
|
idx := strings.Index(rest, ",")
|
|
if idx < 0 {
|
|
return nil
|
|
}
|
|
meta := rest[:idx]
|
|
b64 := rest[idx+1:]
|
|
if b64 == "" {
|
|
return nil
|
|
}
|
|
|
|
mimeType := "application/octet-stream"
|
|
parts := strings.SplitN(meta, ";", 2)
|
|
if len(parts) >= 1 && parts[0] != "" {
|
|
mimeType = parts[0]
|
|
}
|
|
|
|
return &VeoImageInput{
|
|
BytesBase64Encoded: b64,
|
|
MimeType: mimeType,
|
|
}
|
|
}
|