package service import ( "bytes" "encoding/json" "errors" "gorm.io/gorm" "io" "mime/multipart" "net/http" "os" "speechAnalysis/conf" "speechAnalysis/constvar" "speechAnalysis/models" "speechAnalysis/pkg/logx" ) // Response 结构体用于存储响应体的内容 type Response struct { Code int `json:"code"` Msg string `json:"msg"` Result string `json:"result"` Score float64 `json:"score"` } func AnalysisAudio(filename string, targetURL string) (resp Response, err error) { file, err := os.Open(filename) if err != nil { return } defer file.Close() // 创建一个缓冲区来存储表单数据 var requestBody bytes.Buffer writer := multipart.NewWriter(&requestBody) // 创建一个表单字段,用于存储文件 fileWriter, err := writer.CreateFormFile("audio", filename) if err != nil { return } // 将文件内容复制到表单字段中 _, err = io.Copy(fileWriter, file) if err != nil { return } // 关闭表单写入器,以便写入末尾的边界 writer.Close() // 创建POST请求,指定URL和请求体 request, err := http.NewRequest("POST", targetURL, &requestBody) if err != nil { return } // 设置请求头,指定Content-Type为multipart/form-data request.Header.Set("Content-Type", writer.FormDataContentType()) // 发送请求 client := &http.Client{} response, err := client.Do(request) if err != nil { return } defer response.Body.Close() // 读取响应 body := &bytes.Buffer{} _, err = io.Copy(body, response.Body) if err != nil { return } err = json.NewDecoder(body).Decode(&resp) if err != nil { return } return } func Process(audioId uint) (err error) { audio, err := models.NewAudioSearch().SetID(audioId).First() if err != nil { return errors.New("查找音频失败") } if audio.AudioStatus != constvar.AudioStatusUploadOk && audio.AudioStatus != constvar.AudioStatusFailed { return errors.New("状态不正确") } err = models.NewAudioSearch().SetID(audioId).UpdateByMap(map[string]interface{}{"audio_status": constvar.AudioStatusProcessing}) if err != nil { return errors.New("DB错误") } go func() { resp, err := AnalysisAudio(audio.FilePath, conf.AanlysisConf.Url) if err != nil { logx.Errorf("err when AnalysisAudio:%v", err) _ = models.NewAudioSearch().SetID(audioId).UpdateByMap(map[string]interface{}{"audio_status": constvar.AudioStatusFailed}) return } if resp.Code != 0 { logx.Errorf("AnalysisAudio error return:%v", resp) _ = models.NewAudioSearch().SetID(audioId).UpdateByMap(map[string]interface{}{"audio_status": constvar.AudioStatusFailed}) return } logx.Infof("AnalysisAudio result: %v", resp) err = models.WithTransaction(func(db *gorm.DB) error { err = models.NewAudioSearch().SetID(audioId).UpdateByMap(map[string]interface{}{ "audio_status": constvar.AudioStatusFinish, "score": resp.Score, }) if err != nil { return err } err = models.NewAudioTextSearch().Save(&models.AudioText{ AudioID: audio.ID, AudioText: resp.Result, }) return err }) if err != nil { logx.Infof("AnalysisAudio success but update record failed: %v", err) return } }() return nil }