From fe09c60822662c9ddb5dd0bbe374101a59faf656 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Fri, 13 Mar 2026 11:10:39 +0800 Subject: [PATCH] hwaccel --- config.yaml | 1 + config/dto.go | 5 +-- util/ffmpeg.go | 90 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/config.yaml b/config.yaml index ed183a5..76ea750 100644 --- a/config.yaml +++ b/config.yaml @@ -34,6 +34,7 @@ disconnectAction: command: "" preview: enabled: true + hwaccel: "" resolutions: - 720 - 1080 diff --git a/config/dto.go b/config/dto.go index 980a9c3..88f8759 100644 --- a/config/dto.go +++ b/config/dto.go @@ -65,8 +65,9 @@ type DisconnectActionConfig struct { } type PreviewConfig struct { - Enabled bool `mapstructure:"enabled"` - Resolutions []int `mapstructure:"resolutions"` + Enabled bool `mapstructure:"enabled"` + Resolutions []int `mapstructure:"resolutions"` + HwAccel string `mapstructure:"hwaccel"` } type MainConfig struct { diff --git a/util/ffmpeg.go b/util/ffmpeg.go index 2c19d46..5a3c8fb 100644 --- a/util/ffmpeg.go +++ b/util/ffmpeg.go @@ -1,6 +1,7 @@ package util import ( + "ZhenTuLocalPassiveAdapter/config" "ZhenTuLocalPassiveAdapter/dto" "ZhenTuLocalPassiveAdapter/logger" "bytes" @@ -474,6 +475,26 @@ func CompressVideo(ctx context.Context, inputFile, outputFile string, height int subCtx, span := tracer.Start(ctx, "CompressVideo") defer span.End() span.SetAttributes(attribute.Int("height", height)) + + hwaccel := strings.ToLower(strings.TrimSpace(config.Config.Preview.HwAccel)) + if hwaccel != "" && hwaccel != "none" { + span.SetAttributes(attribute.String("hwaccel", hwaccel)) + ok, err := compressVideoGPU(subCtx, inputFile, outputFile, height, hwaccel) + if ok { + return true, nil + } + logger.Warn("GPU编码失败,回退到CPU编码", + zap.String("hwaccel", hwaccel), + zap.Error(err)) + os.Remove(outputFile) + } + + return compressVideoCPU(subCtx, inputFile, outputFile, height) +} + +func compressVideoCPU(ctx context.Context, inputFile, outputFile string, height int) (bool, error) { + _, span := tracer.Start(ctx, "compressVideoCPU") + defer span.End() scaleFilter := fmt.Sprintf("scale=-2:%d", height) ffmpegCmd := []string{ FfmpegExec, @@ -489,7 +510,74 @@ func CompressVideo(ctx context.Context, inputFile, outputFile string, height int "-f", "mp4", outputFile, } - return handleFfmpegProcess(subCtx, ffmpegCmd) + return handleFfmpegProcess(ctx, ffmpegCmd) +} + +func compressVideoGPU(ctx context.Context, inputFile, outputFile string, height int, hwaccel string) (bool, error) { + _, span := tracer.Start(ctx, "compressVideoGPU") + defer span.End() + span.SetAttributes(attribute.String("hwaccel", hwaccel)) + + var ffmpegCmd []string + switch hwaccel { + case "nvenc": + scaleFilter := fmt.Sprintf("scale_cuda=-2:%d", height) + ffmpegCmd = []string{ + FfmpegExec, + "-hide_banner", + "-y", + "-hwaccel", "cuda", + "-hwaccel_output_format", "cuda", + "-i", inputFile, + "-vf", scaleFilter, + "-c:v", "h264_nvenc", + "-preset", "p4", + "-cq", "28", + "-c:a", "aac", + "-b:a", "128k", + "-f", "mp4", + outputFile, + } + case "amf": + scaleFilter := fmt.Sprintf("scale=-2:%d", height) + ffmpegCmd = []string{ + FfmpegExec, + "-hide_banner", + "-y", + "-i", inputFile, + "-vf", scaleFilter, + "-c:v", "h264_amf", + "-quality", "balanced", + "-rc", "cqp", + "-qp_i", "28", + "-qp_p", "28", + "-c:a", "aac", + "-b:a", "128k", + "-f", "mp4", + outputFile, + } + case "qsv": + scaleFilter := fmt.Sprintf("scale=-2:%d", height) + ffmpegCmd = []string{ + FfmpegExec, + "-hide_banner", + "-y", + "-hwaccel", "qsv", + "-i", inputFile, + "-vf", scaleFilter, + "-c:v", "h264_qsv", + "-preset", "faster", + "-global_quality", "28", + "-c:a", "aac", + "-b:a", "128k", + "-f", "mp4", + outputFile, + } + default: + return false, fmt.Errorf("不支持的硬件加速类型: %s", hwaccel) + } + + return handleFfmpegProcess(ctx, ffmpegCmd) } func GetVideoCodec(ctx context.Context, filePath string) (string, error) {