package ffmpeg import ( "bufio" "errors" "fyne.io/fyne/v2/lang" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils" "io" "os/exec" "regexp" "strings" ) type ProgressContract interface { GetProtocole() string Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error } type FFmpegContract interface { GetPath() string GetFFmpegVersion() (string, error) GetEncoders(scanner func(scanner *bufio.Reader)) error RunConvert(setting ConvertSetting, progress ProgressContract, beforeWait func(cmd *exec.Cmd), afterWait func(cmd *exec.Cmd)) error } type ffmpeg struct { path string } func newFFmpeg(path string) (FFmpegContract, error) { if path == "" { return nil, errors.New(lang.L("errorFFmpeg")) } isCheck, err := checkFFmpegPath(path) if err != nil { return nil, err } if isCheck == false { return nil, errors.New(lang.L("errorFFmpeg")) } return &ffmpeg{ path: path, }, nil } func (f *ffmpeg) GetPath() string { return f.path } func (f *ffmpeg) GetFFmpegVersion() (string, error) { cmd := exec.Command(f.path, "-version") utils.PrepareBackgroundCommand(cmd) out, err := cmd.CombinedOutput() if err != nil { return "", err } text := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1) return text[0], nil } func (f *ffmpeg) RunConvert(setting ConvertSetting, progress ProgressContract, beforeWait func(cmd *exec.Cmd), afterWait func(cmd *exec.Cmd)) error { overwriteOutputFiles := "-n" if setting.OverwriteOutputFiles == true { overwriteOutputFiles = "-y" } args := []string{overwriteOutputFiles, "-i", setting.FileInput.Path} args = append(args, setting.Encoder.GetParams()...) args = append(args, "-progress", progress.GetProtocole(), setting.FileOut.Path) cmd := exec.Command(f.path, args...) utils.PrepareBackgroundCommand(cmd) stdOut, err := cmd.StdoutPipe() if err != nil { return err } stdErr, err := cmd.StderrPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } if beforeWait != nil { beforeWait(cmd) } errProgress := progress.Run(stdOut, stdErr) err = cmd.Wait() if afterWait != nil { afterWait(cmd) } if errProgress != nil { return errProgress } if err != nil { return err } return nil } func (f *ffmpeg) GetEncoders(scanner func(scanner *bufio.Reader)) error { cmd := exec.Command(f.path, "-encoders") utils.PrepareBackgroundCommand(cmd) stdOut, err := cmd.StdoutPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } scannerErr := bufio.NewReader(stdOut) scanner(scannerErr) return cmd.Wait() } func checkFFmpegPath(path string) (bool, error) { cmd := exec.Command(path, "-version") utils.PrepareBackgroundCommand(cmd) out, err := cmd.CombinedOutput() if err != nil { return false, err } if strings.Contains(strings.TrimSpace(string(out)), "ffmpeg") == false { return false, nil } return true, nil }