ffmpeg-playout/status/status.go

94 lines
1.9 KiB
Go

package status
import (
"bufio"
"github.com/fsnotify/fsnotify"
"io"
"log"
"os"
"strconv"
"strings"
"time"
)
type Status struct {
Frame int
FPS float64
Bitrate float64
Dupframes int
Speed float64
}
//nolint:funlen
func FFmpegStatusWatcher(c chan<- Status, path string) error {
var ffmpegStatus Status
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
defer watcher.Close()
defer close(c)
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
log.Println(err)
}
splits := strings.Split(line, "=")
key := strings.TrimSpace(splits[0])
value := strings.TrimSpace(splits[1])
switch key {
case "frame":
ffmpegStatus.Frame, err = strconv.Atoi(value)
case "fps":
ffmpegStatus.FPS, err = strconv.ParseFloat(value, 64)
case "bitrate":
ffmpegStatus.Bitrate, err = strconv.ParseFloat(strings.TrimSuffix(value, "kbits/s"), 64)
case "out_time_ms":
// test["Progress.Out_time_ms"], err = strconv.Atoi(value)
continue
case "dup_frames":
ffmpegStatus.Dupframes, err = strconv.Atoi(value)
case "speed":
ffmpegStatus.Speed, err = strconv.ParseFloat(strings.TrimSuffix(value, "x"), 64)
}
if err != nil {
log.Println(err)
}
}
c <- ffmpegStatus
}
case <-time.After(5 * time.Second):
log.Println("Timeout of Status Reading")
return
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("error:", err)
}
}
}()
err = watcher.Add(path)
return err
}