stash/pkg/manager/generator.go

92 lines
2.1 KiB
Go
Raw Normal View History

2019-02-10 05:30:54 +00:00
package manager
import (
"bytes"
2019-02-10 05:30:54 +00:00
"fmt"
2019-02-14 23:42:52 +00:00
"github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/utils"
2019-02-10 05:30:54 +00:00
"os/exec"
"regexp"
"runtime"
2019-02-10 05:30:54 +00:00
"strconv"
)
2019-02-10 09:44:12 +00:00
type GeneratorInfo struct {
2019-02-10 05:30:54 +00:00
ChunkCount int
FrameRate float64
NumberOfFrames int
NthFrame int
VideoFile ffmpeg.VideoFile
}
2019-02-10 09:44:12 +00:00
func newGeneratorInfo(videoFile ffmpeg.VideoFile) (*GeneratorInfo, error) {
2019-02-10 05:30:54 +00:00
exists, err := utils.FileExists(videoFile.Path)
if !exists {
logger.Errorf("video file not found")
return nil, err
}
2019-02-10 09:44:12 +00:00
generator := &GeneratorInfo{VideoFile: videoFile}
2019-02-10 05:30:54 +00:00
return generator, nil
}
2019-02-10 09:44:12 +00:00
func (g *GeneratorInfo) configure() error {
2019-02-10 05:30:54 +00:00
videoStream := g.VideoFile.VideoStream
if videoStream == nil {
return fmt.Errorf("missing video stream")
}
var framerate float64
if g.VideoFile.FrameRate == 0 {
framerate, _ = strconv.ParseFloat(videoStream.RFrameRate, 64)
} else {
framerate = g.VideoFile.FrameRate
}
g.FrameRate = framerate
numberOfFrames, _ := strconv.Atoi(videoStream.NbFrames)
if numberOfFrames == 0 {
args := []string{
"-nostats",
"-i", g.VideoFile.Path,
"-vcodec", "copy",
"-f", "rawvideo",
"-y",
2019-02-10 05:30:54 +00:00
}
if runtime.GOOS == "windows" {
args = append(args, "nul") // https://stackoverflow.com/questions/313111/is-there-a-dev-null-on-windows
} else {
args = append(args, "/dev/null")
}
command := exec.Command(instance.FFMPEGPath, args...)
var stdErrBuffer bytes.Buffer
command.Stderr = &stdErrBuffer // Frames go to stderr rather than stdout
if err := command.Run(); err == nil {
re := regexp.MustCompile(`frame[=] ([0-9]+)`)
frames := re.FindStringSubmatch(stdErrBuffer.String())
if frames != nil && len(frames) > 1 {
numberOfFrames, _ = strconv.Atoi(frames[1])
}
}
}
if numberOfFrames == 0 { // TODO: test
numberOfFrames = int(framerate * g.VideoFile.Duration)
2019-02-10 05:30:54 +00:00
}
if numberOfFrames == 0 {
logger.Errorf(
"number of frames is 0. nb_frames <%s> framerate <%s> duration <%s>",
videoStream.NbFrames,
framerate,
g.VideoFile.Duration,
)
}
2019-02-10 05:30:54 +00:00
g.NumberOfFrames = numberOfFrames
g.NthFrame = g.NumberOfFrames / g.ChunkCount
return nil
}