mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Restructure ffmpeg (#2392)
* Refactor transcode generation * Move phash generation into separate package * Refactor image thumbnail generation * Move JSONTime to separate package * Ffmpeg refactoring * Refactor live transcoding * Refactor scene marker preview generation * Refactor preview generation * Refactor screenshot generation * Refactor sprite generation * Change ffmpeg.IsStreamable to return error * Move frame rate calculation into ffmpeg * Refactor file locking * Refactor title set during scan * Add missing lockmanager instance * Return error instead of logging in MatchContainer
This commit is contained in:
101
pkg/scene/generate/screenshot.go
Normal file
101
pkg/scene/generate/screenshot.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/stashapp/stash/pkg/ffmpeg/transcoder"
|
||||
"github.com/stashapp/stash/pkg/fsutil"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
)
|
||||
|
||||
const (
|
||||
thumbnailWidth = 320
|
||||
thumbnailQuality = 5
|
||||
|
||||
screenshotQuality = 2
|
||||
|
||||
screenshotDurationProportion = 0.2
|
||||
)
|
||||
|
||||
type ScreenshotOptions struct {
|
||||
At *float64
|
||||
}
|
||||
|
||||
func (g Generator) Screenshot(ctx context.Context, input string, hash string, videoWidth int, videoDuration float64, options ScreenshotOptions) error {
|
||||
lockCtx := g.LockManager.ReadLock(ctx, input)
|
||||
defer lockCtx.Cancel()
|
||||
|
||||
output := g.ScenePaths.GetScreenshotPath(hash)
|
||||
if !g.Overwrite {
|
||||
if exists, _ := fsutil.FileExists(output); exists {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
at := screenshotDurationProportion * videoDuration
|
||||
if options.At != nil {
|
||||
at = *options.At
|
||||
}
|
||||
|
||||
if err := g.generateFile(lockCtx, g.ScenePaths, jpgPattern, output, g.screenshot(input, screenshotOptions{
|
||||
Time: at,
|
||||
Quality: screenshotQuality,
|
||||
// default Width is video width
|
||||
})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debug("created screenshot: ", output)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g Generator) Thumbnail(ctx context.Context, input string, hash string, videoDuration float64, options ScreenshotOptions) error {
|
||||
lockCtx := g.LockManager.ReadLock(ctx, input)
|
||||
defer lockCtx.Cancel()
|
||||
|
||||
output := g.ScenePaths.GetThumbnailScreenshotPath(hash)
|
||||
if !g.Overwrite {
|
||||
if exists, _ := fsutil.FileExists(output); exists {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
at := screenshotDurationProportion * videoDuration
|
||||
if options.At != nil {
|
||||
at = *options.At
|
||||
}
|
||||
|
||||
if err := g.generateFile(lockCtx, g.ScenePaths, jpgPattern, output, g.screenshot(input, screenshotOptions{
|
||||
Time: at,
|
||||
Quality: thumbnailQuality,
|
||||
Width: thumbnailWidth,
|
||||
})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Debug("created thumbnail: ", output)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type screenshotOptions struct {
|
||||
Time float64
|
||||
Width int
|
||||
Quality int
|
||||
}
|
||||
|
||||
func (g Generator) screenshot(input string, options screenshotOptions) generateFn {
|
||||
return func(lockCtx *fsutil.LockContext, tmpFn string) error {
|
||||
ssOptions := transcoder.ScreenshotOptions{
|
||||
OutputPath: tmpFn,
|
||||
OutputType: transcoder.ScreenshotOutputTypeImage2,
|
||||
Quality: options.Quality,
|
||||
Width: options.Width,
|
||||
}
|
||||
|
||||
args := transcoder.ScreenshotTime(input, options.Time, ssOptions)
|
||||
|
||||
return g.generate(lockCtx, args)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user