From f076985bf3a8f9cddeb90519f2bc467e75cd6981 Mon Sep 17 00:00:00 2001 From: Carl Pearson Date: Wed, 16 Oct 2024 20:56:44 -0600 Subject: [PATCH] rework ytdlp in terms of start/wait, fix audio transcode error --- handlers.go | 11 +++++++-- workers.go | 2 +- ytdlp/ytdlp.go | 67 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 16 deletions(-) diff --git a/handlers.go b/handlers.go index c2c3d27..90e7504 100644 --- a/handlers.go +++ b/handlers.go @@ -178,7 +178,14 @@ type Meta struct { func getYtdlpTitle(url string, args []string) (string, error) { args = append(args, "--simulate", "--print", "%(title)s", url) - stdout, _, err := ytdlp.Run(args...) + + cmd, cancel, err := ytdlp.Start(args...) + defer cancel() + if err != nil { + log.Errorln(err) + return "", err + } + stdout, _, err := cmd.Wait() if err != nil { log.Errorln(err) return "", err @@ -541,7 +548,7 @@ func processOriginal(originalID uint) { // create audio transcodes for _, bitrate := range []uint{64 /*, 96, 128, 160, 192*/} { - addAudioTranscode(video.ID, originalID, bitrate, "audio") + addAudioTranscode(audio.ID, originalID, bitrate, "audio") } } else { diff --git a/workers.go b/workers.go index ecd9c65..e3f3d83 100644 --- a/workers.go +++ b/workers.go @@ -270,7 +270,7 @@ func transcodePending() { var srcAudio media.Audio err = db.First(&srcAudio, "id = ?", trans.SrcID).Error if err != nil { - fmt.Println("no such source audio for audio Transcode", trans) + log.Errorln("no such source audio for audio Transcode", trans) db.Delete(&trans) continue } diff --git a/ytdlp/ytdlp.go b/ytdlp/ytdlp.go index 486b953..7dd443f 100644 --- a/ytdlp/ytdlp.go +++ b/ytdlp/ytdlp.go @@ -2,25 +2,66 @@ package ytdlp import ( "bytes" + "context" "os/exec" "strings" ) // runs ffprobe with the provided args and returns (stdout, stderr, error) func Run(args ...string) ([]byte, []byte, error) { - ytdlp := "yt-dlp" - log.Infoln(ytdlp, strings.Join(args, " ")) - cmd := exec.Command(ytdlp, args...) - var stdout bytes.Buffer - var stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - + cmd, cancel, err := Start(args...) + defer cancel() if err != nil { - log.Errorf("yt-dlp error: %v", err) + return nil, nil, err } - log.Infoln("stdout:", stdout.String()) - log.Infoln("stderr:", stderr.String()) - return stdout.Bytes(), stderr.Bytes(), err + return cmd.Wait() +} + +type Cmd struct { + ctx context.Context + cmd *exec.Cmd + + stdout *bytes.Buffer + stderr *bytes.Buffer +} + +func Start(args ...string) (*Cmd, context.CancelFunc, error) { + + ytdlp := "yt-dlp" + stdout := new(bytes.Buffer) + stderr := new(bytes.Buffer) + + ctx, cancel := context.WithCancel(context.Background()) + cmd := exec.CommandContext(ctx, ytdlp, args...) + cmd.Stdout = stdout + cmd.Stderr = stderr + + log.Infoln(ytdlp, strings.Join(args, " ")) + err := cmd.Start() + if err != nil { + return nil, cancel, err // FIXME: okay to just return this cancel thing? + } + + return &Cmd{ + ctx: ctx, + cmd: cmd, + stdout: stdout, + stderr: stderr, + }, cancel, nil +} + +func (c *Cmd) Wait() ([]byte, []byte, error) { + err := c.cmd.Wait() + if err != nil { + if c.ctx.Err() == context.Canceled { + log.Debugln("command canceled") + } else { + log.Errorln("yt-dlp error", err) + } + } else { + log.Infoln("stdout:", c.stdout.String()) + log.Infoln("stderr:", c.stderr.String()) + } + + return c.stdout.Bytes(), c.stderr.Bytes(), err }