package main import ( "bufio" "bytes" "fmt" "github.com/schollz/progressbar/v3" "io/fs" "io/ioutil" "log" "os" "os/exec" "path" "regexp" "strings" "time" ) //var sourceDir = "/home/lukas/Downloads" var sourceDir = "V:\\TV_aufnahmen\\Konvertieren" func main() { _files, err := ioutil.ReadDir(sourceDir) if err != nil { log.Fatal(err) } var files []string for _, file := range _files { if validFile(file) { files = append(files, path.Join(sourceDir, file.Name())) } } fmt.Printf("Found %d files\n", len(files)) for _, file := range files { fmt.Printf("Converting %s\n", file) convert(file) } } func validFile(file fs.FileInfo) bool { return !file.IsDir() && strings.HasSuffix(file.Name(), ".ts") } func convert(file string) { ext := path.Ext(file) outfile := file[0:len(file)-len(ext)] + ".mp4" tottime := getVidTime(file) com := exec.Command("ffmpeg", "-y", // overwrite existing out files "-hwaccel", "vulkan", // vulkan hardware accelleration "-hide_banner", "-loglevel", "warning", // set it less silent "-progress", "pipe:1", // pipe a progress text to 1 "-i", file, // input file "-c:v", "h264_amf", // reencode video with amf "-c:a", "copy", // copy audio stream outfile) // output file fmt.Println(com.String()) // pipe stderr directly to out com.Stderr = os.Stderr stderr, _ := com.StdoutPipe() err := com.Start() scanner := bufio.NewScanner(stderr) scanner.Split(bufio.ScanLines) var infoblock string = "" bar := progressbar.Default(tottime) for scanner.Scan() { m := scanner.Text() // we know a new data block begins here if strings.Contains(m, "frame=") { //fmt.Println(infoblock) r := regexp.MustCompile("out_time=(.*)") matches := r.FindStringSubmatch(infoblock) if len(matches) < 2 { continue } parsedtime, err := time.Parse("15:04:05.000000", matches[1]) if err != nil { fmt.Println("error invalid time") continue } secondtime := 3600*parsedtime.Hour() + parsedtime.Minute()*60 + parsedtime.Second() _ = bar.Set(secondtime) infoblock = "" } else { infoblock += m + "\n" } } err = com.Wait() _ = bar.Finish() if err != nil { //fmt.Println(out.String()) log.Fatal(err) } } func getVidTime(file string) int64 { com := exec.Command("ffmpeg", "-i", file) var out bytes.Buffer com.Stdout = &out com.Stderr = &out err := com.Run() fmt.Println("output:") //fmt.Println(out.String()) r := regexp.MustCompile("Duration: (.*), start: ") matches := r.FindStringSubmatch(out.String()) if len(matches) < 2 { return -1 } fmt.Println(r.FindStringSubmatch(out.String())[1]) parsedtime, err := time.Parse("15:04:05.00", matches[1]) if err != nil { fmt.Println("error invalid time") return 0 } sectime := parsedtime.Hour()*3600 + parsedtime.Minute()*60 + parsedtime.Second() fmt.Printf("Length: %d\n", sectime) return int64(sectime) }