Skip to content

Commit

Permalink
Generate cover image (#376)
Browse files Browse the repository at this point in the history
* Make mutating metadata ops mutation
* Implement scene generate screenshot
* Remove fetch policy on metadata mutations
* Port UI changes to v2.5
* Set generated image in database
  • Loading branch information
WithoutPants authored Mar 11, 2020
1 parent 34d8293 commit 3de6955
Show file tree
Hide file tree
Showing 28 changed files with 442 additions and 168 deletions.
27 changes: 27 additions & 0 deletions graphql/documents/mutations/metadata.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
mutation MetadataImport {
metadataImport
}

mutation MetadataExport {
metadataExport
}

mutation MetadataScan($input: ScanMetadataInput!) {
metadataScan(input: $input)
}

mutation MetadataGenerate($input: GenerateMetadataInput!) {
metadataGenerate(input: $input)
}

mutation MetadataAutoTag($input: AutoTagMetadataInput!) {
metadataAutoTag(input: $input)
}

mutation MetadataClean {
metadataClean
}

mutation StopJob {
stopJob
}
6 changes: 5 additions & 1 deletion graphql/documents/mutations/scene.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ mutation SceneResetO($id: ID!) {

mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
}
}

mutation SceneGenerateScreenshot($id: ID!, $at: Float) {
sceneGenerateScreenshot(id: $id, at: $at)
}
28 changes: 0 additions & 28 deletions graphql/documents/queries/settings/metadata.graphql
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
query MetadataImport {
metadataImport
}

query MetadataExport {
metadataExport
}

query MetadataScan($input: ScanMetadataInput!) {
metadataScan(input: $input)
}

query MetadataGenerate($input: GenerateMetadataInput!) {
metadataGenerate(input: $input)
}

query MetadataAutoTag($input: AutoTagMetadataInput!) {
metadataAutoTag(input: $input)
}

query MetadataClean {
metadataClean
}

query JobStatus {
jobStatus {
progress
status
message
}
}

