mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Use Marker endSeconds value when generating previews (#5542)
* generate marker previews using endSeconds value * Limit marker preview duration to 20 seconds max --------- Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
parent
4d43763a39
commit
8bacaa17f4
2 changed files with 26 additions and 17 deletions
|
|
@ -105,11 +105,11 @@ func (t *GenerateMarkersTask) generateSceneMarkers(ctx context.Context) {
|
||||||
|
|
||||||
func (t *GenerateMarkersTask) generateMarker(videoFile *models.VideoFile, scene *models.Scene, sceneMarker *models.SceneMarker) {
|
func (t *GenerateMarkersTask) generateMarker(videoFile *models.VideoFile, scene *models.Scene, sceneMarker *models.SceneMarker) {
|
||||||
sceneHash := scene.GetHash(t.fileNamingAlgorithm)
|
sceneHash := scene.GetHash(t.fileNamingAlgorithm)
|
||||||
seconds := int(sceneMarker.Seconds)
|
seconds := float64(sceneMarker.Seconds)
|
||||||
|
|
||||||
g := t.generator
|
g := t.generator
|
||||||
|
|
||||||
if err := g.MarkerPreviewVideo(context.TODO(), videoFile.Path, sceneHash, seconds, instance.Config.GetPreviewAudio()); err != nil {
|
if err := g.MarkerPreviewVideo(context.TODO(), videoFile.Path, sceneHash, seconds, sceneMarker.EndSeconds, instance.Config.GetPreviewAudio()); err != nil {
|
||||||
logger.Errorf("[generator] failed to generate marker video: %v", err)
|
logger.Errorf("[generator] failed to generate marker video: %v", err)
|
||||||
logErrorOutput(err)
|
logErrorOutput(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
markerPreviewWidth = 640
|
markerPreviewWidth = 640
|
||||||
markerPreviewDuration = 20
|
maxMarkerPreviewDuration = 20
|
||||||
markerPreviewAudioBitrate = "64k"
|
markerPreviewAudioBitrate = "64k"
|
||||||
|
|
||||||
markerImageDuration = 5
|
markerImageDuration = 5
|
||||||
|
|
@ -20,20 +20,28 @@ const (
|
||||||
markerScreenshotQuality = 2
|
markerScreenshotQuality = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g Generator) MarkerPreviewVideo(ctx context.Context, input string, hash string, seconds int, includeAudio bool) error {
|
func (g Generator) MarkerPreviewVideo(ctx context.Context, input string, hash string, seconds float64, endSeconds *float64, includeAudio bool) error {
|
||||||
lockCtx := g.LockManager.ReadLock(ctx, input)
|
lockCtx := g.LockManager.ReadLock(ctx, input)
|
||||||
defer lockCtx.Cancel()
|
defer lockCtx.Cancel()
|
||||||
|
|
||||||
output := g.MarkerPaths.GetVideoPreviewPath(hash, seconds)
|
output := g.MarkerPaths.GetVideoPreviewPath(hash, int(seconds))
|
||||||
if !g.Overwrite {
|
if !g.Overwrite {
|
||||||
if exists, _ := fsutil.FileExists(output); exists {
|
if exists, _ := fsutil.FileExists(output); exists {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
duration := float64(maxMarkerPreviewDuration)
|
||||||
|
|
||||||
|
// don't allow preview to exceed max duration
|
||||||
|
if endSeconds != nil && *endSeconds-seconds < maxMarkerPreviewDuration {
|
||||||
|
duration = float64(*endSeconds) - seconds
|
||||||
|
}
|
||||||
|
|
||||||
if err := g.generateFile(lockCtx, g.MarkerPaths, mp4Pattern, output, g.markerPreviewVideo(input, sceneMarkerOptions{
|
if err := g.generateFile(lockCtx, g.MarkerPaths, mp4Pattern, output, g.markerPreviewVideo(input, sceneMarkerOptions{
|
||||||
Seconds: seconds,
|
Seconds: seconds,
|
||||||
Audio: includeAudio,
|
Duration: duration,
|
||||||
|
Audio: includeAudio,
|
||||||
})); err != nil {
|
})); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -44,8 +52,9 @@ func (g Generator) MarkerPreviewVideo(ctx context.Context, input string, hash st
|
||||||
}
|
}
|
||||||
|
|
||||||
type sceneMarkerOptions struct {
|
type sceneMarkerOptions struct {
|
||||||
Seconds int
|
Seconds float64
|
||||||
Audio bool
|
Duration float64
|
||||||
|
Audio bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Generator) markerPreviewVideo(input string, options sceneMarkerOptions) generateFn {
|
func (g Generator) markerPreviewVideo(input string, options sceneMarkerOptions) generateFn {
|
||||||
|
|
@ -69,8 +78,8 @@ func (g Generator) markerPreviewVideo(input string, options sceneMarkerOptions)
|
||||||
)
|
)
|
||||||
|
|
||||||
trimOptions := transcoder.TranscodeOptions{
|
trimOptions := transcoder.TranscodeOptions{
|
||||||
Duration: markerPreviewDuration,
|
Duration: options.Duration,
|
||||||
StartTime: float64(options.Seconds),
|
StartTime: options.Seconds,
|
||||||
OutputPath: tmpFn,
|
OutputPath: tmpFn,
|
||||||
VideoCodec: ffmpeg.VideoCodecLibX264,
|
VideoCodec: ffmpeg.VideoCodecLibX264,
|
||||||
VideoArgs: videoArgs,
|
VideoArgs: videoArgs,
|
||||||
|
|
@ -90,11 +99,11 @@ func (g Generator) markerPreviewVideo(input string, options sceneMarkerOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Generator) SceneMarkerWebp(ctx context.Context, input string, hash string, seconds int) error {
|
func (g Generator) SceneMarkerWebp(ctx context.Context, input string, hash string, seconds float64) error {
|
||||||
lockCtx := g.LockManager.ReadLock(ctx, input)
|
lockCtx := g.LockManager.ReadLock(ctx, input)
|
||||||
defer lockCtx.Cancel()
|
defer lockCtx.Cancel()
|
||||||
|
|
||||||
output := g.MarkerPaths.GetWebpPreviewPath(hash, seconds)
|
output := g.MarkerPaths.GetWebpPreviewPath(hash, int(seconds))
|
||||||
if !g.Overwrite {
|
if !g.Overwrite {
|
||||||
if exists, _ := fsutil.FileExists(output); exists {
|
if exists, _ := fsutil.FileExists(output); exists {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -143,11 +152,11 @@ func (g Generator) sceneMarkerWebp(input string, options sceneMarkerOptions) gen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Generator) SceneMarkerScreenshot(ctx context.Context, input string, hash string, seconds int, width int) error {
|
func (g Generator) SceneMarkerScreenshot(ctx context.Context, input string, hash string, seconds float64, width int) error {
|
||||||
lockCtx := g.LockManager.ReadLock(ctx, input)
|
lockCtx := g.LockManager.ReadLock(ctx, input)
|
||||||
defer lockCtx.Cancel()
|
defer lockCtx.Cancel()
|
||||||
|
|
||||||
output := g.MarkerPaths.GetScreenshotPath(hash, seconds)
|
output := g.MarkerPaths.GetScreenshotPath(hash, int(seconds))
|
||||||
if !g.Overwrite {
|
if !g.Overwrite {
|
||||||
if exists, _ := fsutil.FileExists(output); exists {
|
if exists, _ := fsutil.FileExists(output); exists {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -167,7 +176,7 @@ func (g Generator) SceneMarkerScreenshot(ctx context.Context, input string, hash
|
||||||
}
|
}
|
||||||
|
|
||||||
type SceneMarkerScreenshotOptions struct {
|
type SceneMarkerScreenshotOptions struct {
|
||||||
Seconds int
|
Seconds float64
|
||||||
Width int
|
Width int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,7 +189,7 @@ func (g Generator) sceneMarkerScreenshot(input string, options SceneMarkerScreen
|
||||||
Width: options.Width,
|
Width: options.Width,
|
||||||
}
|
}
|
||||||
|
|
||||||
args := transcoder.ScreenshotTime(input, float64(options.Seconds), ssOptions)
|
args := transcoder.ScreenshotTime(input, options.Seconds, ssOptions)
|
||||||
|
|
||||||
return g.generate(lockCtx, args)
|
return g.generate(lockCtx, args)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue