package examples import ( "encoding/json" "fmt" "log" "math/rand" "net" "os" "path" "regexp" "strconv" "strings" "time" ffmpeg "github.com/u2takey/ffmpeg-go" ) // ExampleShowProgress is an example of using the ffmpeg `-progress` option with a // unix-domain socket to report progress func ExampleShowProgress(inFileName, outFileName string) { a, err := ffmpeg.Probe(inFileName) if err != nil { panic(err) } totalDuration, err := probeDuration(a) if err != nil { panic(err) } err = ffmpeg.Input(inFileName). Output(outFileName, ffmpeg.KwArgs{"c:v": "libx264", "preset": "veryslow"}). GlobalArgs("-progress", "unix://"+TempSock(totalDuration)). OverWriteOutput(). Run() if err != nil { panic(err) } } func TempSock(totalDuration float64) string { // serve rand.Seed(time.Now().Unix()) sockFileName := path.Join(os.TempDir(), fmt.Sprintf("%d_sock", rand.Int())) l, err := net.Listen("unix", sockFileName) if err != nil { panic(err) } go func() { re := regexp.MustCompile(`out_time_ms=(\d+)`) fd, err := l.Accept() if err != nil { log.Fatal("accept error:", err) } buf := make([]byte, 16) data := "" progress := "" for { _, err := fd.Read(buf) if err != nil { return } data += string(buf) a := re.FindAllStringSubmatch(data, -1) cp := "" if len(a) > 0 && len(a[len(a)-1]) > 0 { c, _ := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1]) cp = fmt.Sprintf("%.2f", float64(c)/totalDuration/1000000) } if strings.Contains(data, "progress=end") { cp = "done" } if cp == "" { cp = ".0" } if cp != progress { progress = cp fmt.Println("progress: ", progress) } } }() return sockFileName } type probeFormat struct { Duration string `json:"duration"` } type probeData struct { Format probeFormat `json:"format"` } func probeDuration(a string) (float64, error) { pd := probeData{} err := json.Unmarshal([]byte(a), &pd) if err != nil { return 0, err } f, err := strconv.ParseFloat(pd.Format.Duration, 64) if err != nil { return 0, err } return f, nil }