mirror of
https://github.com/photoprism/photoprism.git
synced 2025-09-27 05:08:13 +08:00
155 lines
4.6 KiB
Go
155 lines
4.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"github.com/photoprism/photoprism/internal/ffmpeg/encode"
|
|
"github.com/photoprism/photoprism/internal/thumb"
|
|
"github.com/photoprism/photoprism/pkg/fs"
|
|
"github.com/photoprism/photoprism/pkg/txt"
|
|
)
|
|
|
|
// FFmpegBin returns the ffmpeg executable file name.
|
|
func (c *Config) FFmpegBin() string {
|
|
return FindBin(c.options.FFmpegBin, encode.FFmpegBin)
|
|
}
|
|
|
|
// FFprobeBin returns the ffprobe executable file name.
|
|
func (c *Config) FFprobeBin() string {
|
|
if ffmpegBin := c.FFmpegBin(); ffmpegBin != "" && fs.FileExistsNotEmpty(ffmpegBin) {
|
|
return FindBin(filepath.Join(filepath.Dir(ffmpegBin), encode.FFprobeBin), encode.FFprobeBin)
|
|
}
|
|
|
|
return FindBin(encode.FFprobeBin)
|
|
}
|
|
|
|
// YtDlpBin returns the name of the video download executable file, if installed.
|
|
func (c *Config) YtDlpBin() string {
|
|
return FindBin("yt-dlp", "yt-dl", "youtube-dl", "dl")
|
|
}
|
|
|
|
// FFmpegEnabled checks if FFmpeg is enabled for video transcoding.
|
|
func (c *Config) FFmpegEnabled() bool {
|
|
return !c.DisableFFmpeg()
|
|
}
|
|
|
|
// FFmpegEncoder returns the FFmpeg AVC encoder name.
|
|
func (c *Config) FFmpegEncoder() encode.Encoder {
|
|
if c.options.FFmpegEncoder == encode.SoftwareAvc.String() {
|
|
return encode.SoftwareAvc
|
|
} else if c.options.FFmpegEncoder == "" {
|
|
return encode.DefaultAvcEncoder()
|
|
}
|
|
|
|
return encode.FindEncoder(c.options.FFmpegEncoder)
|
|
}
|
|
|
|
// FFmpegSize returns the maximum ffmpeg video encoding size in pixels (720-7680).
|
|
func (c *Config) FFmpegSize() int {
|
|
return thumb.VideoSize(c.options.FFmpegSize).Width
|
|
}
|
|
|
|
// FFmpegQuality returns the ffmpeg encoding quality from 1 to 100,
|
|
// with a default of 50 and where 100 is almost lossless.
|
|
func (c *Config) FFmpegQuality() int {
|
|
switch {
|
|
case c.options.FFmpegQuality <= 0:
|
|
return encode.DefaultQuality
|
|
case c.options.FFmpegQuality < encode.WorstQuality:
|
|
return encode.WorstQuality
|
|
case c.options.FFmpegQuality > 100:
|
|
return encode.BestQuality
|
|
default:
|
|
return c.options.FFmpegQuality
|
|
}
|
|
}
|
|
|
|
// FFmpegBitrate returns the ffmpeg bitrate limit in Mbps for non-AVC videos to be transcoded
|
|
// even if they could be played natively (optional).
|
|
func (c *Config) FFmpegBitrate() int {
|
|
switch {
|
|
case c.options.FFmpegBitrate < 0:
|
|
return encode.NoBitrateLimit
|
|
case c.options.FFmpegBitrate == 0:
|
|
return encode.DefaultBitrateLimit
|
|
case c.options.FFmpegBitrate < encode.MinBitrateLimit:
|
|
return encode.MinBitrateLimit
|
|
case c.options.FFmpegBitrate >= encode.MaxBitrateLimit:
|
|
return encode.MaxBitrateLimit
|
|
default:
|
|
return c.options.FFmpegBitrate
|
|
}
|
|
}
|
|
|
|
// FFmpegBitrateExceeded tests if the ffmpeg bitrate limit in Mbps is exceeded.
|
|
func (c *Config) FFmpegBitrateExceeded(bitrate float64) bool {
|
|
if bitrate <= 0 {
|
|
return false
|
|
} else if limit := c.FFmpegBitrate(); limit <= 0 {
|
|
return false
|
|
} else {
|
|
return bitrate > float64(limit)
|
|
}
|
|
}
|
|
|
|
// FFmpegPreset returns the ffmpeg encoding preset from "ultrafast" to "veryslow",
|
|
// see https://trac.ffmpeg.org/wiki/Encode/H.264#Preset.
|
|
func (c *Config) FFmpegPreset() string {
|
|
if c.options.FFmpegPreset == "" {
|
|
return encode.PresetFast
|
|
}
|
|
|
|
return c.options.FFmpegPreset
|
|
}
|
|
|
|
// FFmpegDevice returns the ffmpeg device path for supported hardware encoders (optional).
|
|
func (c *Config) FFmpegDevice() string {
|
|
if c.options.FFmpegDevice == "" {
|
|
return ""
|
|
} else if txt.IsUInt(c.options.FFmpegDevice) {
|
|
return c.options.FFmpegDevice
|
|
} else if fs.DeviceExists(c.options.FFmpegDevice) {
|
|
return c.options.FFmpegDevice
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// FFmpegMapVideo returns the video streams to be transcoded as string.
|
|
func (c *Config) FFmpegMapVideo() string {
|
|
if c.options.FFmpegMapVideo == "" {
|
|
return encode.DefaultMapVideo
|
|
}
|
|
|
|
return c.options.FFmpegMapVideo
|
|
}
|
|
|
|
// FFmpegMapAudio returns the audio streams to be transcoded as string.
|
|
func (c *Config) FFmpegMapAudio() string {
|
|
if c.options.FFmpegMapAudio == "" {
|
|
return encode.DefaultMapAudio
|
|
}
|
|
|
|
return c.options.FFmpegMapAudio
|
|
}
|
|
|
|
// FFmpegOptions returns the FFmpeg options to use for video transcoding.
|
|
func (c *Config) FFmpegOptions(encoder encode.Encoder, bitrate string) (encode.Options, error) {
|
|
// Get options to transcode other formats with FFmpeg.
|
|
opt := encode.NewVideoOptions(c.FFmpegBin(), encoder, c.FFmpegSize(), c.FFmpegQuality(), c.FFmpegPreset(), c.FFmpegDevice(), c.FFmpegMapVideo(), c.FFmpegMapAudio())
|
|
|
|
// Check options and return error if invalid.
|
|
if opt.Bin == "" {
|
|
return opt, fmt.Errorf("ffmpeg is not installed")
|
|
} else if c.DisableFFmpeg() {
|
|
return opt, fmt.Errorf("ffmpeg is disabled")
|
|
} else if bitrate == "" {
|
|
return opt, fmt.Errorf("bitrate must not be empty")
|
|
} else if encoder.String() == "" {
|
|
return opt, fmt.Errorf("encoder must not be empty")
|
|
}
|
|
|
|
return opt, nil
|
|
}
|