ConvertTStoMP4/Main.go
2022-04-15 16:52:34 +02:00

136 lines
2.9 KiB
Go

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)
}