代码初始化
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -24,11 +25,10 @@ const (
|
||||
backendCpp // whisper.cpp (whisper-cpp)
|
||||
)
|
||||
|
||||
// WhisperService 语音识别服务
|
||||
type WhisperService struct{}
|
||||
type whisperService struct{}
|
||||
|
||||
// Whisper 语音识别服务单例
|
||||
var Whisper = new(WhisperService)
|
||||
var Whisper = new(whisperService)
|
||||
|
||||
// TranscribeReq 语音识别请求
|
||||
type TranscribeReq struct {
|
||||
@@ -54,7 +54,7 @@ type Segment struct {
|
||||
}
|
||||
|
||||
// Transcribe 对音频文件进行语音识别(自动检测后端,自动降级)
|
||||
func (s *WhisperService) Transcribe(ctx context.Context, req *TranscribeReq) (res *TranscribeRes, err error) {
|
||||
func (s *whisperService) Transcribe(ctx context.Context, req *TranscribeReq) (res *TranscribeRes, err error) {
|
||||
// 1. 校验音频文件
|
||||
if _, err = os.Stat(req.AudioPath); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("音频文件不存在: %s", req.AudioPath)
|
||||
@@ -94,7 +94,7 @@ func (s *WhisperService) Transcribe(ctx context.Context, req *TranscribeReq) (re
|
||||
}
|
||||
|
||||
// transcribeWithCLI 使用 whisper CLI 命令
|
||||
func (s *WhisperService) transcribeWithCLI(ctx context.Context, req *TranscribeReq, whisperPath, model, language string) (res *TranscribeRes, err error) {
|
||||
func (s *whisperService) transcribeWithCLI(ctx context.Context, req *TranscribeReq, whisperPath, model, language string) (res *TranscribeRes, err error) {
|
||||
outputDir := filepath.Dir(req.AudioPath)
|
||||
modelDir := g.Cfg().MustGet(ctx, "whisper.model_dir", "").String()
|
||||
threads := g.Cfg().MustGet(ctx, "whisper.threads", 2).Int()
|
||||
@@ -122,7 +122,7 @@ func (s *WhisperService) transcribeWithCLI(ctx context.Context, req *TranscribeR
|
||||
}
|
||||
|
||||
// transcribeWithPython 使用 python -m whisper
|
||||
func (s *WhisperService) transcribeWithPython(ctx context.Context, req *TranscribeReq, model, language string) (res *TranscribeRes, err error) {
|
||||
func (s *whisperService) transcribeWithPython(ctx context.Context, req *TranscribeReq, model, language string) (res *TranscribeRes, err error) {
|
||||
// 查找 python
|
||||
pythonPath, err := exec.LookPath("python3")
|
||||
if err != nil {
|
||||
@@ -160,7 +160,7 @@ func (s *WhisperService) transcribeWithPython(ctx context.Context, req *Transcri
|
||||
}
|
||||
|
||||
// readTxtResult 读取 whisper 输出的 txt 文件
|
||||
func (s *WhisperService) readTxtResult(outputDir, audioPath, model string) (res *TranscribeRes, err error) {
|
||||
func (s *whisperService) readTxtResult(outputDir, audioPath, model string) (res *TranscribeRes, err error) {
|
||||
baseName := strings.TrimSuffix(filepath.Base(audioPath), filepath.Ext(audioPath))
|
||||
txtPaths := []string{
|
||||
filepath.Join(outputDir, baseName+".txt"),
|
||||
@@ -201,7 +201,7 @@ func cleanTranscript(text string) string {
|
||||
}
|
||||
|
||||
// detectBackend 检测可用的 whisper 后端,返回后端类型和可执行路径
|
||||
func (s *WhisperService) detectBackend() (WhisperBackend, string) {
|
||||
func (s *whisperService) detectBackend() (WhisperBackend, string) {
|
||||
// 1. 优先检测 C++ 版 whisper.cpp(最快,但参数格式不同)
|
||||
for _, name := range []string{"whisper-cpp", "whisper-cli"} {
|
||||
if path, err := exec.LookPath(name); err == nil {
|
||||
@@ -242,7 +242,7 @@ func (s *WhisperService) detectBackend() (WhisperBackend, string) {
|
||||
}
|
||||
|
||||
// resolveCppModelPath 查找或下载 whisper.cpp 模型文件
|
||||
func (s *WhisperService) resolveCppModelPath(model string) string {
|
||||
func (s *whisperService) resolveCppModelPath(model string) string {
|
||||
modelName := strings.TrimPrefix(model, "ggml-")
|
||||
modelName = strings.TrimSuffix(modelName, ".bin")
|
||||
|
||||
@@ -262,8 +262,20 @@ func (s *WhisperService) resolveCppModelPath(model string) string {
|
||||
altPaths := []string{
|
||||
cppModelName,
|
||||
filepath.Join(home, ".cache", "whisper", "ggml-"+modelName+"-q5_0.bin"),
|
||||
"/opt/homebrew/share/whisper-cpp/models/" + cppModelName,
|
||||
"/usr/local/share/whisper-cpp/models/" + cppModelName,
|
||||
}
|
||||
// macOS: Homebrew 安装的 whisper.cpp 模型路径
|
||||
if runtime.GOOS == "darwin" {
|
||||
altPaths = append(altPaths,
|
||||
"/opt/homebrew/share/whisper-cpp/models/"+cppModelName,
|
||||
"/usr/local/share/whisper-cpp/models/"+cppModelName,
|
||||
)
|
||||
}
|
||||
// Linux: 常见系统安装路径
|
||||
if runtime.GOOS == "linux" {
|
||||
altPaths = append(altPaths,
|
||||
"/usr/share/whisper-cpp/models/"+cppModelName,
|
||||
"/usr/local/share/whisper-cpp/models/"+cppModelName,
|
||||
)
|
||||
}
|
||||
for _, p := range altPaths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
@@ -310,7 +322,7 @@ func (s *WhisperService) resolveCppModelPath(model string) string {
|
||||
}
|
||||
|
||||
// downloadFile 下载文件到指定路径(支持超时)
|
||||
func (s *WhisperService) downloadFile(url, destPath string, timeout time.Duration) error {
|
||||
func (s *whisperService) downloadFile(url, destPath string, timeout time.Duration) error {
|
||||
tmpPath := destPath + ".tmp"
|
||||
out, err := os.Create(tmpPath)
|
||||
if err != nil {
|
||||
@@ -346,7 +358,7 @@ func (s *WhisperService) downloadFile(url, destPath string, timeout time.Duratio
|
||||
}
|
||||
|
||||
// transcribeWithCpp 使用 whisper.cpp(C++ 版,参数格式不同)
|
||||
func (s *WhisperService) transcribeWithCpp(ctx context.Context, req *TranscribeReq, binaryPath, model, language string) (res *TranscribeRes, err error) {
|
||||
func (s *whisperService) transcribeWithCpp(ctx context.Context, req *TranscribeReq, binaryPath, model, language string) (res *TranscribeRes, err error) {
|
||||
outputDir := filepath.Dir(req.AudioPath)
|
||||
baseName := strings.TrimSuffix(filepath.Base(req.AudioPath), filepath.Ext(req.AudioPath))
|
||||
outputPrefix := filepath.Join(outputDir, baseName)
|
||||
|
||||
Reference in New Issue
Block a user