From 63c6711cced3540f0b71d288ce34a4853b3052e9 Mon Sep 17 00:00:00 2001 From: Tohrusky <65994850+Tohrusky@users.noreply.github.com> Date: Mon, 6 Jan 2025 00:58:59 +0000 Subject: [PATCH] fix: use mkvmerge to concat and ReMux again --- module/ffmpeg/cut.go | 4 +-- module/ffmpeg/merge.go | 60 +++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/module/ffmpeg/cut.go b/module/ffmpeg/cut.go index ed1441d..1493af5 100644 --- a/module/ffmpeg/cut.go +++ b/module/ffmpeg/cut.go @@ -25,11 +25,11 @@ func CutVideo(inputPath string, outputFolder string) ([]string, error) { var scriptPath string switch runtime.GOOS { case OS_WINDOWS: - commandStr = fmt.Sprintf("ffmpeg -i \"%s\" -f segment -segment_format mkv -segment_time 60 -c copy -map 0:v:0 -segment_list \"%s/out.list\" \"%s/%%%%003d.mkv\"", inputPath, outputFolder, outputFolder) //nolint: lll + commandStr = fmt.Sprintf("ffmpeg -i \"%s\" -f segment -segment_format mkv -segment_time 60 -reset_timestamps 1 -c copy -map 0:v:0 -segment_list \"%s/out.list\" \"%s/%%%%003d.mkv\"", inputPath, outputFolder, outputFolder) //nolint: lll scriptPath = "temp_script.bat" commandStr = fmt.Sprintf("@echo off%s%s", "\r\n", commandStr) default: - commandStr = fmt.Sprintf("ffmpeg -i \"%s\" -f segment -segment_format mkv -segment_time 60 -c copy -map 0:v:0 -segment_list \"%s/out.list\" \"%s/%%003d.mkv\"", inputPath, outputFolder, outputFolder) //nolint: lll + commandStr = fmt.Sprintf("ffmpeg -i \"%s\" -f segment -segment_format mkv -segment_time 60 -reset_timestamps 1 -c copy -map 0:v:0 -segment_list \"%s/out.list\" \"%s/%%003d.mkv\"", inputPath, outputFolder, outputFolder) //nolint: lll scriptPath = "temp_script.sh" commandStr = fmt.Sprintf("#!/bin/bash%s%s", "\n", commandStr) } diff --git a/module/ffmpeg/merge.go b/module/ffmpeg/merge.go index 06b621a..427a1d1 100644 --- a/module/ffmpeg/merge.go +++ b/module/ffmpeg/merge.go @@ -2,7 +2,6 @@ package ffmpeg import ( "fmt" - "os" "os/exec" "github.com/TensoRaws/FinalRip/module/log" @@ -11,37 +10,28 @@ import ( // MergeVideo 使用 ffmpeg 进行视频合并,使用 mkvpropedit 清除 tags func MergeVideo(originPath string, inputFiles []string, outputPath string) error { - listPath := "temp_list.txt" // 写入文件列表 tempVideoConcatOutputPath := "temp_video_concat_output.mkv" + tempVideoMergedOutputPath := "temp_video_merged_output.mkv" // clear temp file - _ = util.ClearTempFile(listPath, tempVideoConcatOutputPath) + _ = util.ClearTempFile(tempVideoConcatOutputPath, tempVideoMergedOutputPath) defer func(p ...string) { log.Logger.Infof("Clear temp file %v", p) _ = util.ClearTempFile(p...) - }(listPath, tempVideoConcatOutputPath) + }(tempVideoConcatOutputPath, tempVideoMergedOutputPath) - var listStr string - for _, file := range inputFiles { - listStr += fmt.Sprintf("file '%s'\n", file) - } + // Concat video + log.Logger.Infof("Concat video with encoded clips: %s", inputFiles) - err := os.WriteFile(listPath, []byte(listStr), 0755) - if err != nil { - log.Logger.Errorf("write list file failed: %v", err) - return err + mkvmergeArgs := []string{"-v", "-o", tempVideoConcatOutputPath} + for i, file := range inputFiles { + if i > 0 { + mkvmergeArgs = append(mkvmergeArgs, "+") + } + mkvmergeArgs = append(mkvmergeArgs, file) } - // Concat video - log.Logger.Infof("Concat video with list: %s", listPath) - cmd := exec.Command( - "ffmpeg", - "-safe", "0", - "-f", "concat", - "-i", listPath, - "-c", "copy", - tempVideoConcatOutputPath, - ) + cmd := exec.Command("mkvmerge", mkvmergeArgs...) out, err := cmd.CombinedOutput() if err != nil { log.Logger.Errorf("Concat video failed: %v", err) @@ -49,14 +39,30 @@ func MergeVideo(originPath string, inputFiles []string, outputPath string) error } log.Logger.Infof("Concat video output: %s", out) - // ReMuxWithSourceVideo - err = ReMuxWithSourceVideo(originPath, outputPath, tempVideoConcatOutputPath) + // ReMux with source video + err = ReMuxWithSourceVideo(originPath, tempVideoMergedOutputPath, tempVideoConcatOutputPath) if err != nil { log.Logger.Errorf("ReMux with source video failed: %v", err) return err } + // ReMux with mkvmerge + // !mkvmerge -o output.mkv temp_merged.mkv + log.Logger.Infof("ReMux video with mkvmerge...") + cmd = exec.Command( + "mkvmerge", + "-o", outputPath, + tempVideoMergedOutputPath, + ) + out, err = cmd.CombinedOutput() + if err != nil { + log.Logger.Errorf("Re-mux video failed: %v", err) + return err + } + log.Logger.Infof("Re-mux output: %s", out) + // Remove tags with mkvpropedit + // !mkvpropedit output.mkv --tags all: log.Logger.Infof("Remove tags with mkvpropedit...") cmd = exec.Command( "mkvpropedit", @@ -73,7 +79,7 @@ func MergeVideo(originPath string, inputFiles []string, outputPath string) error } // ReMuxWithSourceVideo 使用 ffmpeg 和原始视频进行 remux -func ReMuxWithSourceVideo(originPath string, outputPath string, concatOutputPath string) error { +func ReMuxWithSourceVideo(originPath string, tempVideoMergedOutputPath string, concatOutputPath string) error { // Define the different codec combinations to try codecCombinations := [][]string{ // Try copying both audio and subtitles @@ -126,7 +132,7 @@ func ReMuxWithSourceVideo(originPath string, outputPath string, concatOutputPath "-i", concatOutputPath, } args = append(args, codecArgs...) - args = append(args, outputPath) + args = append(args, tempVideoMergedOutputPath) cmd := exec.Command("ffmpeg", args...) out, err := cmd.CombinedOutput() @@ -140,7 +146,7 @@ func ReMuxWithSourceVideo(originPath string, outputPath string, concatOutputPath // Log the error and try the next combination log.Logger.Errorf("ffmpeg remux failed with codec combination %v: %v", codecArgs, err) // If failed, clean up temp files which may have been created - _ = util.ClearTempFile(outputPath) + _ = util.ClearTempFile(tempVideoMergedOutputPath) } return fmt.Errorf("ffmpeg remux: all codec combinations failed")