2

Serverless实战驾校小程序【语音读题】六

 3 years ago
source link: https://studygolang.com/articles/15931?fr=sidebar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

语音读题功能

为了更方便查看题目,我们加入读题功能。语音读题主要应用在智能客服机器人、电子有声读物、智慧教育等领域,了解到目前市场语音合成技术,主要有讯飞语音、百度语音、腾讯语音这几家大厂。 都支持男女生声,讯飞价格比较贵,这里发现腾讯语音合成暂时不收费,

腾讯云的语言合成介绍
https://cloud.tencent.com/product/tts#scenarios

语音合成(Text To Speech)满足已知文本生成语音的需求,打通人机交互闭环。多种音色选择,支持自定义音量、语速,为企业客户提供定制自有领域词库和个性化发音人服务,让发音更自然、更专业、更符合场景需求。语音合成广泛应用于语音导航、有声读物、标准发音领读、自动新闻播报等场景。

本以为这些API厂商,直接提供了API接口,小程序里请求就好了,现实不是的,做法跟做微信支付有点类似。必须自己实现一套服务端API,服务端实现接口加密等操作。

这几家都需要这样做,这里首先把需要的资料准备好。

  1. 开发语言 这里选Golang,官方有服务端SDK
  2. 腾讯云API密匙,自己在控制台查看并记录
  3. 开发文档地址:https://cloud.tencent.com/document/api/441/18086
  4. 选一台服务器,备案好域名,配置好https
    beego.Router("/1/textToVoice", &controllers.CloudController{}, "post:TextToVoice")

2.控制器

func (cloud *CloudController) TextToVoice() {
    body := cloud.Ctx.Input.CopyBody(beego.BConfig.MaxMemory)
    js, err := simplejson.NewJson(body)
    if err != nil {
        cloud.responseError(err)
    }
    //获取文本信息
    text := js.Get("text").MustString()
    //判断不能为空
    if strings.TrimSpace(text) == "" {
        cloud.responseError(fmt.Errorf("text param不能为空"))
    }
    
//这里初始化大家传入自己腾讯云的key信息
    client, _ := aai.NewClientWithSecretId(
        "id",
        "key",
        regions.Guangzhou)

    request := aai.NewTextToVoiceRequest()
    request.Text = common.StringPtr(text)
    request.SessionId = common.StringPtr(uuid.GetRandomString(16))
    request.ModelType = common.Int64Ptr(-1)
    request.ModelType = common.Int64Ptr(-1)
    request.Speed = common.Float64Ptr(0.8)
    response, err := client.TextToVoice(request)
    // 处理异常
    if _, ok := err.(*errors.TencentCloudSDKError); ok {
        cloud.responseError(fmt.Errorf("An API error has returned: %s", err))
    }
    // 非SDK异常,直接失败。实际代码中可以加入其他的处理。
    if err != nil {
        cloud.responseError(err)
    }
    // 打印返回的json字符串
    var base64Str *string = response.Response.Audio
    fileByte, err := models.Base64Decode([]byte(*base64Str))
    if err != nil {
        cloud.responseError(err)
    }

    fileName := uuid.GetRandomString(16) + "_" + fmt.Sprintf("%d", time.Now().Unix()) + ".wav"
    filePath := "/data/dyfsuda/app/restful/files/" + fileName
    url := "https://api.xxxx.com/files/" + fileName
//把文件写入目录
    if err = ioutil.WriteFile(filePath, fileByte, os.ModeAppend); err != nil {
        cloud.responseError(err)
    }
    if err = os.Chmod(filePath, 0777); err != nil {
        cloud.responseError(err)
    }
//返回文件路径给客户端
    cloud.Data["json"] = map[string]string{"url": url}
    cloud.ServeJSON()
}

这里每次的题目可能都不一样,所以就不更新到数据库了,需要的时候,调用一次接口,如果接口收费,这里就把语音文件路径保存到数据表里,每次判断数据表是否存在语音就可以了。

目前开发这读题还是需要自己有服务器,如果现成的API调用就好了。

4276407-0181b408d920a95d.png
image.png

这项目目前已经上线,大家可以体验下读题效果。

4276407-d6b5e691b088a795.png
image.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK