mirror of https://github.com/stashapp/stash.git
108 lines
2.7 KiB
Go
108 lines
2.7 KiB
Go
package transcoder
|
|
|
|
import "github.com/stashapp/stash/pkg/ffmpeg"
|
|
|
|
type TranscodeOptions struct {
|
|
OutputPath string
|
|
Format ffmpeg.Format
|
|
|
|
VideoCodec ffmpeg.VideoCodec
|
|
VideoArgs ffmpeg.Args
|
|
|
|
AudioCodec ffmpeg.AudioCodec
|
|
AudioArgs ffmpeg.Args
|
|
|
|
// if XError is true, then ffmpeg will fail on warnings
|
|
XError bool
|
|
|
|
StartTime float64
|
|
SlowSeek bool
|
|
Duration float64
|
|
|
|
// Verbosity is the logging verbosity. Defaults to LogLevelError if not set.
|
|
Verbosity ffmpeg.LogLevel
|
|
|
|
// arguments added before the input argument
|
|
ExtraInputArgs []string
|
|
// arguments added before the output argument
|
|
ExtraOutputArgs []string
|
|
}
|
|
|
|
func (o *TranscodeOptions) setDefaults() {
|
|
if o.Verbosity == "" {
|
|
o.Verbosity = ffmpeg.LogLevelError
|
|
}
|
|
}
|
|
|
|
func Transcode(input string, options TranscodeOptions) ffmpeg.Args {
|
|
options.setDefaults()
|
|
|
|
// TODO - this should probably be generalised and applied to all operations. Need to verify impact on phash algorithm.
|
|
const fallbackMinSlowSeek = 20.0
|
|
|
|
var fastSeek float64
|
|
var slowSeek float64
|
|
|
|
if !options.SlowSeek {
|
|
fastSeek = options.StartTime
|
|
slowSeek = 0
|
|
} else {
|
|
// In slowseek mode, try a combination of fast/slow seek instead of just fastseek
|
|
// Commonly with avi/wmv ffmpeg doesn't seem to always predict the right start point to begin decoding when
|
|
// using fast seek. If you force ffmpeg to decode more, it avoids the "blocky green artifact" issue.
|
|
if options.StartTime > fallbackMinSlowSeek {
|
|
// Handle seeks longer than fallbackMinSlowSeek with fast/slow seeks
|
|
// Allow for at least fallbackMinSlowSeek seconds of slow seek
|
|
fastSeek = options.StartTime - fallbackMinSlowSeek
|
|
slowSeek = fallbackMinSlowSeek
|
|
} else {
|
|
// Handle seeks shorter than fallbackMinSlowSeek with only slow seeks.
|
|
slowSeek = options.StartTime
|
|
fastSeek = 0
|
|
}
|
|
}
|
|
|
|
var args ffmpeg.Args
|
|
args = args.LogLevel(options.Verbosity).Overwrite()
|
|
args = append(args, options.ExtraInputArgs...)
|
|
|
|
if options.XError {
|
|
args = args.XError()
|
|
}
|
|
|
|
if fastSeek > 0 {
|
|
args = args.Seek(fastSeek)
|
|
}
|
|
|
|
args = args.Input(input)
|
|
|
|
if slowSeek > 0 {
|
|
args = args.Seek(slowSeek)
|
|
}
|
|
|
|
if options.Duration > 0 {
|
|
args = args.Duration(options.Duration)
|
|
}
|
|
|
|
// https://trac.ffmpeg.org/ticket/6375
|
|
args = args.MaxMuxingQueueSize(1024)
|
|
|
|
args = args.VideoCodec(options.VideoCodec)
|
|
args = args.AppendArgs(options.VideoArgs)
|
|
|
|
// if audio codec is not provided, then skip it
|
|
if options.AudioCodec == "" {
|
|
args = args.SkipAudio()
|
|
} else {
|
|
args = args.AudioCodec(options.AudioCodec)
|
|
}
|
|
args = args.AppendArgs(options.AudioArgs)
|
|
|
|
args = append(args, options.ExtraOutputArgs...)
|
|
|
|
args = args.Format(options.Format)
|
|
args = args.Output(options.OutputPath)
|
|
|
|
return args
|
|
}
|