package main import ( "bytes" "fmt" "git.wanpinghui.com/WPH/go_common/wph" "os" "os/exec" "path" "path/filepath" "strings" ) func main() { inputFiles, err := listFiles(`./ffmpeg/mp3`, `.mp3`) if nil != err { println(`查找输入文件出错:`, err.Error()) } if nil == inputFiles || len(inputFiles) == 0 { return } var command, out string for _, f := range inputFiles { o := fmt.Sprintf(`./ffmpeg/output/%s.m4a`, strings.TrimRight(strings.ToLower(path.Base(f)), ".mp3")) command, out, err = MP3ToM4A(f, o) if nil != err { println("error:", err.Error()) println("command:", command) println("out:\n", out) } } } const ( wrongMP3Output = `Estimating duration from bitrate, this may be inaccurate` infoCmdFormat = `ffmpeg -i %s` tempCmdFormat = `ffmpeg -i %s -c:a alac -b:a 80k -c:v copy %s -y` audioCmdFormat = `ffmpeg -i %s -movflags faststart -c:a aac -b:a 80k -vn %s -y` transCmdFormat = `ffmpeg -i %s -movflags faststart -c:a aac -b:a 80k %s -y` ) // mp3转m4a func MP3ToM4A(inputFileName, outputFileName string) (string, string, error) { var err error var command string // 先查看文件信息 command = fmt.Sprintf(infoCmdFormat, inputFileName) out, _ := RunCmd(command) if strings.Contains(out, wrongMP3Output) { // 处理特殊编码的mp3文件 // 选用原始编码器先复写一份临时m4a,此文件含图像,体积特别大 tempFileName := fmt.Sprintf(`./%d.m4a`, wph.NextId()) command = fmt.Sprintf(tempCmdFormat, inputFileName, tempFileName) out, err = RunCmd(command) if nil != err { return command, out, err } // 从临时文件中提取音频 command = fmt.Sprintf(audioCmdFormat, tempFileName, outputFileName) out, err = RunCmd(command) if nil != err { return command, out, err } // 删除临时文件 _ = os.Remove(tempFileName) } else { // 正常编码的mp3 command := fmt.Sprintf(transCmdFormat, inputFileName, outputFileName) out, err = RunCmd(command) if nil != err { return command, out, err } } return command, out, nil } func RunCmd(command string) (string, error) { command = strings.TrimSpace(command) if command == "" { return "", nil } var cmdAndArgs []string arr := strings.Split(command, " ") for i := 0; i < len(arr); i++ { part := strings.TrimSpace(arr[i]) if part == "" { continue } cmdAndArgs = append(cmdAndArgs, part) } if nil == cmdAndArgs || len(cmdAndArgs) == 0 { return "", nil } var cmd *exec.Cmd if len(cmdAndArgs) == 1 { cmd = exec.Command(cmdAndArgs[0]) } else { cmd = exec.Command(cmdAndArgs[0], cmdAndArgs[1:]...) } var out bytes.Buffer cmd.Stdout = &out cmd.Stderr = &out err := cmd.Start() if nil != err { return out.String(), err } err = cmd.Wait() return out.String(), err } func listFiles(dirPath string, extList ...string) ([]string, error) { dir, err := os.Stat(dirPath) if (nil != err && os.IsNotExist(err)) || !dir.IsDir() { return nil, nil } err = nil var files []string err = filepath.Walk(dirPath, func(name string, info os.FileInfo, err error) error { if info.IsDir() { return nil } ext := strings.ToLower(path.Ext(name)) if wph.Contains(extList, ext) { files = append(files, name) } return nil }) if nil != err { return nil, err } return files, nil }