扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇内容主要讲解“调用AI api实现网页文字朗读的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“调用AI api实现网页文字朗读的方法”吧!
创新互联建站主营襄垣网站建设的网络公司,主营网站建设方案,App定制开发,襄垣h5微信小程序开发搭建,襄垣网站营销推广欢迎襄垣等地区企业咨询
京东云上提供了足够多的人工智能api,并且都使用了http的方式进行了封装,用户可以方便在自己的系统中接入京东云的ai能力。今天就是介绍一下如何编写很少的代码就能使用京东云的语音合成api在网页中实现文字朗读,最终实现效果,延迟小,支持主流设备,声调优美,还能男女生切换。
最终效果,微信打开链接,点击播放按钮则可以进行文字朗读。
京东云AI API使用Restful接口风格,同时提供了java和python的sdk,使用sdk能够方便的封装参数,调用api获得数据。
为了提升调用方的响应速度,语音合成api采用了分段合成的模式,所以调用的时候在后端逻辑中按顺序多次调用,将音频数据以数据流的形式回写给前端。
访问京东云api需要获取 ak sk ,配合sdk使用;
进入京东云控制台-账号管理-Access Key管理,创建并获取Access Key。
这里给出后端部分源码,实现一个controller,开发一个get请求方法,参数封装的逻辑全都提炼出单独的方法,代码逻辑结构简单易懂。代码使用fastJson处理参数,另外引用了京东云sdk,其余都是jdk自带的api,依赖很少。
1 import com.alibaba.fastjson.JSON; 2 import com.alibaba.fastjson.JSONObject; 3 import com.wxapi.WxApiCall.WxApiCall; 4 import com.wxapi.model.RequestModel; 5 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.RequestHeader; 9 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 import java.io.OutputStream; 14 import java.util.Base64; 15 import java.util.HashMap; 16 import java.util.Map; 17 18 @Controller 19 public class TTSControllerExample { 20 //url appkey secretkey 21 private static final String url = "https://aiapi.jdcloud.com/jdai/tts"; 22 private static final String appKey = ""; 23 private static final String secretKey = ""; 24 25 @GetMapping("/tts/stream/example") 26 public void ttsStream( 27 @RequestHeader(value = "Range", required = false) String range, 28 HttpServletRequest req, 29 HttpServletResponse resp) { 30 31 //应对safari的第一次确认请求携带header Range:bytes=0-1,此时回写1byte数据,防止错误 32 if ("bytes=0-1".equals(range)) { 33 try { 34 byte[] temp = new byte['a']; 35 resp.setHeader("Content-Type", "audio/mp3"); 36 OutputStream out = resp.getOutputStream(); 37 out.write(temp); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 return; 42 } 43 //封装输入参数 44 Map queryMap = processQueryParam(req); 45 String text = req.getParameter("text"); 46 //封装api调用请求报文 47 RequestModel requestModel = getBaseRequestModel(queryMap, text); 48 try { 49 //回写音频数据给前端 50 writeTtsStream(resp, requestModel); 51 } catch (IOException e) { 52 e.printStackTrace(); 53 } 54 } 55 56 /** 57 * 将前端输入参数封装为api调用的请求对象,同时设置url appkey secaretKey 58 * @param queryMap 59 * @param bodyStr 60 * @return 61 */ 62 private RequestModel getBaseRequestModel(Map queryMap, String bodyStr) { 63 RequestModel requestModel = new RequestModel(); 64 requestModel.setGwUrl(url); 65 requestModel.setAppkey(appKey); 66 requestModel.setSecretKey(secretKey); 67 requestModel.setQueryParams(queryMap); 68 requestModel.setBodyStr(bodyStr); 69 return requestModel; 70 } 71 72 /** 73 * 流式api调用,需要将sequenceId 依次递增,用该方法进行设置请求对象sequenceId 74 * @param sequenceId 75 * @param requestModel 76 * @return 77 */ 78 private RequestModel changeSequenceId(int sequenceId, RequestModel requestModel) { 79 requestModel.getQueryParams().put("Sequence-Id", sequenceId); 80 return requestModel; 81 } 82 83 /** 84 * 将request中的请求参数封装为api调用请求对象中的queryMap 85 * @param req 86 * @return 87 */ 88 private Map processQueryParam(HttpServletRequest req) { 89 String reqid = req.getParameter("reqid"); 90 int tim = Integer.parseInt(req.getParameter("tim")); 91 String sp = req.getParameter("sp"); 92 93 JSONObject parameters = new JSONObject(8); 94 parameters.put("tim", tim); 95 parameters.put("sr", 24000); 96 parameters.put("sp", sp); 97 parameters.put("vol", 2.0); 98 parameters.put("tte", 0); 99 parameters.put("aue", 3); 100 101 JSONObject property = new JSONObject(4); 102 property.put("platform", "Linux"); 103 property.put("version", "1.0.0"); 104 property.put("parameters", parameters); 105 106 MapqueryMap = new HashMap<>(); 107 //访问参数 108 queryMap.put("Service-Type", "synthesis"); 109 queryMap.put("Request-Id", reqid); 110 queryMap.put("Protocol", 1); 111 queryMap.put("Net-State", 1); 112 queryMap.put("Applicator", 1); 113 queryMap.put("Property", property.toJSONString()); 114 115 return queryMap; 116 } 117 118 /** 119 * 循环调用api,将音频数据回写到response对象 120 * @param resp 121 * @param requestModel 122 * @throws IOException 123 */ 124 public void writeTtsStream(HttpServletResponse resp, RequestModel requestModel) throws IOException { 125 //分段获取音频sequenceId从1递增 126 int sequenceId = 1; 127 changeSequenceId(sequenceId, requestModel); 128 //设置返回报文头内容类型为audio/mp3 129 resp.setHeader("Content-Type", "audio/mp3"); 130 //api请求sdk对象 131 WxApiCall call = new WxApiCall(); 132 //获取输出流用于输出音频流 133 OutputStream out = resp.getOutputStream(); 134 call.setModel(requestModel); 135 //解析返回报文,获得status 136 String response = call.request(); 137 JSONObject jsonObject = JSON.parseObject(response); 138 JSONObject data = jsonObject.getJSONObject("result"); 139 //第一次请求增加校验,如果错误则向前端回写500错误码 140 if (data.getIntValue("status") != 0) { 141 resp.sendError(500, data.getString("message")); 142 return; 143 } 144 //推送实际音频数据 145 String audio = data.getString("audio"); 146 byte[] part = Base64.getDecoder().decode(audio); 147 out.write(part); 148 out.flush(); 149 //判断是否已结束,多次请求对应多个index,index<0 代表最后一个包 150 if (data.getIntValue("index") < 0) { 151 return; 152 } 153 //循环推送剩余部分音频 154 while (data.getIntValue("index") >= 0) { 155 //sequenceid 递增 156 sequenceId = sequenceId + 1; 157 changeSequenceId(sequenceId, requestModel); 158 //请求api获得新的音频数据 159 call.setModel(requestModel); 160 response = call.request(); 161 jsonObject = JSON.parseObject(response); 162 data = jsonObject.getJSONObject("result"); 163 audio = data.getString("audio"); 164 part = Base64.getDecoder().decode(audio); 165 //回写新的音频数据 166 out.write(part); 167 out.flush(); 168 } 169 } 170 171 172 173 前端audio播放朗读 174 前端部分给出在vue 模块化开发中的script部分,由于采用html5的audio进行语音播放,为了兼容性需要引用howler.js (npm install howler),主要逻辑为根据设置的参数和待朗读的文字拼接一个url,调用howler.js 中的api进行播放。 175 176
到此,相信大家对“调用AI api实现网页文字朗读的方法”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流