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  }