Text to Speech Speech to Text

job.go 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. package job
  2. import (
  3. "crypto/md5"
  4. "encoding/json"
  5. "fmt"
  6. "git.links123.net/Slate/CorpusAI/service"
  7. "git.links123.net/Slate/CorpusAI/service/store/cache"
  8. "git.links123.net/Slate/CorpusAI/service/store/mysql"
  9. "git.links123.net/Slate/CorpusAI/config"
  10. "github.com/jinzhu/gorm"
  11. _ "github.com/go-sql-driver/mysql"
  12. "github.com/spf13/cobra"
  13. "github.com/gocolly/colly"
  14. "io/ioutil"
  15. "log"
  16. "math/rand"
  17. "net/http"
  18. "net/url"
  19. "strconv"
  20. "strings"
  21. "html"
  22. "time"
  23. )
  24. type TtsRaw struct {
  25. ID int64
  26. Text string //翻译的文本
  27. UniqKey string //唯一键值
  28. Status int64
  29. Remark string
  30. }
  31. func (TtsRaw) TableName() string {
  32. return "lnk_corpus_tts_raw"
  33. }
  34. type langType struct {
  35. languageCode string;
  36. voiceName string;
  37. }
  38. type Phrase struct {
  39. Text string
  40. Paraphrase string
  41. Type int64
  42. Word string
  43. }
  44. type Phonetic struct {
  45. ID int64
  46. Word string //翻译的文本
  47. UkPhonetic string //唯一键值
  48. Status int64
  49. UsPhonetic string
  50. }
  51. func (Phrase) TableName() string {
  52. return "lnk_corpus_phrase_spider"
  53. }
  54. func RunCommand() *cobra.Command {
  55. cmd := &cobra.Command{
  56. Use: "job",
  57. Short: "Run the job service",
  58. Run: func(cmd *cobra.Command, args []string) {
  59. //fmt.Println("Echo: " + strings.Join(args, " "))
  60. minId := args[0]
  61. maxId := args[1]
  62. dbConfig := config.C.DB
  63. settings := dbConfig.User+":"+dbConfig.Password+"@tcp("+dbConfig.Host+")/"+dbConfig.Name+"?charset=utf8&parseTime=True&loc=Local"
  64. var phoneticList []Phonetic
  65. db, err := gorm.Open("mysql", settings)
  66. if err != nil {
  67. panic("failed to connect database")
  68. }
  69. db.Where("id <= ? and id >= ?", maxId, minId).Find(&ttsRawList)
  70. for _, ttsRaw := range phoneticList {
  71. word := ttsRaw.Word
  72. Phonetic := transApi(word, "", "")
  73. //if result == true {
  74. ttsRaw.Status = 1
  75. ttsRaw.UkPhonetic = Phonetic["uk_phonetic"]
  76. ttsRaw.UsPhonetic = Phonetic["us_phonetic"]
  77. fmt.Println(ttsRaw)
  78. db.Save(&ttsRaw)
  79. }
  80. db.Close()
  81. //return
  82. //var ttsRawList []TtsRaw
  83. //
  84. //db, err := gorm.Open("mysql", settings)
  85. //if err != nil {
  86. // panic("failed to connect database")
  87. //}
  88. //
  89. //db.Where("id <= ? and id >= ?", maxId, minId).Find(&ttsRawList)
  90. //
  91. //for _, ttsRaw := range ttsRawList {
  92. //
  93. // word := ttsRaw.Text
  94. // c := colly.NewCollector(
  95. // // Visit only domains: hackerspaces.org, wiki.hackerspaces.org
  96. // colly.AllowedDomains("dict.cn", "m.dict.cn"),
  97. // )
  98. //
  99. // // 例句
  100. // c.OnHTML("div[class=\"layout sort\"]", func(e *colly.HTMLElement) {
  101. // e.ForEach("ol", func(_ int, eol *colly.HTMLElement) {
  102. // eol.ForEach("li", func(_ int, el *colly.HTMLElement) {
  103. // //fmt.Println(el.DOM.Html())
  104. // liText, _ := el.DOM.Html()
  105. // liData := strings.Split(html.UnescapeString(liText), "<br/>")
  106. // example := ReplaceTrim(liData[0])
  107. // exampleParaphrase := ReplaceTrim(liData[1])
  108. //
  109. // examplePhrase := Phrase{Text:example, Paraphrase:exampleParaphrase, Type: 0, Word:word}
  110. // fmt.Println(examplePhrase)
  111. // db.Create(&examplePhrase)
  112. // })
  113. // })
  114. // })
  115. //
  116. // // 词汇搭配, 短语
  117. // c.OnHTML("div[class=\"layout coll\"]", func(e *colly.HTMLElement) {
  118. //
  119. // e.ForEach("li", func(_ int, el *colly.HTMLElement) {
  120. // if el.ChildAttr("a", "href") != "" {
  121. // phrase := ReplaceTrim(el.ChildText("a"))
  122. // paraphrase := ReplaceTrim(el.Text)
  123. // paraphrase = strings.Replace(paraphrase, phrase, "", 1)
  124. //
  125. // newPhrase := Phrase{Text:phrase, Paraphrase:paraphrase, Type: 1, Word:word}
  126. // fmt.Println(newPhrase)
  127. // db.Create(&newPhrase)
  128. // }
  129. // })
  130. // })
  131. //
  132. // c.OnHTML("div[class=\"layout anno\"]", func(e *colly.HTMLElement) {
  133. //
  134. // e.ForEach("li", func(_ int, el *colly.HTMLElement) {
  135. // if el.ChildAttr("a", "href") != "" {
  136. // phrase := ReplaceTrim(el.ChildText("a"))
  137. // paraphrase := ReplaceTrim(el.Text)
  138. // paraphrase = strings.Replace(paraphrase, phrase, "", 1)
  139. //
  140. // newPhrase := Phrase{Text:phrase, Paraphrase:paraphrase, Type: 1, Word:word}
  141. // fmt.Println(newPhrase)
  142. // db.Create(&newPhrase)
  143. // }
  144. // })
  145. // })
  146. // c.OnRequest(func(r *colly.Request) {
  147. // fmt.Println("Visiting", r.URL.String())
  148. // })
  149. //
  150. // c.Visit("http://dict.cn/"+word)
  151. //
  152. // //if result == true {
  153. // ttsRaw.Status = 1
  154. // //更新成功
  155. // //} else {
  156. // // ttsRaw.Status = -1
  157. // // //更新错误状态和msg
  158. // // ttsRaw.Remark = msg
  159. // //}
  160. // fmt.Println(ttsRaw)
  161. // db.Save(&ttsRaw)
  162. //}
  163. db.Close()
  164. },
  165. }
  166. return cmd
  167. }
  168. func SyncTtsOss(text string, speed float64, pitch float64) (bool, string) {
  169. text, _ = url.QueryUnescape(text)
  170. text = strings.Trim(text , "")
  171. if text == "" {
  172. return false, "Error: text null"
  173. }
  174. typeMap := make(map[int]langType)
  175. typeMap[1] = langType{"en-US","en-US-Wavenet-B"}
  176. typeMap[2] = langType{"en-US","en-US-Wavenet-C"}
  177. typeMap[3] = langType{"en-GB","en-GB-Wavenet-B"}
  178. typeMap[4] = langType{"en-GB","en-GB-Wavenet-C"}
  179. for _, lang := range typeMap {
  180. ossObjectKey := service.GetTtsOssKey(text, lang.voiceName, lang.languageCode, speed, pitch)
  181. textKey := cache.GetTextKey(ossObjectKey)
  182. AudioContent, err := service.TextToSpeech(text, lang.voiceName, lang.languageCode, speed, pitch)
  183. if err != nil {
  184. return false, "TextToSpeech Error:" + err.Error()
  185. }
  186. uploadResult, err := service.UploadHkOss(ossObjectKey, AudioContent)
  187. if uploadResult == true {
  188. uploadResult, err = service.UploadOss(ossObjectKey, AudioContent)
  189. if uploadResult == true {
  190. //hk&cn节点oss都同步成功, set db
  191. mysql.CreateCorpusTts(text, textKey, lang.languageCode, lang.voiceName, ossObjectKey, speed, pitch)
  192. }
  193. }
  194. if err != nil {
  195. return false, "UploadHkOss Error" + err.Error()
  196. }
  197. }
  198. return true, ""
  199. }
  200. func ReplaceTrim(str string) string {
  201. str = strings.Replace(str, "\n", "", -1)
  202. str = strings.Replace(str, "\t", "", -1)
  203. return strings.Trim(str, "")
  204. }
  205. func transApi(text, from, to string) map[string]string {
  206. apiUrl := "http://openapi.youdao.com/api"
  207. appKey := "629a1435e6d2a894"
  208. secKey := "DAgjDJfE0xPdZtMVhl1YUFUIrZc2DVHd"
  209. basicMap := make (map[string]string)
  210. if from == "" {
  211. from = "auto"
  212. }
  213. if to == "" {
  214. to = "auto"
  215. }
  216. rand.Seed(time.Now().Unix())
  217. salt := strconv.Itoa(rand.Int())
  218. sign := buildSign(appKey, text, salt, secKey)
  219. request, err := http.NewRequest("GET", apiUrl, nil)
  220. if err != nil {
  221. log.Print(err)
  222. return basicMap
  223. }
  224. query := request.URL.Query()
  225. query.Add("q", text)
  226. query.Add("from", from)
  227. query.Add("to", to)
  228. query.Add("appKey", appKey)
  229. query.Add("salt", salt)
  230. query.Add("sign", sign)
  231. request.URL.RawQuery = query.Encode()
  232. //fmt.Println(request.URL.String())
  233. var resp *http.Response
  234. resp, err = http.DefaultClient.Do(request)
  235. if err != nil {
  236. log.Print(err)
  237. return basicMap
  238. }
  239. defer resp.Body.Close()
  240. body, _ := ioutil.ReadAll(resp.Body)
  241. result := map[string]interface{}{}
  242. json.Unmarshal(body, &result)
  243. basic := result["basic"].(map[string]string)
  244. //fmt.Println(basic["phonetic"],basic["uk-phonetic"],basic["us-phonetic"])
  245. basicMap["uk-phonetic"] = basic["uk-phonetic"]
  246. basicMap["us-phonetic"] = basic["us-phonetic"]
  247. return basicMap
  248. }
  249. func buildSign(appKey, text, salt, secKey string) string {
  250. data := []byte(appKey + text + salt + secKey)
  251. hash := md5.Sum(data)
  252. return fmt.Sprintf("%x", hash)
  253. }