Files
media/dao/video/scene_split_task_dao.go
2026-06-22 09:18:45 +08:00

160 lines
4.6 KiB
Go

package video
import (
"context"
"encoding/json"
"sort"
"strconv"
"strings"
"time"
dto "media/model/dto/video"
entity "media/model/entity/video"
"gitea.redpowerfuture.com/red-future/common/db/gfdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
var SceneSplitTask = new(sceneSplitTaskDao)
type sceneSplitTaskDao struct{}
const sceneSplitTaskTable = "scene_split_task"
// Insert 创建任务(排除 id 字段,让数据库自增)
func (d *sceneSplitTaskDao) Insert(ctx context.Context, data *entity.SceneSplitTask) (id int64, err error) {
r, err := gfdb.DB(ctx).Model(ctx, sceneSplitTaskTable).
Data(data).
FieldsEx(entity.SceneSplitTaskCols.Id).
Insert()
if err != nil {
return 0, err
}
return r.LastInsertId()
}
// GetByTaskID 根据taskId查询任务
func (d *sceneSplitTaskDao) GetByTaskID(ctx context.Context, taskID string) (res *entity.SceneSplitTask, err error) {
r, err := gfdb.DB(ctx).Model(ctx, sceneSplitTaskTable).
Where(entity.SceneSplitTaskCols.TaskID, taskID).
One()
if err != nil {
return nil, err
}
if r == nil {
return nil, nil
}
err = r.Struct(&res)
return
}
// UpdateRunning 更新为运行中
func (d *sceneSplitTaskDao) UpdateRunning(ctx context.Context, taskID string) error {
_, err := gfdb.DB(ctx).Model(ctx, sceneSplitTaskTable).
Data(g.Map{
entity.SceneSplitTaskCols.Status: "running",
}).
Where(entity.SceneSplitTaskCols.TaskID, taskID).
Update()
return err
}
// UpdateSuccess 更新为成功
func (d *sceneSplitTaskDao) UpdateSuccess(ctx context.Context, taskID string, segmentURLs, audioURL string, sceneCount int, audioDuration float64, videoDuration float64) error {
_, err := gfdb.DB(ctx).Model(ctx, sceneSplitTaskTable).
Data(g.Map{
entity.SceneSplitTaskCols.Status: "success",
entity.SceneSplitTaskCols.SegmentURLs: segmentURLs,
entity.SceneSplitTaskCols.AudioURL: audioURL,
entity.SceneSplitTaskCols.SceneCount: sceneCount,
entity.SceneSplitTaskCols.AudioDuration: audioDuration,
entity.SceneSplitTaskCols.VideoDuration: videoDuration,
entity.SceneSplitTaskCols.ErrorMessage: "",
}).
Where(entity.SceneSplitTaskCols.TaskID, taskID).
Update()
return err
}
// UpdateError 更新为失败
func (d *sceneSplitTaskDao) UpdateError(ctx context.Context, taskID string, errMsg string) error {
_, err := gfdb.DB(ctx).Model(ctx, sceneSplitTaskTable).
Data(g.Map{
entity.SceneSplitTaskCols.Status: "failed",
entity.SceneSplitTaskCols.ErrorMessage: errMsg,
}).
Where(entity.SceneSplitTaskCols.TaskID, taskID).
Update()
return err
}
// EntityToSceneSplitTaskRes 实体转DTO
func EntityToSceneSplitTaskRes(e *entity.SceneSplitTask) *dto.GetSceneSplitTaskRes {
res := &dto.GetSceneSplitTaskRes{
TaskID: e.TaskID,
Status: e.Status,
SceneCount: e.SceneCount,
AudioDuration: e.AudioDuration,
VideoDuration: e.VideoDuration,
}
if e.CreatedAt != nil {
res.CreatedAt = gconv.Int64(e.CreatedAt.Timestamp())
} else {
res.CreatedAt = time.Now().UnixMilli()
}
if e.Status == "success" {
res.AudioURL = e.AudioURL
res.Segments = ParseSegmentEntries(e.SegmentURLs)
res.SceneCount = e.SceneCount
res.AudioDuration = e.AudioDuration
res.VideoDuration = e.VideoDuration
}
if e.Status == "failed" {
res.ErrorMessage = e.ErrorMessage
}
return res
}
// ParseSegmentEntries 将 JSON 数组解析为按时间线排序的 SegmentEntry 切片
// JSON 格式: [{"timeline":"0.0-7.2","url":"..."}, ...]
func ParseSegmentEntries(jsonStr string) []dto.SegmentEntry {
if jsonStr == "" {
return nil
}
// 先尝试解析为数组格式
var entries []dto.SegmentEntry
if err := json.Unmarshal([]byte(jsonStr), &entries); err == nil && len(entries) > 0 {
// 按起始时间排序确保有序
sort.Slice(entries, func(i, j int) bool {
return extractStartTime(entries[i].Timeline) < extractStartTime(entries[j].Timeline)
})
return entries
}
// 兼容旧的 map 格式 {"0.0-7.2":"url", ...}
var m map[string]string
if err := json.Unmarshal([]byte(jsonStr), &m); err != nil {
return nil
}
entries = make([]dto.SegmentEntry, 0, len(m))
for timeline, url := range m {
entries = append(entries, dto.SegmentEntry{Timeline: timeline, URL: url})
}
sort.Slice(entries, func(i, j int) bool {
return extractStartTime(entries[i].Timeline) < extractStartTime(entries[j].Timeline)
})
return entries
}
// extractStartTime 从时间线 key(如 "0.0-7.2")提取起始秒数用于排序
func extractStartTime(timeline string) float64 {
idx := strings.Index(timeline, "-")
if idx < 0 {
return 0
}
v, _ := strconv.ParseFloat(timeline[:idx], 64)
return v
}