diff --git a/db/migrations/20260205120000_add_codec_and_update_transcodings.go b/db/migrations/20260307175815_add_codec_and_update_transcodings.go similarity index 84% rename from db/migrations/20260205120000_add_codec_and_update_transcodings.go rename to db/migrations/20260307175815_add_codec_and_update_transcodings.go index c481c9b42..4e8b1b7f5 100644 --- a/db/migrations/20260205120000_add_codec_and_update_transcodings.go +++ b/db/migrations/20260307175815_add_codec_and_update_transcodings.go @@ -50,11 +50,21 @@ func upAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error { return err } } + + // Add probe_data column for caching ffprobe results. + _, err = tx.Exec(`ALTER TABLE media_file ADD COLUMN probe_data TEXT DEFAULT NULL`) + if err != nil { + return err + } return nil } func downAddCodecAndUpdateTranscodings(_ context.Context, tx *sql.Tx) error { - _, err := tx.Exec(`DROP INDEX IF EXISTS media_file_codec`) + _, err := tx.Exec(`ALTER TABLE media_file DROP COLUMN probe_data`) + if err != nil { + return err + } + _, err = tx.Exec(`DROP INDEX IF EXISTS media_file_codec`) if err != nil { return err } diff --git a/model/mediafile.go b/model/mediafile.go index 908540a0f..d04060473 100644 --- a/model/mediafile.go +++ b/model/mediafile.go @@ -58,6 +58,7 @@ type MediaFile struct { BitDepth int `structs:"bit_depth" json:"bitDepth"` Channels int `structs:"channels" json:"channels"` Codec string `structs:"codec" json:"codec"` + ProbeData string `structs:"probe_data" json:"-" hash:"ignore"` Genre string `structs:"genre" json:"genre"` Genres Genres `structs:"-" json:"genres,omitempty"` SortTitle string `structs:"sort_title" json:"sortTitle,omitempty"` @@ -440,6 +441,7 @@ type MediaFileRepository interface { CountBySuffix(options ...QueryOptions) (map[string]int64, error) Exists(id string) (bool, error) Put(m *MediaFile) error + UpdateProbeData(id string, data string) error Get(id string) (*MediaFile, error) GetWithParticipants(id string) (*MediaFile, error) GetAll(options ...QueryOptions) (MediaFiles, error) diff --git a/persistence/mediafile_repository.go b/persistence/mediafile_repository.go index 43736e317..264778ea0 100644 --- a/persistence/mediafile_repository.go +++ b/persistence/mediafile_repository.go @@ -163,6 +163,11 @@ func (r *mediaFileRepository) Put(m *model.MediaFile) error { return r.updateParticipants(m.ID, m.Participants) } +func (r *mediaFileRepository) UpdateProbeData(id string, data string) error { + _, err := r.executeSQL(Update(r.tableName).Set("probe_data", data).Where(Eq{"id": id})) + return err +} + func (r *mediaFileRepository) selectMediaFile(options ...model.QueryOptions) SelectBuilder { sql := r.newSelect(options...).Columns("media_file.*", "library.path as library_path", "library.name as library_name"). LeftJoin("library on media_file.library_id = library.id") diff --git a/tests/mock_mediafile_repo.go b/tests/mock_mediafile_repo.go index 1d4527c88..01eacae30 100644 --- a/tests/mock_mediafile_repo.go +++ b/tests/mock_mediafile_repo.go @@ -109,6 +109,17 @@ func (m *MockMediaFileRepo) Put(mf *model.MediaFile) error { return nil } +func (m *MockMediaFileRepo) UpdateProbeData(id string, data string) error { + if m.Err { + return errors.New("error") + } + if d, ok := m.Data[id]; ok { + d.ProbeData = data + return nil + } + return model.ErrNotFound +} + func (m *MockMediaFileRepo) Delete(id string) error { if m.Err { return errors.New("error")