Text to Speech Speech to Text

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