From b3966b3c76829e50e2e60c21cf274b8185d075dd Mon Sep 17 00:00:00 2001 From: WithoutPants <53250216+WithoutPants@users.noreply.github.com> Date: Thu, 11 Mar 2021 12:51:42 +1100 Subject: [PATCH] Remove streaming resolutions over max configured (#1187) --- pkg/api/resolver_query_scene.go | 3 +- pkg/manager/scene.go | 141 +++++++----------- pkg/models/model_scene.go | 8 + .../src/components/Changelog/versions/v060.md | 1 + 4 files changed, 69 insertions(+), 84 deletions(-) diff --git a/pkg/api/resolver_query_scene.go b/pkg/api/resolver_query_scene.go index bffbcfd6f..64110e70d 100644 --- a/pkg/api/resolver_query_scene.go +++ b/pkg/api/resolver_query_scene.go @@ -7,6 +7,7 @@ import ( "github.com/stashapp/stash/pkg/api/urlbuilders" "github.com/stashapp/stash/pkg/manager" + "github.com/stashapp/stash/pkg/manager/config" "github.com/stashapp/stash/pkg/models" ) @@ -29,5 +30,5 @@ func (r *queryResolver) SceneStreams(ctx context.Context, id *string) ([]*models baseURL, _ := ctx.Value(BaseURLCtxKey).(string) builder := urlbuilders.NewSceneURLBuilder(baseURL, scene.ID) - return manager.GetSceneStreamPaths(scene, builder.GetStreamURL()) + return manager.GetSceneStreamPaths(scene, builder.GetStreamURL(), config.GetMaxStreamingTranscodeSize()) } diff --git a/pkg/manager/scene.go b/pkg/manager/scene.go index 55495da81..52ff02e5f 100644 --- a/pkg/manager/scene.go +++ b/pkg/manager/scene.go @@ -194,7 +194,38 @@ func GetSceneFileContainer(scene *models.Scene) (ffmpeg.Container, error) { return container, nil } -func GetSceneStreamPaths(scene *models.Scene, directStreamURL string) ([]*models.SceneStreamEndpoint, error) { +func includeSceneStreamPath(scene *models.Scene, streamingResolution models.StreamingResolutionEnum, maxStreamingTranscodeSize models.StreamingResolutionEnum) bool { + // convert StreamingResolutionEnum to ResolutionEnum so we can get the min + // resolution + convertedRes := models.ResolutionEnum(streamingResolution) + + minResolution := int64(convertedRes.GetMinResolution()) + sceneResolution := scene.GetMinResolution() + + // don't include if scene resolution is smaller than the streamingResolution + if sceneResolution != 0 && sceneResolution < minResolution { + return false + } + + // if we always allow everything, then return true + if maxStreamingTranscodeSize == models.StreamingResolutionEnumOriginal { + return true + } + + // convert StreamingResolutionEnum to ResolutionEnum + maxStreamingResolution := models.ResolutionEnum(maxStreamingTranscodeSize) + return int64(maxStreamingResolution.GetMinResolution()) >= minResolution +} + +func makeStreamEndpoint(streamURL string, streamingResolution models.StreamingResolutionEnum, mimeType, label string) *models.SceneStreamEndpoint { + return &models.SceneStreamEndpoint{ + URL: fmt.Sprintf("%s?resolution=%s", streamURL, streamingResolution.String()), + MimeType: &mimeType, + Label: &label, + } +} + +func GetSceneStreamPaths(scene *models.Scene, directStreamURL string, maxStreamingTranscodeSize models.StreamingResolutionEnum) ([]*models.SceneStreamEndpoint, error) { if scene == nil { return nil, fmt.Errorf("nil scene") } @@ -248,107 +279,51 @@ func GetSceneStreamPaths(scene *models.Scene, directStreamURL string) ([]*models // Note: These have the wrong mime type intentionally to allow jwplayer to selection between mp4/webm webmLabelFourK := "WEBM 4K (2160p)" // "FOUR_K" webmLabelFullHD := "WEBM Full HD (1080p)" // "FULL_HD" - webmLabelStardardHD := "WEBM HD (720p)" // "STANDARD_HD" + webmLabelStandardHD := "WEBM HD (720p)" // "STANDARD_HD" webmLabelStandard := "WEBM Standard (480p)" // "STANDARD" webmLabelLow := "WEBM Low (240p)" // "LOW" - if !scene.Height.Valid || scene.Height.Int64 >= 2160 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".webm?resolution=FOUR_K", - MimeType: &mimeMp4, - Label: &webmLabelFourK, - } - ret = append(ret, &new) - } - - if !scene.Height.Valid || scene.Height.Int64 >= 1080 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".webm?resolution=FULL_HD", - MimeType: &mimeMp4, - Label: &webmLabelFullHD, - } - ret = append(ret, &new) - } - - if !scene.Height.Valid || scene.Height.Int64 >= 720 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".webm?resolution=STANDARD_HD", - MimeType: &mimeMp4, - Label: &webmLabelStardardHD, - } - ret = append(ret, &new) - } - - if !scene.Height.Valid || scene.Height.Int64 >= 480 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".webm?resolution=STANDARD", - MimeType: &mimeMp4, - Label: &webmLabelStandard, - } - ret = append(ret, &new) - } - - if !scene.Height.Valid || scene.Height.Int64 >= 240 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".webm?resolution=LOW", - MimeType: &mimeMp4, - Label: &webmLabelLow, - } - ret = append(ret, &new) - } - // Setup up lower quality transcoding options (MP4) mp4LabelFourK := "MP4 4K (2160p)" // "FOUR_K" mp4LabelFullHD := "MP4 Full HD (1080p)" // "FULL_HD" - mp4LabelStardardHD := "MP4 HD (720p)" // "STANDARD_HD" + mp4LabelStandardHD := "MP4 HD (720p)" // "STANDARD_HD" mp4LabelStandard := "MP4 Standard (480p)" // "STANDARD" mp4LabelLow := "MP4 Low (240p)" // "LOW" - if !scene.Height.Valid || scene.Height.Int64 >= 2160 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".mp4?resolution=FOUR_K", - MimeType: &mimeMp4, - Label: &mp4LabelFourK, - } - ret = append(ret, &new) + var webmStreams []*models.SceneStreamEndpoint + var mp4Streams []*models.SceneStreamEndpoint + + webmURL := directStreamURL + ".webm" + mp4URL := directStreamURL + ".mp4" + + if includeSceneStreamPath(scene, models.StreamingResolutionEnumFourK, maxStreamingTranscodeSize) { + webmStreams = append(webmStreams, makeStreamEndpoint(webmURL, models.StreamingResolutionEnumFourK, mimeMp4, webmLabelFourK)) + mp4Streams = append(mp4Streams, makeStreamEndpoint(mp4URL, models.StreamingResolutionEnumFourK, mimeMp4, mp4LabelFourK)) } - if !scene.Height.Valid || scene.Height.Int64 >= 1080 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".mp4?resolution=FULL_HD", - MimeType: &mimeMp4, - Label: &mp4LabelFullHD, - } - ret = append(ret, &new) + if includeSceneStreamPath(scene, models.StreamingResolutionEnumFullHd, maxStreamingTranscodeSize) { + webmStreams = append(webmStreams, makeStreamEndpoint(webmURL, models.StreamingResolutionEnumFullHd, mimeMp4, webmLabelFullHD)) + mp4Streams = append(mp4Streams, makeStreamEndpoint(mp4URL, models.StreamingResolutionEnumFullHd, mimeMp4, mp4LabelFullHD)) } - if !scene.Height.Valid || scene.Height.Int64 >= 720 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".mp4?resolution=STANDARD_HD", - MimeType: &mimeMp4, - Label: &mp4LabelStardardHD, - } - ret = append(ret, &new) + if includeSceneStreamPath(scene, models.StreamingResolutionEnumStandardHd, maxStreamingTranscodeSize) { + webmStreams = append(webmStreams, makeStreamEndpoint(webmURL, models.StreamingResolutionEnumStandardHd, mimeMp4, webmLabelStandardHD)) + mp4Streams = append(mp4Streams, makeStreamEndpoint(mp4URL, models.StreamingResolutionEnumStandardHd, mimeMp4, mp4LabelStandardHD)) } - if !scene.Height.Valid || scene.Height.Int64 >= 480 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".mp4?resolution=STANDARD", - MimeType: &mimeMp4, - Label: &mp4LabelStandard, - } - ret = append(ret, &new) + if includeSceneStreamPath(scene, models.StreamingResolutionEnumStandard, maxStreamingTranscodeSize) { + webmStreams = append(webmStreams, makeStreamEndpoint(webmURL, models.StreamingResolutionEnumStandard, mimeMp4, webmLabelStandard)) + mp4Streams = append(mp4Streams, makeStreamEndpoint(mp4URL, models.StreamingResolutionEnumStandard, mimeMp4, mp4LabelStandard)) } - if !scene.Height.Valid || scene.Height.Int64 >= 240 { - new := models.SceneStreamEndpoint{ - URL: directStreamURL + ".mp4?resolution=LOW", - MimeType: &mimeMp4, - Label: &mp4LabelLow, - } - ret = append(ret, &new) + if includeSceneStreamPath(scene, models.StreamingResolutionEnumLow, maxStreamingTranscodeSize) { + webmStreams = append(webmStreams, makeStreamEndpoint(webmURL, models.StreamingResolutionEnumLow, mimeMp4, webmLabelLow)) + mp4Streams = append(mp4Streams, makeStreamEndpoint(mp4URL, models.StreamingResolutionEnumLow, mimeMp4, mp4LabelLow)) } + ret = append(ret, webmStreams...) + ret = append(ret, mp4Streams...) + defaultStreams := []*models.SceneStreamEndpoint{ { URL: directStreamURL + ".webm", diff --git a/pkg/models/model_scene.go b/pkg/models/model_scene.go index 3d1abbf76..40bcd43e9 100644 --- a/pkg/models/model_scene.go +++ b/pkg/models/model_scene.go @@ -84,6 +84,14 @@ func (s Scene) GetHash(hashAlgorithm HashAlgorithm) string { panic("unknown hash algorithm") } +func (s Scene) GetMinResolution() int64 { + if s.Width.Int64 < s.Height.Int64 { + return s.Width.Int64 + } + + return s.Height.Int64 +} + // SceneFileType represents the file metadata for a scene. type SceneFileType struct { Size *string `graphql:"size" json:"size"` diff --git a/ui/v2.5/src/components/Changelog/versions/v060.md b/ui/v2.5/src/components/Changelog/versions/v060.md index 170612ccc..4d9c8b66c 100644 --- a/ui/v2.5/src/components/Changelog/versions/v060.md +++ b/ui/v2.5/src/components/Changelog/versions/v060.md @@ -17,6 +17,7 @@ * Added Rescan button to scene, image, gallery details overflow button. ### 🐛 Bug fixes +* Filter out streaming resolution options that are over the maximum streaming resolution. * Fix `cover.jpg` not being detected as cover image when in sub-directory. * Fix scan re-associating galleries to the same scene. * Fix SQL error when filtering galleries excluding performers or tags.