diff --git a/pkg/ffmpeg/encoder_scene_preview_chunk.go b/pkg/ffmpeg/encoder_scene_preview_chunk.go index 9d7547c56..6b09881e5 100644 --- a/pkg/ffmpeg/encoder_scene_preview_chunk.go +++ b/pkg/ffmpeg/encoder_scene_preview_chunk.go @@ -28,6 +28,7 @@ func (e *Encoder) ScenePreviewVideoChunk(probeResult VideoFile, options ScenePre "-vf", fmt.Sprintf("scale=%v:-2", options.Width), "-c:a", "aac", "-b:a", "128k", + "-strict", "-2", options.OutputPath, } _, _ = e.run(probeResult, args) diff --git a/pkg/ffmpeg/encoder_transcode.go b/pkg/ffmpeg/encoder_transcode.go index 579899a04..e9dd1bd9a 100644 --- a/pkg/ffmpeg/encoder_transcode.go +++ b/pkg/ffmpeg/encoder_transcode.go @@ -14,6 +14,7 @@ func (e *Encoder) Transcode(probeResult VideoFile, options TranscodeOptions) { "-crf", "23", "-vf", "scale=iw:-2", "-c:a", "aac", + "-strict", "-2", options.OutputPath, } _, _ = e.run(probeResult, args) diff --git a/pkg/manager/generator.go b/pkg/manager/generator.go index c2439bb0a..ca1d0368a 100644 --- a/pkg/manager/generator.go +++ b/pkg/manager/generator.go @@ -1,11 +1,14 @@ package manager import ( + "bytes" "fmt" "github.com/stashapp/stash/pkg/ffmpeg" "github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/utils" "os/exec" + "regexp" + "runtime" "strconv" ) @@ -45,16 +48,42 @@ func (g *GeneratorInfo) configure() error { numberOfFrames, _ := strconv.Atoi(videoStream.NbFrames) if numberOfFrames == 0 { - command := `ffmpeg -nostats -i ` + g.VideoFile.Path + ` -vcodec copy -f rawvideo -y /dev/null 2>&1 | \ - grep frame | \ - awk '{split($0,a,"fps")}END{print a[1]}' | \ - sed 's/.*= *//'` - commandResult, _ := exec.Command(command).Output() - numberOfFrames, _ := strconv.Atoi(string(commandResult)) - if numberOfFrames == 0 { // TODO: test - numberOfFrames = int(framerate * g.VideoFile.Duration) + args := []string{ + "-nostats", + "-i", g.VideoFile.Path, + "-vcodec", "copy", + "-f", "rawvideo", + "-y", + } + 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) + } + if numberOfFrames == 0 { + logger.Errorf( + "number of frames is 0. nb_frames <%s> framerate <%s> duration <%s>", + videoStream.NbFrames, + framerate, + g.VideoFile.Duration, + ) + } + g.NumberOfFrames = numberOfFrames g.NthFrame = g.NumberOfFrames / g.ChunkCount diff --git a/pkg/manager/generator_sprite.go b/pkg/manager/generator_sprite.go index 2897f8d9e..bb7617474 100644 --- a/pkg/manager/generator_sprite.go +++ b/pkg/manager/generator_sprite.go @@ -81,6 +81,7 @@ func (g *SpriteGenerator) generateSpriteImage(encoder *ffmpeg.Encoder) error { // Combine all of the thumbnails into a sprite image globPath := filepath.Join(instance.Paths.Generated.Tmp, "thumbnail*.jpg") imagePaths, _ := doublestar.Glob(globPath) + utils.NaturalSort(imagePaths) var images []image.Image for _, imagePath := range imagePaths { img, err := imaging.Open(imagePath) diff --git a/pkg/manager/manager_tasks.go b/pkg/manager/manager_tasks.go index 9e280f1f5..62fa03c19 100644 --- a/pkg/manager/manager_tasks.go +++ b/pkg/manager/manager_tasks.go @@ -21,7 +21,7 @@ func (s *singleton) Scan() { var results []string for _, path := range config.GetStashPaths() { - globPath := filepath.Join(path, "**/*.{zip,m4v,mp4,mov,wmv,avi}") + globPath := filepath.Join(path, "**/*.{zip,m4v,mp4,mov,wmv,avi,mpg,mpeg,rmvb,rm,flv,asf,mkv,webm}") // TODO: Make this configurable globResults, _ := doublestar.Glob(globPath) results = append(results, globResults...) }