stash/pkg/manager/task_transcode.go

116 lines
3.4 KiB
Go
Raw Normal View History

2019-02-11 20:12:08 +00:00
package manager
import (
"github.com/remeh/sizedwaitgroup"
2019-02-14 23:42:52 +00:00
"github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/manager/config"
2019-02-14 23:42:52 +00:00
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
2019-02-11 20:12:08 +00:00
)
type GenerateTranscodeTask struct {
2020-08-06 01:21:14 +00:00
Scene models.Scene
Overwrite bool
fileNamingAlgorithm models.HashAlgorithm
2019-02-11 20:12:08 +00:00
}
func (t *GenerateTranscodeTask) Start(wg *sizedwaitgroup.SizedWaitGroup) {
2019-02-11 20:12:08 +00:00
defer wg.Done()
2020-08-06 01:21:14 +00:00
hasTranscode := HasTranscode(&t.Scene, t.fileNamingAlgorithm)
if !t.Overwrite && hasTranscode {
2019-02-11 20:12:08 +00:00
return
}
var container ffmpeg.Container
if t.Scene.Format.Valid {
container = ffmpeg.Container(t.Scene.Format.String)
} else { // container isn't in the DB
// shouldn't happen unless user hasn't scanned after updating to PR#384+ version
tmpVideoFile, err := ffmpeg.NewVideoFile(instance.FFProbePath, t.Scene.Path, false)
if err != nil {
logger.Errorf("[transcode] error reading video file: %s", err.Error())
return
}
container = ffmpeg.MatchContainer(tmpVideoFile.Container, t.Scene.Path)
}
videoCodec := t.Scene.VideoCodec.String
audioCodec := ffmpeg.MissingUnsupported
if t.Scene.AudioCodec.Valid {
audioCodec = ffmpeg.AudioCodec(t.Scene.AudioCodec.String)
}
if ffmpeg.IsStreamable(videoCodec, audioCodec, container) {
return
}
2019-02-11 20:12:08 +00:00
videoFile, err := ffmpeg.NewVideoFile(instance.FFProbePath, t.Scene.Path, false)
2019-02-11 20:12:08 +00:00
if err != nil {
logger.Errorf("[transcode] error reading video file: %s", err.Error())
return
}
2020-08-06 01:21:14 +00:00
sceneHash := t.Scene.GetHash(t.fileNamingAlgorithm)
outputPath := instance.Paths.Generated.GetTmpPath(sceneHash + ".mp4")
transcodeSize := config.GetInstance().GetMaxTranscodeSize()
2019-02-11 20:12:08 +00:00
options := ffmpeg.TranscodeOptions{
OutputPath: outputPath,
MaxTranscodeSize: transcodeSize,
2019-02-11 20:12:08 +00:00
}
encoder := ffmpeg.NewEncoder(instance.FFMPEGPath)
if videoCodec == ffmpeg.H264 { // for non supported h264 files stream copy the video part
if audioCodec == ffmpeg.MissingUnsupported {
encoder.CopyVideo(*videoFile, options)
} else {
encoder.TranscodeAudio(*videoFile, options)
}
} else {
if audioCodec == ffmpeg.MissingUnsupported {
//ffmpeg fails if it trys to transcode an unsupported audio codec
encoder.TranscodeVideo(*videoFile, options)
} else {
encoder.Transcode(*videoFile, options)
}
}
if err := utils.SafeMove(outputPath, instance.Paths.Scene.GetTranscodePath(sceneHash)); err != nil {
2019-02-11 20:12:08 +00:00
logger.Errorf("[transcode] error generating transcode: %s", err.Error())
return
}
2020-08-06 01:21:14 +00:00
logger.Debugf("[transcode] <%s> created transcode: %s", sceneHash, outputPath)
}
// return true if transcode is needed
// used only when counting files to generate, doesn't affect the actual transcode generation
// if container is missing from DB it is treated as non supported in order not to delay the user
func (t *GenerateTranscodeTask) isTranscodeNeeded() bool {
videoCodec := t.Scene.VideoCodec.String
container := ""
audioCodec := ffmpeg.MissingUnsupported
if t.Scene.AudioCodec.Valid {
audioCodec = ffmpeg.AudioCodec(t.Scene.AudioCodec.String)
}
if t.Scene.Format.Valid {
container = t.Scene.Format.String
}
if ffmpeg.IsStreamable(videoCodec, audioCodec, ffmpeg.Container(container)) {
return false
}
2020-08-06 01:21:14 +00:00
hasTranscode := HasTranscode(&t.Scene, t.fileNamingAlgorithm)
if !t.Overwrite && hasTranscode {
return false
}
return true
}