76 lines
2.3 KiB
Go
76 lines
2.3 KiB
Go
package encoder
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func (m *FFmpegManager) BuildVideoCmd(inputPath, outputPath, targetResolution, ffmpegFlags string, originalWidth, originalHeight int) (*exec.Cmd, error) {
|
|
args := []string{"-i", inputPath}
|
|
|
|
if targetResolution != "" {
|
|
targetHeightStr := strings.TrimRight(strings.ToLower(targetResolution), "p")
|
|
targetHeight, err := strconv.Atoi(targetHeightStr)
|
|
if err == nil && targetHeight > 0 && originalHeight > targetHeight {
|
|
scaleWidth := int((float64(originalWidth) / float64(originalHeight)) * float64(targetHeight))
|
|
if scaleWidth%2 != 0 {
|
|
scaleWidth--
|
|
}
|
|
args = append(args, "-vf", fmt.Sprintf("scale=%d:%d", scaleWidth, targetHeight))
|
|
}
|
|
}
|
|
|
|
args = append(args, "-c:v", "libx265", "-c:a", "copy", "-preset", "medium", "-crf", "22", "-f", "matroska")
|
|
|
|
if ffmpegFlags != "" {
|
|
userArgs := ShlexSplit(ffmpegFlags)
|
|
args = append(args, userArgs...)
|
|
}
|
|
|
|
args = append(args, outputPath, "-y")
|
|
|
|
return exec.Command(m.BinaryPath, args...), nil
|
|
}
|
|
|
|
func (m *FFmpegManager) ShouldSkipVideo(inputPath, targetResolution string) bool {
|
|
// Probe the codec
|
|
cmd := exec.Command("ffprobe", "-v", "quiet", "-select_streams", "v:0",
|
|
"-show_entries", "stream=codec_name", "-of", "csv=p=0", inputPath)
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
codec := strings.TrimSpace(string(out))
|
|
|
|
// Probe the height
|
|
cmdHeight := exec.Command("ffprobe", "-v", "quiet", "-select_streams", "v:0",
|
|
"-show_entries", "stream=height", "-of", "csv=p=0", inputPath)
|
|
outHeight, err := cmdHeight.Output()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// If it's not H.264 or H.265, do not skip (encode it)
|
|
if codec != "h264" && codec != "hevc" {
|
|
return false
|
|
}
|
|
|
|
// If it's H.265 and no target resolution is set, it's already in the target codec
|
|
if codec == "hevc" && targetResolution == "" {
|
|
return true
|
|
}
|
|
|
|
// If it's H.265 and target resolution is set, only skip if current height is <= target height
|
|
if codec == "hevc" && targetResolution != "" {
|
|
currentHeight, _ := strconv.Atoi(strings.TrimSpace(string(outHeight)))
|
|
targetHeight, _ := strconv.Atoi(strings.TrimRight(strings.ToLower(targetResolution), "p"))
|
|
if currentHeight > 0 && targetHeight > 0 && currentHeight <= targetHeight {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|