github.com/Mrs4s/go-cqhttp@v1.2.0/modules/silk/codec.go (about) 1 //go:build (linux || (windows && !arm && !arm64) || darwin) && (386 || amd64 || arm || arm64) && !race && !nosilk 2 // +build linux windows,!arm,!arm64 darwin 3 // +build 386 amd64 arm arm64 4 // +build !race 5 // +build !nosilk 6 7 package silk 8 9 import ( 10 "os" 11 "os/exec" 12 "path" 13 14 "github.com/pkg/errors" 15 "github.com/wdvxdr1123/go-silk" 16 17 "github.com/Mrs4s/go-cqhttp/internal/base" 18 ) 19 20 const silkCachePath = "data/cache" 21 22 // encode 将音频编码为Silk 23 func encode(record []byte, tempName string) (silkWav []byte, err error) { 24 // 1. 写入缓存文件 25 rawPath := path.Join(silkCachePath, tempName+".wav") 26 err = os.WriteFile(rawPath, record, os.ModePerm) 27 if err != nil { 28 return nil, errors.Wrap(err, "write temp file error") 29 } 30 defer os.Remove(rawPath) 31 32 // 2.转换pcm 33 pcmPath := path.Join(silkCachePath, tempName+".pcm") 34 cmd := exec.Command("ffmpeg", "-i", rawPath, "-f", "s16le", "-ar", "24000", "-ac", "1", pcmPath) 35 if errors.Is(cmd.Err, exec.ErrDot) { 36 cmd.Err = nil 37 } 38 if base.Debug { 39 cmd.Stdout = os.Stdout 40 cmd.Stderr = os.Stderr 41 } 42 if err = cmd.Run(); err != nil { 43 return nil, errors.Wrap(err, "convert pcm file error") 44 } 45 defer os.Remove(pcmPath) 46 47 // 3. 转silk 48 pcm, err := os.ReadFile(pcmPath) 49 if err != nil { 50 return nil, errors.Wrap(err, "read pcm file err") 51 } 52 silkWav, err = silk.EncodePcmBuffToSilk(pcm, 24000, 24000, true) 53 if err != nil { 54 return nil, errors.Wrap(err, "silk encode error") 55 } 56 silkPath := path.Join(silkCachePath, tempName+".silk") 57 err = os.WriteFile(silkPath, silkWav, 0o666) 58 return 59 } 60 61 // resample 将silk重新编码为 24000 bit rate 62 func resample(data []byte) []byte { 63 pcm, err := silk.DecodeSilkBuffToPcm(data, 24000) 64 if err != nil { 65 panic(err) 66 } 67 data, err = silk.EncodePcmBuffToSilk(pcm, 24000, 24000, true) 68 if err != nil { 69 panic(err) 70 } 71 return data 72 }