123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- package services
- import (
- "baliance.com/gooxml/document"
- "baliance.com/gooxml/measurement"
- "baliance.com/gooxml/schema/soo/wml"
- "bufio"
- "eta/eta_api/models"
- "eta/eta_api/models/speech_recognition"
- "eta/eta_api/services/alarm_msg"
- "eta/eta_api/utils"
- "fmt"
- "github.com/jung-kurt/gofpdf"
- "os"
- "strconv"
- "sync"
- "time"
- )
- const (
- SpeechRecognitionExportTypeTxt = 1
- SpeechRecognitionExportTypeDocx = 2
- SpeechRecognitionExportTypePdf = 3
- )
- // GetSpeechRecognitionTagMenuTreeRecursive 递归获取标签目录树
- func GetSpeechRecognitionTagMenuTreeRecursive(list []*speech_recognition.SpeechRecognitionTagMenu, parentId int) []*speech_recognition.SpeechRecognitionTagMenuItem {
- res := make([]*speech_recognition.SpeechRecognitionTagMenuItem, 0)
- for _, v := range list {
- if v.ParentId == parentId {
- t := new(speech_recognition.SpeechRecognitionTagMenuItem)
- t.MenuId = v.SpeechRecognitionTagMenuId
- t.MenuName = v.MenuName
- t.ParentId = v.ParentId
- t.Level = v.Level
- t.Sort = v.Sort
- t.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime)
- t.Children = GetSpeechRecognitionTagMenuTreeRecursive(list, v.SpeechRecognitionTagMenuId)
- res = append(res, t)
- }
- }
- return res
- }
- // BatchConvertSpeech 批量转写语音
- func BatchConvertSpeech(speeches []*speech_recognition.SpeechRecognition) {
- var err error
- defer func() {
- if err != nil {
- tips := fmt.Sprintf("批量转写语音失败, ErrMsg: %s", err.Error())
- utils.FileLog.Info(tips)
- go alarm_msg.SendAlarmMsg(tips, 1)
- }
- }()
- conf, e := models.GetBusinessConf()
- if e != nil {
- err = fmt.Errorf("获取配置失败, Err: %s", e.Error())
- return
- }
- if conf[models.BusinessConfTencentApiSecretId] == "" || conf[models.BusinessConfTencentApiSecretKey] == "" || conf[models.BusinessConfTencentApiRecTaskCallbackUrl] == "" {
- err = fmt.Errorf("API配置有误, SecretId: %s, SecretKey: %s, Callback: %s", conf[models.BusinessConfTencentApiSecretId], conf[models.BusinessConfTencentApiSecretKey], conf[models.BusinessConfTencentApiRecTaskCallbackUrl])
- return
- }
- // 限制接口请求频率
- apiLimit := make(chan struct{}, 20)
- var wg sync.WaitGroup
- for _, v := range speeches {
- wg.Add(1)
- go func(speech *speech_recognition.SpeechRecognition) {
- defer func() {
- wg.Done()
- <-apiLimit
- }()
- apiLimit <- struct{}{}
- // 发起请求
- var errMsg string
- var r TencentRecTaskReq
- r.FileUrl = speech.ResourceUrl
- r.SecretId = conf[models.BusinessConfTencentApiSecretId]
- r.SecretKey = conf[models.BusinessConfTencentApiSecretKey]
- r.CallbackUrl = conf[models.BusinessConfTencentApiRecTaskCallbackUrl]
- taskId, e := TencentCreateRecTask(r)
- if e != nil {
- errMsg = "创建语音识别任务失败"
- utils.FileLog.Info("TencentCreateRecTask创建语音识别任务失败, ErrMsg: %s", e.Error())
- }
- if errMsg == "" {
- apiLog := new(speech_recognition.SpeechRecognitionApiLog)
- apiLog.SpeechRecognitionId = speech.SpeechRecognitionId
- apiLog.RequestId = strconv.Itoa(taskId)
- apiLog.RequestCode = -1
- apiLog.CreateTime = time.Now().Local()
- apiLog.ModifyTime = time.Now().Local()
- if e = apiLog.Create(); e != nil {
- errMsg = "生成API请求失败"
- utils.FileLog.Info("CreateApiLog生成API请求记录失败, ErrMsg: %s", e.Error())
- return
- }
- }
- // 有报错则更新对应语音识别状态
- if errMsg == "" {
- return
- }
- speech.State = speech_recognition.SpeechRecognitionStateFail
- speech.ConvertRemark = errMsg
- speech.ModifyTime = time.Now().Local()
- updateCols := []string{speech_recognition.SpeechRecognitionCols.State, speech_recognition.SpeechRecognitionCols.ConvertRemark, speech_recognition.SpeechRecognitionCols.ModifyTime}
- if e = speech.Update(updateCols); e != nil {
- utils.FileLog.Info("UpdateSpeech更新语音识别状态失败, ErrMsg: %s", e.Error())
- return
- }
- }(v)
- }
- wg.Wait()
- return
- }
- // SpeechRecognitionContentExport 导出语音识别内容
- func SpeechRecognitionContentExport(exportType int, exportTimestamp bool, fileName string, contents []*speech_recognition.SpeechRecognitionContent) (result string, err error) {
- defer func() {
- if err != nil {
- fmt.Println(err)
- }
- }()
- if len(contents) == 0 {
- return
- }
- // 整理内容
- exportText := ""
- exportArr := make([]string, 0)
- exportPdfArr := make([]string, 0)
- for _, v := range contents {
- if v.Content == "" {
- continue
- }
- sec := ""
- secPdf := ""
- if exportTimestamp {
- // 毫秒转时间格式
- sec = fmt.Sprintf("%s\n%s\n\n", utils.MillisecondsToHHMMSS(v.StartMs), v.Content)
- secPdf = fmt.Sprintf("%s %s", utils.MillisecondsToHHMMSS(v.StartMs), v.Content)
- } else {
- sec = fmt.Sprintf("%s\n\n", v.Content)
- secPdf = v.Content
- }
- exportText += sec
- exportArr = append(exportArr, sec)
- exportPdfArr = append(exportPdfArr, secPdf)
- }
- // 导出doc
- if exportType == SpeechRecognitionExportTypeDocx {
- doc := document.New()
- for _, v := range exportArr {
- p := doc.AddParagraph()
- prop := p.Properties()
- prop.Spacing().SetLineSpacing(measurement.Distance(1.5*15*measurement.Point), wml.ST_LineSpacingRuleAuto)
- prop.SetAlignment(wml.ST_JcLeft)
- run := p.AddRun()
- runProp := run.Properties()
- runProp.SetSize(measurement.Distance(15 * measurement.Point))
- runProp.SetFontFamily("宋体")
- run.AddText(v)
- run.AddBreak()
- }
- filePath := fmt.Sprintf("%s.docx", fileName)
- if e := doc.SaveToFile(filePath); e != nil {
- err = fmt.Errorf("生成docx失败, Err: %s", e.Error())
- return
- }
- result = filePath
- return
- }
- // 导出pdf
- if exportType == SpeechRecognitionExportTypePdf {
- pdf := gofpdf.New("P", "mm", "A4", "")
- pdf.AddPage()
- pdf.AddUTF8Font("SimHei", "", "static/SimHei.ttf") // 此处字体文件只能用本地的
- pdf.SetFont("SimHei", "", 14)
- // 计算可用内容区域宽度
- w, _ := pdf.GetPageSize()
- marginLeft := 10.0
- marginRight := 10.0
- availableWidth := w - marginLeft - marginRight
- for _, v := range exportPdfArr {
- pdf.MultiCell(availableWidth, 10, v, "", "L", false)
- pdf.MultiCell(availableWidth, 5, "", "", "L", false) // 单纯的换行
- }
- filePath := fmt.Sprintf("%s.pdf", fileName)
- if e := pdf.OutputFileAndClose(filePath); e != nil {
- err = fmt.Errorf("生成pdf失败, Err: %s", e.Error())
- return
- }
- result = filePath
- return
- }
- // 默认导出txt
- filePath := fmt.Sprintf("%s.txt", fileName)
- file, e := os.Create(filePath)
- if e != nil {
- err = fmt.Errorf("生成txt文件失败, err: %s", e.Error())
- return
- }
- defer file.Close()
- // 写入txt
- writer := bufio.NewWriter(file)
- _, e = writer.WriteString(exportText)
- if e != nil {
- err = fmt.Errorf("写入txt文件失败, err: %s", e.Error())
- return
- }
- if e = writer.Flush(); e != nil {
- err = fmt.Errorf("刷新txt缓存失败, err: %s", e.Error())
- return
- }
- result = filePath
- return
- }
|