fix(upscale): report ffmpeg progress via pipe
This commit is contained in:
parent
c517ec09a2
commit
784d6cba52
105
main.go
105
main.go
|
|
@ -5703,36 +5703,47 @@ func (s *appState) executeUpscaleJob(ctx context.Context, job *queue.Job, progre
|
||||||
}
|
}
|
||||||
|
|
||||||
runFFmpegWithProgress := func(args []string, duration float64, startPct, endPct float64) error {
|
runFFmpegWithProgress := func(args []string, duration float64, startPct, endPct float64) error {
|
||||||
|
if len(args) > 0 {
|
||||||
|
last := args[len(args)-1]
|
||||||
|
args = append(args[:len(args)-1], "-progress", "pipe:1", "-nostats", last)
|
||||||
|
}
|
||||||
cmd := exec.CommandContext(ctx, utils.GetFFmpegPath(), args...)
|
cmd := exec.CommandContext(ctx, utils.GetFFmpegPath(), args...)
|
||||||
utils.ApplyNoWindow(cmd)
|
utils.ApplyNoWindow(cmd)
|
||||||
stderr, err := cmd.StderrPipe()
|
stdout, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create stderr pipe: %w", err)
|
return fmt.Errorf("failed to create stdout pipe: %w", err)
|
||||||
|
}
|
||||||
|
if logFile != nil {
|
||||||
|
cmd.Stderr = logFile
|
||||||
|
} else {
|
||||||
|
cmd.Stderr = io.Discard
|
||||||
}
|
}
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("failed to start ffmpeg: %w", err)
|
return fmt.Errorf("failed to start ffmpeg: %w", err)
|
||||||
}
|
}
|
||||||
scanner := bufio.NewScanner(stderr)
|
scanner := bufio.NewScanner(stdout)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
if logFile != nil {
|
if logFile != nil {
|
||||||
fmt.Fprintln(logFile, line)
|
fmt.Fprintln(logFile, line)
|
||||||
}
|
}
|
||||||
if strings.Contains(line, "time=") && duration > 0 {
|
if duration <= 0 {
|
||||||
if idx := strings.Index(line, "time="); idx != -1 {
|
continue
|
||||||
timeStr := line[idx+5:]
|
}
|
||||||
if spaceIdx := strings.Index(timeStr, " "); spaceIdx != -1 {
|
parts := strings.SplitN(line, "=", 2)
|
||||||
timeStr = timeStr[:spaceIdx]
|
if len(parts) != 2 {
|
||||||
}
|
continue
|
||||||
var h, m int
|
}
|
||||||
var s float64
|
key, val := parts[0], parts[1]
|
||||||
if _, err := fmt.Sscanf(timeStr, "%d:%d:%f", &h, &m, &s); err == nil {
|
if key == "out_time_ms" {
|
||||||
currentTime := float64(h*3600+m*60) + s
|
ms, err := strconv.ParseFloat(val, 64)
|
||||||
progress := startPct + ((currentTime / duration) * (endPct - startPct))
|
if err != nil {
|
||||||
if progressCallback != nil {
|
continue
|
||||||
progressCallback(progress)
|
}
|
||||||
}
|
currentTime := ms / 1000000.0
|
||||||
}
|
progress := startPct + ((currentTime / duration) * (endPct - startPct))
|
||||||
|
if progressCallback != nil {
|
||||||
|
progressCallback(progress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5895,6 +5906,8 @@ func (s *appState) executeUpscaleJob(ctx context.Context, job *queue.Job, progre
|
||||||
"-crf", strconv.Itoa(crfValue),
|
"-crf", strconv.Itoa(crfValue),
|
||||||
"-pix_fmt", "yuv420p",
|
"-pix_fmt", "yuv420p",
|
||||||
"-c:a", "copy",
|
"-c:a", "copy",
|
||||||
|
"-progress", "pipe:1",
|
||||||
|
"-nostats",
|
||||||
outputPath,
|
outputPath,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -5902,49 +5915,47 @@ func (s *appState) executeUpscaleJob(ctx context.Context, job *queue.Job, progre
|
||||||
cmd := exec.CommandContext(ctx, utils.GetFFmpegPath(), args...)
|
cmd := exec.CommandContext(ctx, utils.GetFFmpegPath(), args...)
|
||||||
utils.ApplyNoWindow(cmd)
|
utils.ApplyNoWindow(cmd)
|
||||||
|
|
||||||
// Create progress reader for stderr
|
stdout, err := cmd.StdoutPipe()
|
||||||
stderr, err := cmd.StderrPipe()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create stderr pipe: %w", err)
|
return fmt.Errorf("failed to create stdout pipe: %w", err)
|
||||||
|
}
|
||||||
|
if logFile != nil {
|
||||||
|
cmd.Stderr = logFile
|
||||||
|
} else {
|
||||||
|
cmd.Stderr = io.Discard
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return fmt.Errorf("failed to start upscale: %w", err)
|
return fmt.Errorf("failed to start upscale: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse progress from FFmpeg stderr
|
// Parse progress from FFmpeg stdout (-progress pipe:1)
|
||||||
go func() {
|
go func() {
|
||||||
scanner := bufio.NewScanner(stderr)
|
scanner := bufio.NewScanner(stdout)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
if logFile != nil {
|
if logFile != nil {
|
||||||
fmt.Fprintln(logFile, line)
|
fmt.Fprintln(logFile, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse progress from "time=00:01:23.45"
|
if duration, ok := cfg["duration"].(float64); ok && duration > 0 {
|
||||||
if strings.Contains(line, "time=") {
|
parts := strings.SplitN(line, "=", 2)
|
||||||
// Get duration from job config
|
if len(parts) != 2 {
|
||||||
if duration, ok := cfg["duration"].(float64); ok && duration > 0 {
|
continue
|
||||||
// Extract time from FFmpeg output
|
}
|
||||||
if idx := strings.Index(line, "time="); idx != -1 {
|
key, val := parts[0], parts[1]
|
||||||
timeStr := line[idx+5:]
|
if key == "out_time_ms" {
|
||||||
if spaceIdx := strings.Index(timeStr, " "); spaceIdx != -1 {
|
ms, err := strconv.ParseFloat(val, 64)
|
||||||
timeStr = timeStr[:spaceIdx]
|
if err != nil {
|
||||||
}
|
continue
|
||||||
|
}
|
||||||
// Parse time string (HH:MM:SS.ms)
|
currentTime := ms / 1000000.0
|
||||||
var h, m int
|
progress := (currentTime / duration) * 100.0
|
||||||
var s float64
|
if progress > 100.0 {
|
||||||
if _, err := fmt.Sscanf(timeStr, "%d:%d:%f", &h, &m, &s); err == nil {
|
progress = 100.0
|
||||||
currentTime := float64(h*3600+m*60) + s
|
}
|
||||||
progress := (currentTime / duration) * 100.0
|
if progressCallback != nil {
|
||||||
if progress > 100.0 {
|
progressCallback(progress)
|
||||||
progress = 100.0
|
|
||||||
}
|
|
||||||
if progressCallback != nil {
|
|
||||||
progressCallback(progress)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user