package main import ( "context" "errors" "flag" "fmt" "io/fs" "log" "os" "os/exec" "path/filepath" "regexp" "runtime" "strconv" "github.com/go-logr/stdr" "go.xsfx.dev/workgroups" ) var ( re = regexp.MustCompile(`\(Teil\s(\d+)\)`) ErrWrongNumber = errors.New("wrong submatch number") ) func main() { dir := flag.String("dir", "", "dir to run on") flag.Parse() if *dir == "" { log.Fatal("missing dir") } files := []string{} if err := filepath.WalkDir(*dir, func(path string, d fs.DirEntry, err error) error { if !d.IsDir() { files = append(files, path) } return nil }, ); err != nil { log.Fatal(err) } log := stdr.New(log.New(os.Stderr, "", log.Lshortfile)) dis, ctx := workgroups.NewDispatcher( context.Background(), log.WithName("workgroups"), runtime.GOMAXPROCS(0), len(files), ) stdr.SetVerbosity(0) dis.Start() for _, f := range files { f := f dis.Append(workgroups.NewJob(ctx, func(ctx context.Context) error { if tn := re.FindStringSubmatch(f); tn != nil { log := log.WithValues("file", f) if len(tn) != 2 { return ErrWrongNumber } ti, err := strconv.Atoi(tn[1]) if err != nil { return fmt.Errorf("failed to convert ti to int: %w", err) } log.Info("extracted tracknumber", "track", ti) fixedName := fmt.Sprintf("%s.FIXED.opus", f) cmd := exec.CommandContext( ctx, "ffmpeg", "-i", f, "-metadata", fmt.Sprintf("track=%d", ti), "-c:a", "copy", fixedName, ) // cmd.Stdout = os.Stdout // cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return fmt.Errorf("error on command: %w", err) } log.Info("moving fixed to real file", "fixed", fixedName) if err := os.Rename(fixedName, f); err != nil { return fmt.Errorf("failed to rename: %w", err) } } return nil })) } dis.Close() if err := dis.Wait(); err != nil { log.Error(err, "error on waiting") os.Exit(1) } }