1. 增加配置持久化
2. 完善细节
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"ffmpeg-gui/internal/ffmpeg"
|
||||
"ffmpeg-gui/internal/media"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -193,6 +194,26 @@ func (m *Manager) runTask(t *Task) {
|
||||
return
|
||||
}
|
||||
|
||||
// For burn tasks: extract internal subtitles to temp files first.
|
||||
// The subtitles filter (libass) hangs on Windows when re-opening the
|
||||
// input via si= — extracting avoids the file re-open entirely.
|
||||
var tempFiles []string
|
||||
if t.Type == TypeBurn {
|
||||
for i, sub := range t.Subtitle.Subtitles {
|
||||
if sub.Source == "internal" {
|
||||
tmpPath := t.OutputFile + fmt.Sprintf(".sub_%d_tmp.srt", i)
|
||||
if _, err := m.exec.RunSync("-y", "-i", t.InputFile,
|
||||
"-map", fmt.Sprintf("0:s:%d", sub.Index), "-c:s", "srt", tmpPath); err != nil {
|
||||
m.completeTask(t, false, fmt.Sprintf("提取字幕轨道 #%d 失败: %v", sub.Index, err))
|
||||
return
|
||||
}
|
||||
t.Subtitle.Subtitles[i].Source = "external"
|
||||
t.Subtitle.Subtitles[i].FilePath = tmpPath
|
||||
tempFiles = append(tempFiles, tmpPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args := BuildArgs(t, m.hwAccel)
|
||||
t.Args = args
|
||||
|
||||
@@ -234,8 +255,14 @@ func (m *Manager) runTask(t *Task) {
|
||||
|
||||
<-done
|
||||
runErr := <-errCh
|
||||
|
||||
// Clean up temp subtitle files
|
||||
for _, f := range tempFiles {
|
||||
os.Remove(f)
|
||||
}
|
||||
|
||||
if runErr != nil {
|
||||
m.completeTask(t, false, fmt.Sprintf("编码失败: %v", runErr))
|
||||
m.completeTask(t, false, fmt.Sprintf("%s失败: %v", taskTypeLabel(t.Type), runErr))
|
||||
} else {
|
||||
m.completeTask(t, true, "")
|
||||
}
|
||||
@@ -260,6 +287,11 @@ func (m *Manager) completeTask(t *Task, success bool, errMsg string) {
|
||||
}
|
||||
t.CompletedAt = &now
|
||||
m.emit(EventTaskUpdated, t)
|
||||
// Emit final progress so frontend bar reaches 100%
|
||||
m.emit(EventTaskProgress, map[string]any{
|
||||
"taskId": t.ID,
|
||||
"progress": t.Progress,
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) find(taskID string) *Task {
|
||||
@@ -276,3 +308,16 @@ func (m *Manager) emit(eventType string, data any) {
|
||||
m.onEvent(eventType, data)
|
||||
}
|
||||
}
|
||||
|
||||
func taskTypeLabel(typ Type) string {
|
||||
switch typ {
|
||||
case TypeRemux:
|
||||
return "封装"
|
||||
case TypeEncode:
|
||||
return "转码"
|
||||
case TypeBurn:
|
||||
return "字幕烧录"
|
||||
default:
|
||||
return "任务"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ type Task struct {
|
||||
Encode ffmpeg.EncodeSettings `json:"encode,omitempty"`
|
||||
Remux ffmpeg.RemuxSettings `json:"remux,omitempty"`
|
||||
Subtitle ffmpeg.SubtitleSettings `json:"subtitle,omitempty"`
|
||||
Args []string `json:"-"`
|
||||
Logs []string `json:"-"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
Logs []string `json:"logs,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
CompletedAt *time.Time `json:"completedAt,omitempty"`
|
||||
|
||||
Reference in New Issue
Block a user