| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- package utils
- import (
- "encoding/base64"
- "fmt"
- "io"
- "log"
- "os"
- "os/exec"
- "path/filepath"
- "pbx-api-gin/internal/pkg/configs"
- "pbx-api-gin/pkg/lfshook"
- "strconv"
- "strings"
- )
- // FileExists checks if a file exists and is not a directory before we
- // try using it to prevent further errors.
- func FileExists(filename string) bool {
- info, err := os.Stat(filename)
- if os.IsNotExist(err) {
- return false
- }
- return !info.IsDir()
- }
- func GetDuration(filePath string) (int, error) {
- cmd := exec.Command("ffprobe",
- "-v", "quiet",
- "-show_entries", "format=duration",
- "-of", "default=nw=1:nokey=1",
- filePath,
- )
- output, err := cmd.Output()
- if err != nil {
- return 0, err
- }
- // 解析输出(纯数字,单位秒)
- durationStr := strings.TrimSpace(string(output))
- duration, err := strconv.ParseFloat(durationStr, 64)
- if err != nil {
- return 0, err
- }
- return int(duration), nil
- }
- func AudioFileEncode(dstFile, srcFile string) error {
- data := "sripis123"
- encoded := base64.StdEncoding.EncodeToString([]byte(data))
- // Step 2: 创建一个新文件,写入 Base64 编码结果
- outputFile, err := os.Create(dstFile)
- if err != nil {
- return err
- }
- defer outputFile.Close()
- _, err = outputFile.WriteString(encoded)
- if err != nil {
- return err
- }
- // Step 3: 打开 audio.wav 文件
- audioFile, err := os.Open(srcFile)
- if err != nil {
- return err
- }
- defer audioFile.Close()
- // Step 4: 将 audio.wav 的内容追加到 output.bin 文件末尾
- _, err = audioFile.Seek(0, io.SeekStart) // 确保从文件开头读取
- if err != nil {
- return err
- }
- _, err = io.Copy(outputFile, audioFile)
- if err != nil {
- return err
- }
- return err
- }
- // ConvertAndSegmentWAV 将 WAV 文件转为 22kHz 并每 180 秒切分,返回生成的文件名列表
- func ConvertAndSegmentWAV(inputFile string, outputPrefix string) ([]string, error) {
- // 输出文件命名模式,如:output_%03d.wav
- outputPattern := outputPrefix + "_%03d.wav"
- // 构建 ffmpeg 命令
- cmd := exec.Command("ffmpeg",
- "-i", inputFile, // 输入文件
- "-ar", "22050", // 设置采样率为 22050 Hz (22kHz)
- "-f", "segment", // 启用分段模式
- "-segment_time", "180", // 每段 180 秒
- "-c:a", "pcm_s16le", // 音频编码格式(标准 WAV)
- "-reset_timestamps", "1", // 重置时间戳,每个片段从 0 开始
- outputPattern, // 输出文件命名规则
- )
- // 执行命令并捕获输出
- output, err := cmd.CombinedOutput()
- if err != nil && !strings.Contains(string(output), "Conversion failed!") {
- // 即使有警告(如非关键错误),只要文件生成了就继续解析
- log.Printf("ffmpeg 执行时有警告: %v", err)
- }
- // 解析输出,提取所有生成的文件名
- files := extractFilenamesFromFFmpegOutput(outputPrefix)
- lfshook.NewLogger().Infof("=============== found after convert outfiles %+v ", files)
- return files, nil
- }
- // extractFilenamesFromFFmpegOutput 从 ffmpeg 输出日志中提取生成的文件名
- func extractFilenamesFromFFmpegOutput(prefix string) []string {
- pattern := fmt.Sprintf("%s_*", prefix)
- matches, err := filepath.Glob(pattern)
- if err != nil {
- log.Fatal("模式匹配错误:", err)
- }
- return matches
- }
- func WriteLogToFile(message string) {
- // 打开文件,支持追加模式,如果文件不存在则创建
- file, err := os.OpenFile(configs.ConfigGlobal.RecordEventLog, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
- if err != nil {
- return
- }
- defer file.Close()
- // 创建一个写入到文件的日志器
- logger := log.New(file, "", log.LstdFlags)
- // 写入日志消息
- logger.Println(message)
- }
- var Logger *log.Logger
- func init() {
- file, _ := os.OpenFile("/data/test/log/recordEvent.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
- Logger = log.New(file, "", log.LstdFlags) // 自动带时间戳
- }
- func GetPadInfo(base string) (padType, padNum, connectedCab string) {
- // 按 '/' 分割字符串
- parts := strings.Split(base, "/")
- // 取最后一段
- lastPart := parts[len(parts)-1]
- // 最后一段中,按‘-’分割返回前三段:parts[0], parts[1], parts[2] → PAD-2411-1411
- ret := strings.Split(lastPart, "-")
- if len(ret) < 3 {
- return
- }
- return ret[1], ret[2], ret[3]
- }
|