From be19daf5feb7a7eddb0545aae869a323f34d1e9c Mon Sep 17 00:00:00 2001 From: Rogee Date: Tue, 17 Dec 2024 09:50:28 +0800 Subject: [PATCH] fix: add buffer to utils --- .../commands/discover/discover_medias.go | 71 ++++++++++++++----- backend/pkg/utils/buffer.go | 26 +++++++ 2 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 backend/pkg/utils/buffer.go diff --git a/backend/modules/commands/discover/discover_medias.go b/backend/modules/commands/discover/discover_medias.go index dd56817..fd92f00 100644 --- a/backend/modules/commands/discover/discover_medias.go +++ b/backend/modules/commands/discover/discover_medias.go @@ -1,6 +1,7 @@ package discover import ( + "bytes" "crypto/md5" "fmt" "io" @@ -13,6 +14,7 @@ import ( "backend/modules/medias" "backend/pkg/media_store" "backend/pkg/path" + "backend/pkg/utils" "github.com/pkg/errors" log "github.com/sirupsen/logrus" @@ -61,6 +63,12 @@ func (d *DiscoverMedias) RunE(from, to string) error { return errors.Wrapf(err, "get file md5: %s", video) } name := filepath.Base(video)[0:strings.LastIndex(filepath.Base(video), ".")] + d.log.Infof("start process video: %s, md5: %s, name: %s", video, md5, name) + + if name == "" { + d.log.Errorf("video name is empty: %s", video) + continue + } if info, ok := store.HashExists(md5); ok { info.Name = name @@ -68,6 +76,7 @@ func (d *DiscoverMedias) RunE(from, to string) error { if err := store.Save(to); err != nil { return errors.Wrapf(err, "save store: %s", to) } + d.log.Infof("video exists: %s", video) continue } @@ -156,11 +165,18 @@ func (d *DiscoverMedias) extractAudio(video string, output string) error { } d.log.Infof("cmd: ffmpeg %s", strings.Join(args, " ")) - logs, err := exec.Command("ffmpeg", args...).CombinedOutput() - if err != nil { - return errors.Wrapf(err, "extract audio: %s", video) + + cmd := exec.Command("ffmpeg", args...) + var buf bytes.Buffer + logWriter := utils.NewLogBuffer(func(line string) { + d.log.Info(line) + }) + cmd.Stdout = utils.NewCombinedBuffer(&buf, logWriter) + cmd.Stderr = utils.NewCombinedBuffer(&buf, logWriter) + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "extract audio failed: %s\n%s", video, buf.String()) } - d.log.Infof("extract audio: %s", logs) return nil } @@ -206,12 +222,19 @@ func (d *DiscoverMedias) ffmpegVideoToM3U8(input, output, hash string) error { } log.Infof("cmd: ffmpeg %s", strings.Join(args, " ")) - logs, err := exec.Command("ffmpeg", args...).CombinedOutput() - if err != nil { - return errors.Wrapf(err, "ffmpeg video to m3u8: %s", input) + + cmd := exec.Command("ffmpeg", args...) + var buf bytes.Buffer + logWriter := utils.NewLogBuffer(func(line string) { + d.log.Info(line) + }) + cmd.Stdout = utils.NewCombinedBuffer(&buf, logWriter) + cmd.Stderr = utils.NewCombinedBuffer(&buf, logWriter) + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "ffmpeg video to m3u8 failed: %s\n%s", input, buf.String()) } - d.log.Infof("ffmpeg video to m3u8: %s", logs) return nil } @@ -234,12 +257,19 @@ func (d *DiscoverMedias) ffmpegAudioToM3U8(input, output, hash string) error { } log.Infof("cmd: ffmpeg %s", strings.Join(args, " ")) - logs, err := exec.Command("ffmpeg", args...).CombinedOutput() - if err != nil { - return errors.Wrapf(err, "ffmpeg audio to m3u8: %s", input) + + cmd := exec.Command("ffmpeg", args...) + var buf bytes.Buffer + logWriter := utils.NewLogBuffer(func(line string) { + d.log.Info(line) + }) + cmd.Stdout = utils.NewCombinedBuffer(&buf, logWriter) + cmd.Stderr = utils.NewCombinedBuffer(&buf, logWriter) + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "ffmpeg audio to m3u8 failed: %s\n%s", input, buf.String()) } - d.log.Infof("ffmpeg audio to m3u8: %s", logs) return nil } @@ -274,8 +304,8 @@ func (d *DiscoverMedias) runCleanup(to string) { // getSnapshot get the snapshot of target seconds of a video func (d *DiscoverMedias) ffmpegVideoToPoster(video string, output string) error { - // ffmpeg -i input_video.mp4 -ss N -vframes 1 -vf "scale=width:height" output_image.jpg args := []string{ + "-y", // 添加 -y 参数强制覆盖 "-i", video, "-ss", "00:00:01", "-vframes", "1", @@ -284,12 +314,19 @@ func (d *DiscoverMedias) ffmpegVideoToPoster(video string, output string) error } d.log.Infof("cmd: ffmpeg %s", strings.Join(args, " ")) - logs, err := exec.Command("ffmpeg", args...).CombinedOutput() - if err != nil { - return errors.Wrapf(err, "get snapshot: %s", video) + + cmd := exec.Command("ffmpeg", args...) + var buf bytes.Buffer + logWriter := utils.NewLogBuffer(func(line string) { + d.log.Info(line) + }) + cmd.Stdout = utils.NewCombinedBuffer(&buf, logWriter) + cmd.Stderr = utils.NewCombinedBuffer(&buf, logWriter) + + if err := cmd.Run(); err != nil { + return errors.Wrapf(err, "get snapshot failed: %s\n%s", video, buf.String()) } - d.log.Infof("get snapshot: %s", logs) return nil } diff --git a/backend/pkg/utils/buffer.go b/backend/pkg/utils/buffer.go new file mode 100644 index 0000000..5746d74 --- /dev/null +++ b/backend/pkg/utils/buffer.go @@ -0,0 +1,26 @@ +package utils + +import ( + "bufio" + "io" +) + +// NewLogBuffer creates a buffer that can be used to capture output stream +// and write to a logger in real time +func NewLogBuffer(output func(string)) io.Writer { + reader, writer := io.Pipe() + + go func() { + scanner := bufio.NewScanner(reader) + for scanner.Scan() { + output(scanner.Text()) + } + }() + + return writer +} + +// NewCombinedBuffer combines multiple io.Writers +func NewCombinedBuffer(writers ...io.Writer) io.Writer { + return io.MultiWriter(writers...) +}