mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-09 19:07:12 +02:00
* refactor(scanner): remove the legacy ffmpeg metadata extractor The ffmpeg extractor in scanner/metadata_old has not been wired into the scanner since the taglib-only rewrite, so it was only exercised by its own tests. Remove the package, the FFmpeg.Probe method and its ffmetadata command that only it used, and the startup fallback for Scanner.Extractor="ffmpeg". Configs that still set it keep working: unknown extractors already fall back to taglib with a warning. * fix(conf): warn and fall back to taglib for an unknown Scanner.Extractor Validate the option when loading the config, so invalid values such as the removed "ffmpeg" extractor are reported once at startup instead of only when a library storage is created.
91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package tests
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
|
|
"github.com/navidrome/navidrome/core/ffmpeg"
|
|
)
|
|
|
|
func NewMockFFmpeg(data string) *MockFFmpeg {
|
|
return &MockFFmpeg{Reader: strings.NewReader(data), ProbeAvailable: true}
|
|
}
|
|
|
|
type MockFFmpeg struct {
|
|
io.Reader
|
|
lock sync.Mutex
|
|
closed atomic.Bool
|
|
Error error
|
|
ProbeAudioResult *ffmpeg.AudioProbeResult
|
|
ProbeAvailable bool
|
|
}
|
|
|
|
func (ff *MockFFmpeg) IsAvailable() bool {
|
|
return true
|
|
}
|
|
|
|
func (ff *MockFFmpeg) IsProbeAvailable() bool {
|
|
return ff.ProbeAvailable
|
|
}
|
|
|
|
func (ff *MockFFmpeg) Transcode(_ context.Context, _ ffmpeg.TranscodeOptions) (io.ReadCloser, error) {
|
|
if ff.Error != nil {
|
|
return nil, ff.Error
|
|
}
|
|
return ff, nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) ExtractImage(context.Context, string) (io.ReadCloser, error) {
|
|
if ff.Error != nil {
|
|
return nil, ff.Error
|
|
}
|
|
return ff, nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) ConvertAnimatedImage(_ context.Context, reader io.Reader, _ int, _ int) (io.ReadCloser, error) {
|
|
if ff.Error != nil {
|
|
return nil, ff.Error
|
|
}
|
|
data, err := io.ReadAll(reader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return io.NopCloser(bytes.NewReader(data)), nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) ProbeAudioStream(context.Context, string) (*ffmpeg.AudioProbeResult, error) {
|
|
if ff.Error != nil {
|
|
return nil, ff.Error
|
|
}
|
|
return ff.ProbeAudioResult, nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) CmdPath() (string, error) {
|
|
if ff.Error != nil {
|
|
return "", ff.Error
|
|
}
|
|
return "ffmpeg", nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) Version() string {
|
|
return "1.0"
|
|
}
|
|
|
|
func (ff *MockFFmpeg) Read(p []byte) (n int, err error) {
|
|
ff.lock.Lock()
|
|
defer ff.lock.Unlock()
|
|
return ff.Reader.Read(p)
|
|
}
|
|
|
|
func (ff *MockFFmpeg) Close() error {
|
|
ff.closed.Store(true)
|
|
return nil
|
|
}
|
|
|
|
func (ff *MockFFmpeg) IsClosed() bool {
|
|
return ff.closed.Load()
|
|
}
|