From fda746c5fdf3b38890129e47bca2cb27fa7e6aa7 Mon Sep 17 00:00:00 2001 From: iawia002 Date: Fri, 10 Aug 2018 16:04:43 +0800 Subject: [PATCH] utils/ffmpeg: integrate merge functions into a file [ci skip] --- downloader/downloader.go | 45 ++++-------------------------- utils/ffmpeg.go | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 39 deletions(-) create mode 100644 utils/ffmpeg.go diff --git a/downloader/downloader.go b/downloader/downloader.go index 4846d28ef..ab775afe9 100644 --- a/downloader/downloader.go +++ b/downloader/downloader.go @@ -2,13 +2,11 @@ package downloader import ( "bufio" - "bytes" "encoding/json" "fmt" "io" "log" "os" - "os/exec" "sort" "strings" "time" @@ -320,45 +318,14 @@ func (v VideoData) Download(refer string) { return } // merge - mergeFileName := title + ".txt" // merge list file should be in the current directory - filePath := utils.FilePath(title, "mp4", false) - fmt.Printf("Merging video parts into %s\n", filePath) - var cmd *exec.Cmd - if strings.Contains(v.Site, "youtube") { - // merge audio and video - cmds := []string{ - "-y", - } - for _, part := range parts { - cmds = append(cmds, "-i", part) - } - cmds = append( - cmds, "-c:v", "copy", "-c:a", "aac", "-strict", "experimental", - filePath, - ) - cmd = exec.Command("ffmpeg", cmds...) + fmt.Printf("Merging video parts into %s\n", mergedFilePath) + var err error + if v.Site == "YouTube youtube.com" { + err = utils.MergeAudioAndVideo(parts, mergedFilePath) } else { - // write ffmpeg input file list - mergeFile, _ := os.Create(mergeFileName) - for _, part := range parts { - mergeFile.Write([]byte(fmt.Sprintf("file '%s'\n", part))) - } - mergeFile.Close() - - cmd = exec.Command( - "ffmpeg", "-y", "-f", "concat", "-safe", "-1", - "-i", mergeFileName, "-c", "copy", "-bsf:a", "aac_adtstoasc", filePath, - ) + err = utils.MergeToMP4(parts, mergedFilePath, title) } - var stderr bytes.Buffer - cmd.Stderr = &stderr - err := cmd.Run() if err != nil { - log.Fatal(fmt.Sprint(err) + "\n" + stderr.String()) - } - // remove parts - os.Remove(mergeFileName) - for _, part := range parts { - os.Remove(part) + log.Println(err) } } diff --git a/utils/ffmpeg.go b/utils/ffmpeg.go new file mode 100644 index 000000000..7cab56e1b --- /dev/null +++ b/utils/ffmpeg.go @@ -0,0 +1,59 @@ +package utils + +import ( + "bytes" + "fmt" + "os" + "os/exec" +) + +func runMergeCmd(cmd *exec.Cmd, paths []string, mergeFilePath string) error { + var stderr bytes.Buffer + cmd.Stderr = &stderr + err := cmd.Run() + if err != nil { + return fmt.Errorf("%s\n%s", err, stderr.String()) + } + + if mergeFilePath != "" { + os.Remove(mergeFilePath) + } + // remove parts + for _, path := range paths { + os.Remove(path) + } + return nil +} + +// MergeAudioAndVideo merge audio and video +func MergeAudioAndVideo(paths []string, mergedFilePath string) error { + cmds := []string{ + "-y", + } + for _, path := range paths { + cmds = append(cmds, "-i", path) + } + cmds = append( + cmds, "-c:v", "copy", "-c:a", "aac", "-strict", "experimental", + mergedFilePath, + ) + return runMergeCmd(exec.Command("ffmpeg", cmds...), paths, "") +} + +// MergeToMP4 merge video parts to MP4 +func MergeToMP4(paths []string, mergedFilePath string, filename string) error { + mergeFilePath := filename + ".txt" // merge list file should be in the current directory + + // write ffmpeg input file list + mergeFile, _ := os.Create(mergeFilePath) + for _, path := range paths { + mergeFile.Write([]byte(fmt.Sprintf("file '%s'\n", path))) + } + mergeFile.Close() + + cmd := exec.Command( + "ffmpeg", "-y", "-f", "concat", "-safe", "-1", + "-i", mergeFilePath, "-c", "copy", "-bsf:a", "aac_adtstoasc", mergedFilePath, + ) + return runMergeCmd(cmd, paths, mergeFilePath) +}