123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package audio
- import (
- "bytes"
- "eta/eta_pub/utils"
- "fmt"
- "math"
- "os"
- "os/exec"
- "path"
- "strconv"
- "strings"
- )
- // ConvAudioDecibel 音频分贝转换(生成新的文件)
- func ConvAudioDecibel(inputFile string) (outputFile string, isConvDecibel bool, err error) {
- // 转换音频格式后的音频地址
- convAudioPath := inputFile
- //音频格式转换
- ext := path.Ext(convAudioPath)
- inputFileStrList := strings.Split(convAudioPath, ext)
- if ext != ".mp3" {
- // 转换音频格式后的文件名
- convAudioPath = inputFileStrList[0] + "_conv.mp3"
- err = ConvertAudioFormat(inputFile, convAudioPath)
- if err != nil {
- //fmt.Println("ConvertAudioFormat Err:" + err.Error())
- return
- }
- // 退出后需要删除该临时文件
- defer func() {
- os.Remove(convAudioPath)
- }()
- }
- baseDecibels := -22.8 //基准音量分贝,dB
- // 音频的实际分贝 音频的实际分贝与基准分贝的差值
- var volumeFloat, diffDecibels float64
- //音频声音处理
- {
- tmpVolumeFloat, ok, tmpErr := extractVolume(convAudioPath)
- if tmpErr != nil {
- err = tmpErr
- return
- }
- if !ok {
- return
- }
- volumeFloat = tmpVolumeFloat
- // 分贝差值
- diffDecibels = volumeFloat - baseDecibels
- // 分贝差值在5dB误差内,那就不转了
- if math.Abs(diffDecibels) <= 5 {
- //fmt.Println("音频分贝在误差范围内,无需转音频")
- return
- }
- }
- //fmt.Println("开始转变音频分贝")
- // 分贝大小变更
- targetDecibels := "" // 目标分贝值
- //fmt.Println("分贝差值:", diffDecibels)
- if diffDecibels < 0 { // 原先的音频分贝过小,那么需要增大
- targetDecibels = fmt.Sprintf("+%sdB", utils.SubFloatToString(math.Abs(diffDecibels), 2))
- } else { // 原先的音频分贝过大,那么需要减小
- targetDecibels = fmt.Sprintf("-%sdB", utils.SubFloatToString(math.Abs(diffDecibels), 2))
- }
- //fmt.Println("开始转音频分贝:", targetDecibels)
- afCommandStr := "volume=" + targetDecibels
- //fmt.Println(afCommandStr)
- // 转换音频分贝格式后的文件名
- outputFile = inputFileStrList[0] + "_decibel.mp3"
- // 构建 FFmpeg 命令
- cmd := exec.Command("ffmpeg", "-y", "-i", convAudioPath, "-af", afCommandStr, outputFile)
- var out bytes.Buffer
- cmd.Stderr = &out
- // 执行 FFmpeg 命令
- err = cmd.Run()
- if err != nil {
- utils.FileLog.Info("转换音频分贝格式失败,FFmpeg命令返回:\n" + out.String())
- return
- }
- isConvDecibel = true
- //fmt.Println("音频文件的音量已设置成功!")
- return
- }
- // 从FFmpeg输出中提取音量信息
- func extractVolume(audioPath string) (decibels float64, ok bool, err error) {
- cmd := exec.Command("ffmpeg", "-i", audioPath, "-af", "volumedetect", "-f", "null", "-")
- var out bytes.Buffer
- cmd.Stderr = &out
- err = cmd.Run()
- if err != nil {
- return
- }
- output := out.String()
- //fmt.Println("output:", output)
- var volumeLine string
- lines := strings.Split(output, "\n")
- for _, line := range lines {
- if strings.Contains(line, "mean_volume:") {
- volumeLine = line
- break
- }
- }
- if volumeLine == `` {
- return
- }
- volumeArr := strings.Split(volumeLine, " ")
- if len(volumeArr) < 4 {
- return
- }
- //fmt.Println("volume start")
- //fmt.Println(volumeStr)
- //fmt.Println(volumeArr)
- //fmt.Println(len(volumeArr))
- //for k, v := range volumeArr {
- // fmt.Println(k, v)
- //}
- //fmt.Println("volume end")
- volume := volumeArr[4]
- decibels, err = convertToFloat(volume)
- ok = true
- //fmt.Println(audioPath, "音量分贝值为:", decibels)
- return
- }
- // 将字符串转换为浮点数
- func convertToFloat(str string) (float64, error) {
- str = strings.TrimSpace(str)
- value, err := strconv.ParseFloat(str, 64)
- if err != nil {
- return 0, err
- }
- return value, nil
- }
- // ConvertAudioFormat 转换音频文件格式
- func ConvertAudioFormat(inputFilePath, outputFilePath string) (err error) {
- cmd := exec.Command("ffmpeg", "-y", "-i", inputFilePath, "-codec:a", "libmp3lame", outputFilePath)
- err = cmd.Run()
- if err != nil {
- return
- }
- return nil
- }
|