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:
WithoutPants
2022-04-18 10:50:10 +10:00
committed by GitHub
parent cdaa191155
commit aacf07feef
89 changed files with 3208 additions and 2004 deletions

View File

@@ -12,6 +12,7 @@ import (
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/scene"
"github.com/stashapp/stash/pkg/scene/generate"
"github.com/stashapp/stash/pkg/sliceutil/stringslice"
"github.com/stashapp/stash/pkg/utils"
)
@@ -67,15 +68,23 @@ func (j *GenerateJob) Execute(ctx context.Context, progress *job.Progress) {
logger.Error(err.Error())
}
g := &generate.Generator{
Encoder: instance.FFMPEG,
LockManager: instance.ReadLockManager,
MarkerPaths: instance.Paths.SceneMarkers,
ScenePaths: instance.Paths.Scene,
Overwrite: j.overwrite,
}
if err := j.txnManager.WithReadTxn(ctx, func(r models.ReaderRepository) error {
qb := r.Scene()
if len(j.input.SceneIDs) == 0 && len(j.input.MarkerIDs) == 0 {
totals = j.queueTasks(ctx, queue)
totals = j.queueTasks(ctx, g, queue)
} else {
if len(j.input.SceneIDs) > 0 {
scenes, err = qb.FindMany(sceneIDs)
for _, s := range scenes {
j.queueSceneJobs(ctx, s, queue, &totals)
j.queueSceneJobs(ctx, g, s, queue, &totals)
}
}
@@ -85,7 +94,7 @@ func (j *GenerateJob) Execute(ctx context.Context, progress *job.Progress) {
return err
}
for _, m := range markers {
j.queueMarkerJob(m, queue, &totals)
j.queueMarkerJob(g, m, queue, &totals)
}
}
}
@@ -142,7 +151,7 @@ func (j *GenerateJob) Execute(ctx context.Context, progress *job.Progress) {
logger.Info(fmt.Sprintf("Generate finished (%s)", elapsed))
}
func (j *GenerateJob) queueTasks(ctx context.Context, queue chan<- Task) totalsGenerate {
func (j *GenerateJob) queueTasks(ctx context.Context, g *generate.Generator, queue chan<- Task) totalsGenerate {
var totals totalsGenerate
const batchSize = 1000
@@ -165,7 +174,7 @@ func (j *GenerateJob) queueTasks(ctx context.Context, queue chan<- Task) totalsG
return context.Canceled
}
j.queueSceneJobs(ctx, ss, queue, &totals)
j.queueSceneJobs(ctx, g, ss, queue, &totals)
}
if len(scenes) != batchSize {
@@ -185,7 +194,42 @@ func (j *GenerateJob) queueTasks(ctx context.Context, queue chan<- Task) totalsG
return totals
}
func (j *GenerateJob) queueSceneJobs(ctx context.Context, scene *models.Scene, queue chan<- Task, totals *totalsGenerate) {
func getGeneratePreviewOptions(optionsInput models.GeneratePreviewOptionsInput) generate.PreviewOptions {
config := config.GetInstance()
ret := generate.PreviewOptions{
Segments: config.GetPreviewSegments(),
SegmentDuration: config.GetPreviewSegmentDuration(),
ExcludeStart: config.GetPreviewExcludeStart(),
ExcludeEnd: config.GetPreviewExcludeEnd(),
Preset: config.GetPreviewPreset().String(),
Audio: config.GetPreviewAudio(),
}
if optionsInput.PreviewSegments != nil {
ret.Segments = *optionsInput.PreviewSegments
}
if optionsInput.PreviewSegmentDuration != nil {
ret.SegmentDuration = *optionsInput.PreviewSegmentDuration
}
if optionsInput.PreviewExcludeStart != nil {
ret.ExcludeStart = *optionsInput.PreviewExcludeStart
}
if optionsInput.PreviewExcludeEnd != nil {
ret.ExcludeEnd = *optionsInput.PreviewExcludeEnd
}
if optionsInput.PreviewPreset != nil {
ret.Preset = optionsInput.PreviewPreset.String()
}
return ret
}
func (j *GenerateJob) queueSceneJobs(ctx context.Context, g *generate.Generator, scene *models.Scene, queue chan<- Task, totals *totalsGenerate) {
if utils.IsTrue(j.input.Sprites) {
task := &GenerateSpriteTask{
Scene: *scene,
@@ -200,19 +244,21 @@ func (j *GenerateJob) queueSceneJobs(ctx context.Context, scene *models.Scene, q
}
}
generatePreviewOptions := j.input.PreviewOptions
if generatePreviewOptions == nil {
generatePreviewOptions = &models.GeneratePreviewOptionsInput{}
}
options := getGeneratePreviewOptions(*generatePreviewOptions)
if utils.IsTrue(j.input.Previews) {
generatePreviewOptions := j.input.PreviewOptions
if generatePreviewOptions == nil {
generatePreviewOptions = &models.GeneratePreviewOptionsInput{}
}
setGeneratePreviewOptionsInput(generatePreviewOptions)
task := &GeneratePreviewTask{
Scene: *scene,
ImagePreview: utils.IsTrue(j.input.ImagePreviews),
Options: *generatePreviewOptions,
Options: options,
Overwrite: j.overwrite,
fileNamingAlgorithm: j.fileNamingAlgo,
generator: g,
}
sceneHash := scene.GetHash(task.fileNamingAlgorithm)
@@ -241,6 +287,8 @@ func (j *GenerateJob) queueSceneJobs(ctx context.Context, scene *models.Scene, q
fileNamingAlgorithm: j.fileNamingAlgo,
ImagePreview: utils.IsTrue(j.input.MarkerImagePreviews),
Screenshot: utils.IsTrue(j.input.MarkerScreenshots),
generator: g,
}
markers := task.markersNeeded(ctx)
@@ -259,6 +307,7 @@ func (j *GenerateJob) queueSceneJobs(ctx context.Context, scene *models.Scene, q
Overwrite: j.overwrite,
Force: forceTranscode,
fileNamingAlgorithm: j.fileNamingAlgo,
g: g,
}
if task.isTranscodeNeeded() {
totals.transcodes++
@@ -298,12 +347,13 @@ func (j *GenerateJob) queueSceneJobs(ctx context.Context, scene *models.Scene, q
}
}
func (j *GenerateJob) queueMarkerJob(marker *models.SceneMarker, queue chan<- Task, totals *totalsGenerate) {
func (j *GenerateJob) queueMarkerJob(g *generate.Generator, marker *models.SceneMarker, queue chan<- Task, totals *totalsGenerate) {
task := &GenerateMarkersTask{
TxnManager: j.txnManager,
Marker: marker,
Overwrite: j.overwrite,
fileNamingAlgorithm: j.fileNamingAlgo,
generator: g,
}
totals.markers++
totals.tasks++