query StopJob {
stopJob
}
32 changes: 18 additions & 14 deletions graphql/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,7 @@ type Query {

# Metadata

"""Start an import. Returns the job ID"""
metadataImport: String!
"""Start an export. Returns the job ID"""
metadataExport: String!
"""Start a scan. Returns the job ID"""
metadataScan(input: ScanMetadataInput!): String!
"""Start generating content. Returns the job ID"""
metadataGenerate(input: GenerateMetadataInput!): String!
"""Start auto-tagging. Returns the job ID"""
metadataAutoTag(input: AutoTagMetadataInput!): String!
"""Clean metadata. Returns the job ID"""
metadataClean: String!

jobStatus: MetadataUpdateStatus!
stopJob: Boolean!

# Get everything

Expand Down Expand Up @@ -120,6 +106,9 @@ type Mutation {
"""Resets the o-counter for a scene to 0. Returns the new value"""
sceneResetO(id: ID!): Int!

"""Generates screenshot at specified time in seconds. Leave empty to generate default screenshot"""
sceneGenerateScreenshot(id: ID!, at: Float): String!

sceneMarkerCreate(input: SceneMarkerCreateInput!): SceneMarker
sceneMarkerUpdate(input: SceneMarkerUpdateInput!): SceneMarker
sceneMarkerDestroy(id: ID!): Boolean!
Expand All @@ -143,6 +132,21 @@ type Mutation {
"""Change general configuration options"""
configureGeneral(input: ConfigGeneralInput!): ConfigGeneralResult!
configureInterface(input: ConfigInterfaceInput!): ConfigInterfaceResult!

"""Start an import. Returns the job ID"""
metadataImport: String!
"""Start an export. Returns the job ID"""
metadataExport: String!
"""Start a scan. Returns the job ID"""
metadataScan(input: ScanMetadataInput!): String!
"""Start generating content. Returns the job ID"""
metadataGenerate(input: GenerateMetadataInput!): String!
"""Start auto-tagging. Returns the job ID"""
metadataAutoTag(input: AutoTagMetadataInput!): String!
"""Clean metadata. Returns the job ID"""
metadataClean: String!

stopJob: Boolean!
}

type Subscription {
Expand Down
53 changes: 53 additions & 0 deletions pkg/api/resolver_mutation_metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package api

import (
"context"

"github.com/stashapp/stash/pkg/manager"
"github.com/stashapp/stash/pkg/models"
)

func (r *mutationResolver) MetadataScan(ctx context.Context, input models.ScanMetadataInput) (string, error) {
manager.GetInstance().Scan(input.UseFileMetadata)
return "todo", nil
}

func (r *mutationResolver) MetadataImport(ctx context.Context) (string, error) {
manager.GetInstance().Import()
return "todo", nil
}

func (r *mutationResolver) MetadataExport(ctx context.Context) (string, error) {
manager.GetInstance().Export()
return "todo", nil
}

func (r *mutationResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
return "todo", nil
}

func (r *mutationResolver) MetadataAutoTag(ctx context.Context, input models.AutoTagMetadataInput) (string, error) {
manager.GetInstance().AutoTag(input.Performers, input.Studios, input.Tags)
return "todo", nil
}

func (r *mutationResolver) MetadataClean(ctx context.Context) (string, error) {
manager.GetInstance().Clean()
return "todo", nil
}

func (r *mutationResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateStatus, error) {
status := manager.GetInstance().Status
ret := models.MetadataUpdateStatus{
Progress: status.Progress,
Status: status.Status.String(),
Message: "",
}

return &ret, nil
}

func (r *mutationResolver) StopJob(ctx context.Context) (bool, error) {
return manager.GetInstance().Status.Stop(), nil
}
10 changes: 10 additions & 0 deletions pkg/api/resolver_mutation_scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,13 @@ func (r *mutationResolver) SceneResetO(ctx context.Context, id string) (int, err

return newVal, nil
}

func (r *mutationResolver) SceneGenerateScreenshot(ctx context.Context, id string, at *float64) (string, error) {
if at != nil {
manager.GetInstance().GenerateScreenshot(id, *at)
} else {
manager.GetInstance().GenerateDefaultScreenshot(id)
}

return "todo", nil
}
34 changes: 0 additions & 34 deletions pkg/api/resolver_query_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,6 @@ import (
"github.com/stashapp/stash/pkg/models"
)

func (r *queryResolver) MetadataScan(ctx context.Context, input models.ScanMetadataInput) (string, error) {
manager.GetInstance().Scan(input.UseFileMetadata)
return "todo", nil
}

func (r *queryResolver) MetadataImport(ctx context.Context) (string, error) {
manager.GetInstance().Import()
return "todo", nil
}

func (r *queryResolver) MetadataExport(ctx context.Context) (string, error) {
manager.GetInstance().Export()
return "todo", nil
}

func (r *queryResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
return "todo", nil
}

func (r *queryResolver) MetadataAutoTag(ctx context.Context, input models.AutoTagMetadataInput) (string, error) {
manager.GetInstance().AutoTag(input.Performers, input.Studios, input.Tags)
return "todo", nil
}

func (r *queryResolver) MetadataClean(ctx context.Context) (string, error) {
manager.GetInstance().Clean()
return "todo", nil
}

func (r *queryResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateStatus, error) {
status := manager.GetInstance().Status
ret := models.MetadataUpdateStatus{
Expand All @@ -47,7 +17,3 @@ func (r *queryResolver) JobStatus(ctx context.Context) (*models.MetadataUpdateSt

return &ret, nil
}

func (r *queryResolver) StopJob(ctx context.Context) (bool, error) {
return manager.GetInstance().Status.Stop(), nil
}
6 changes: 4 additions & 2 deletions pkg/ffmpeg/encoder_screenshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type ScreenshotOptions struct {
Verbosity string
}

func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) {
func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) error {
if options.Verbosity == "" {
options.Verbosity = "error"
}
Expand All @@ -28,5 +28,7 @@ func (e *Encoder) Screenshot(probeResult VideoFile, options ScreenshotOptions) {
"-f", "image2",
options.OutputPath,
}
_, _ = e.run(probeResult, args)
_, err := e.run(probeResult, args)

return err
}
49 changes: 49 additions & 0 deletions pkg/manager/manager_tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,55 @@ func (s *singleton) Generate(sprites bool, previews bool, markers bool, transcod
}()
}

func (s *singleton) GenerateDefaultScreenshot(sceneId string) {
s.generateScreenshot(sceneId, nil)
}

func (s *singleton) GenerateScreenshot(sceneId string, at float64) {
s.generateScreenshot(sceneId, &at)
}

// generate default screenshot if at is nil
func (s *singleton) generateScreenshot(sceneId string, at *float64) {
if s.Status.Status != Idle {
return
}
s.Status.SetStatus(Generate)
s.Status.indefiniteProgress()

qb := models.NewSceneQueryBuilder()
instance.Paths.Generated.EnsureTmpDir()

go func() {
defer s.returnToIdleState()

sceneIdInt, err := strconv.Atoi(sceneId)
if err != nil {
logger.Errorf("Error parsing scene id %s: %s", sceneId, err.Error())
return
}

scene, err := qb.Find(sceneIdInt)
if err != nil || scene == nil {
logger.Errorf("failed to get scene for generate")
return
}

task := GenerateScreenshotTask{
Scene: *scene,
ScreenshotAt: at,
}

var wg sync.WaitGroup
wg.Add(1)
go task.Start(&wg)

wg.Wait()

logger.Infof("Generate finished")
}()
}

func (s *singleton) AutoTag(performerIds []string, studioIds []string, tagIds []string) {
if s.Status.Status != Idle {
return
Expand Down
16 changes: 16 additions & 0 deletions pkg/manager/screenshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package manager

import (
"github.com/stashapp/stash/pkg/ffmpeg"
)

func makeScreenshot(probeResult ffmpeg.VideoFile, outputPath string, quality int, width int, time float64) {
encoder := ffmpeg.NewEncoder(instance.FFMPEGPath)
options := ffmpeg.ScreenshotOptions{
OutputPath: outputPath,
Quality: quality,
Time: time,
Width: width,
}
encoder.Screenshot(probeResult, options)
}
Loading

0 comments on commit 3de6955

Please sign in to comment.