diff --git a/Main.go b/Main.go new file mode 100644 index 0000000..2910468 --- /dev/null +++ b/Main.go @@ -0,0 +1,135 @@ +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) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8379c00 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module Konvertieren + +go 1.16 + +require ( + github.com/schollz/progressbar/v3 v3.8.6 // indirect + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect +)