Files
photoprism/internal/ffmpeg/transcode_cmd.go
2025-01-09 10:38:56 +01:00

72 lines
2.1 KiB
Go

package ffmpeg
import (
"fmt"
"os/exec"
"github.com/photoprism/photoprism/internal/ffmpeg/apple"
"github.com/photoprism/photoprism/internal/ffmpeg/encode"
"github.com/photoprism/photoprism/internal/ffmpeg/intel"
"github.com/photoprism/photoprism/internal/ffmpeg/nvidia"
"github.com/photoprism/photoprism/internal/ffmpeg/v4l"
"github.com/photoprism/photoprism/internal/ffmpeg/vaapi"
"github.com/photoprism/photoprism/pkg/fs"
)
// TranscodeCmd returns the FFmpeg command for transcoding existing video files to MPEG-4 AVC.
func TranscodeCmd(srcName, destName string, opt encode.Options) (cmd *exec.Cmd, useMutex bool, err error) {
if srcName == "" {
return nil, false, fmt.Errorf("empty source filename")
} else if destName == "" {
return nil, false, fmt.Errorf("empty destination filename")
}
// Prevents multiple videos from being transcoded at the same time.
useMutex = true
// Use the default binary name if no name is specified.
if opt.Bin == "" {
opt.Bin = DefaultBin
}
// Always use software encoder for transcoding animated pictures into videos.
if fs.TypeAnimated[fs.FileType(srcName)] != "" {
cmd = exec.Command(
opt.Bin,
"-y",
"-strict", "-2",
"-i", srcName,
"-pix_fmt", encode.FormatYUV420P.String(),
"-vf", "scale='trunc(iw/2)*2:trunc(ih/2)*2'",
"-f", "mp4",
"-movflags", "+faststart", // puts headers at the beginning for faster streaming
destName,
)
return cmd, useMutex, nil
}
// Log encoder name if it is not the default.
if opt.Encoder != encode.SoftwareAvc {
log.Infof("convert: ffmpeg encoder %s selected", opt.Encoder.String())
}
// Transcode video with selected encoder.
switch opt.Encoder {
case encode.IntelAvc:
cmd = intel.TranscodeToAvcCmd(srcName, destName, opt)
case encode.AppleAvc:
cmd = apple.TranscodeToAvcCmd(srcName, destName, opt)
case encode.VaapiAvc:
cmd = vaapi.TranscodeToAvcCmd(srcName, destName, opt)
case encode.NvidiaAvc:
cmd = nvidia.TranscodeToAvcCmd(srcName, destName, opt)
case encode.V4LAvc:
cmd = v4l.TranscodeToAvcCmd(srcName, destName, opt)
default:
cmd = encode.TranscodeToAvcCmd(srcName, destName, opt)
}
return cmd, useMutex, nil
}