stash/pkg/file/video/scan.go

58 lines
1.4 KiB
Go
Raw Normal View History

File storage rewrite (#2676) * Restructure data layer part 2 (#2599) * Refactor and separate image model * Refactor image query builder * Handle relationships in image query builder * Remove relationship management methods * Refactor gallery model/query builder * Add scenes to gallery model * Convert scene model * Refactor scene models * Remove unused methods * Add unit tests for gallery * Add image tests * Add scene tests * Convert unnecessary scene value pointers to values * Convert unnecessary pointer values to values * Refactor scene partial * Add scene partial tests * Refactor ImagePartial * Add image partial tests * Refactor gallery partial update * Add partial gallery update tests * Use zero/null package for null values * Add files and scan system * Add sqlite implementation for files/folders * Add unit tests for files/folders * Image refactors * Update image data layer * Refactor gallery model and creation * Refactor scene model * Refactor scenes * Don't set title from filename * Allow galleries to freely add/remove images * Add multiple scene file support to graphql and UI * Add multiple file support for images in graphql/UI * Add multiple file for galleries in graphql/UI * Remove use of some deprecated fields * Remove scene path usage * Remove gallery path usage * Remove path from image * Move funscript to video file * Refactor caption detection * Migrate existing data * Add post commit/rollback hook system * Lint. Comment out import/export tests * Add WithDatabase read only wrapper * Prepend tasks to list * Add 32 pre-migration * Add warnings in release and migration notes
2022-07-13 06:30:54 +00:00
package video
import (
"context"
"errors"
"fmt"
"github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/file"
)
// Decorator adds video specific fields to a File.
type Decorator struct {
FFProbe ffmpeg.FFProbe
}
func (d *Decorator) Decorate(ctx context.Context, fs file.FS, f file.File) (file.File, error) {
if d.FFProbe == "" {
return f, errors.New("ffprobe not configured")
}
base := f.Base()
// TODO - copy to temp file if not an OsFS
if _, isOs := fs.(*file.OsFS); !isOs {
return f, fmt.Errorf("video.constructFile: only OsFS is supported")
}
probe := d.FFProbe
videoFile, err := probe.NewVideoFile(base.Path)
if err != nil {
return f, fmt.Errorf("running ffprobe on %q: %w", base.Path, err)
}
container, err := ffmpeg.MatchContainer(videoFile.Container, base.Path)
if err != nil {
return f, fmt.Errorf("matching container for %q: %w", base.Path, err)
}
// check if there is a funscript file
interactive := false
if _, err := fs.Lstat(GetFunscriptPath(base.Path)); err == nil {
interactive = true
}
return &file.VideoFile{
BaseFile: base,
Format: string(container),
VideoCodec: videoFile.VideoCodec,
AudioCodec: videoFile.AudioCodec,
Width: videoFile.Width,
Height: videoFile.Height,
Duration: videoFile.Duration,
FrameRate: videoFile.FrameRate,
BitRate: videoFile.Bitrate,
Interactive: interactive,
}, nil
}