From 5e232e932a1a5731ade3362cd144bf6552c8f2d6 Mon Sep 17 00:00:00 2001 From: wuchunlei Date: Fri, 6 Dec 2024 14:37:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E5=AD=97=E8=BD=AC=E9=9F=B3=E9=A2=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../peanut/common/utils/BaiduVoicesUtils.java | 139 +++++++++++++++--- .../BookChapterContentController.java | 56 +++++++ 2 files changed, 178 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/peanut/common/utils/BaiduVoicesUtils.java b/src/main/java/com/peanut/common/utils/BaiduVoicesUtils.java index 693380ec..7ff66d5d 100644 --- a/src/main/java/com/peanut/common/utils/BaiduVoicesUtils.java +++ b/src/main/java/com/peanut/common/utils/BaiduVoicesUtils.java @@ -1,25 +1,118 @@ package com.peanut.common.utils; -import java.io.File; -import java.io.FileOutputStream; +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.util.Arrays; import java.util.UUID; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import org.joda.time.DateTime; public class BaiduVoicesUtils { // 填写申请百度语音申请的appkey 申请地址:百度AI开放平台 - //todo private final static String appKey = "aKDun6vXyqPLhWMdoIsv87Ez"; + private final static String appKey = "WOKN473V1o1gL8WMsAkfJZIY"; + private final static String secretKey = "CpgbKdB9aZu2esnq5lMdqRZG37Jn3a76"; + + + public static String shortText(String content){ + try { + String getTokenURL = "https://tsn.baidu.com/text2audio?tok=" + getAccessToken(); + getTokenURL += "&cuid=zcc123456&ctp=1&lan=zh"; + getTokenURL += "&spd=4";//语速,取值0-15,默认为5中语速 + getTokenURL += "&pit=5";//音调,取值0-15,默认为5中语调 + getTokenURL += "&vol=7";//音量,取值0-15,默认为5中音量(取值为0时为音量最小值,并非为无声) + getTokenURL += "&per=1";//度小宇=1,度小美=0,度逍遥(基础)=3,度丫丫=4 度逍遥(精品)=5003,度小鹿=5118,度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5 + getTokenURL += "&tex=" + ConnUtil.urlEncode(content); + URL url = new URL(getTokenURL); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + String contentType = conn.getContentType(); + if (contentType.contains("mp3")) { + byte[] bytes = ConnUtil.getResponseBytes(conn); + String fileUrl = uploadFile(new ByteArrayInputStream(bytes),UUID.randomUUID().toString()+".mp3"); + return fileUrl; + } else { + System.err.println("ERROR: content-type= " + contentType); + String res = ConnUtil.getResponseString(conn); + System.err.println(res); + return ""; + } + }catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + //长文字查询 + public void queryVoice(String id) throws Exception { + URL url = new URL("https://aip.baidubce.com/rpc/2.0/tts/v1/query?access_token=" + getAccessToken()); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Accept", "application/json"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setDoOutput(true); + OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("task_ids", Arrays.asList(id)); + writer.write(jsonObject.toString()); + writer.flush(); + writer.close(); + String result = ConnUtil.getResponseString(conn); + JSONArray tasksInfo = (JSONArray)(JSONObject.parseObject(result).get("tasks_info")); + JSONObject i = (JSONObject)tasksInfo.get(0); + String taskStatus = i.get("task_status").toString(); + if ("Running".equals(taskStatus)){ + queryVoice(id); + } + System.out.println("taskId:" + result); + } + //长文字转换 + public String excute(String content) throws Exception { + URL url = new URL("https://aip.baidubce.com/rpc/2.0/tts/v1/create?access_token=" + getAccessToken()); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Accept", "application/json"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setDoOutput(true); + OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("text",content); + jsonObject.put("voice",1);//基础音库:度小宇=1,度小美=0,度逍遥(基础)=3,度丫丫=4;精品音库:度逍遥(精品)=5003,度小鹿=5118,度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5。默认为度小美 + jsonObject.put("lang", "zh");//固定值zh。语言选择,目前只有中英文混合模式,填写固定值zh + jsonObject.put("speed", 3);//取值0-15,默认为5中语速 + jsonObject.put("pitch", 5);//取值0-15,默认为5中语调 + jsonObject.put("volume", 8);//取值0-15,默认为5中音量(取值为0时为音量最小值,并非为无声) + jsonObject.put("enable_subtitle", 1);//取值范围0, 1, 2,默认为0。0表示不开启字幕,1表示开启句级别字幕,2表示开启词级别字幕 + writer.write(jsonObject.toString()); + writer.flush(); + writer.close(); + String result = ConnUtil.getResponseString(conn); + String taskId = JSONObject.parseObject(result).get("task_id").toString(); + System.out.println("taskId result json:" + taskId); + return taskId; + } + + public static String getAccessToken() throws Exception { + String getTokenURL = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials" + "&client_id=" + ConnUtil.urlEncode(appKey) + + "&client_secret=" + ConnUtil.urlEncode(secretKey); + URL url = new URL(getTokenURL); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setConnectTimeout(5000); + String result = ConnUtil.getResponseString(conn); + String accessToken = JSONObject.parseObject(result).get("access_token").toString(); + return accessToken; + } + + + + -// private final static String appKey = "eaPPX40oIazH8R4oWsD9U4IT"; - private final static String appKey = "xkyZMti9hu6KSQ8PdRDsadqI"; - // 填写申请百度语音申请的APP SECRET -// todo private final static String secretKey = "ew9dMb4yGmwF1g4qutxNvogzjd9eP5tb"; -// private final static String secretKey = "DTN0ioQywwM23IoT2ZzEBmvfBe63ATEY"; - private final static String secretKey = "KQvdrrADpV7hBzptqvakwG56dYuGljeg"; // text 的内容为"欢迎使用百度语音合成"的urlencode,utf-8 编码 private final String text = "百度百科是百度公司推出的一部内容开放、自由的网络百科全书。"; @@ -42,14 +135,6 @@ public class BaiduVoicesUtils { TokenHolder holder = new TokenHolder(appKey, secretKey, TokenHolder.ASR_SCOPE); holder.resfresh(); String token = holder.getToken(); - String token1 = holder.getToken(); - final String s = ConnUtil.urlEncode(content); - String url21 = url +"?tex=" + s; - url21 +="&per="+ per; - url21 +=""+cuid; - url21 +=""+vol; - long expiresAt = holder.getExpiresAt(); -// for (String a:list) { String url2 = url + "?tex=" + ConnUtil.urlEncode(content); url2 += "&per=" + per; url2 += "&spd=" + spd; @@ -80,4 +165,24 @@ public class BaiduVoicesUtils { // } } + public static String uploadFile(InputStream inputStream, String fileName) { + String endpoint = ConstantPropertiesUtils.END_POIND; + String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID; + String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET; + String bucketName = ConstantPropertiesUtils.BUCKET_NAME; + try { + OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); + String uuid = UUID.randomUUID().toString().replaceAll("-", ""); + fileName = uuid + fileName; + String datePath = new DateTime().toString("yyyy/MM/dd"); + fileName = datePath + "/" + fileName; + ossClient.putObject(bucketName, fileName, inputStream); + ossClient.shutdown(); + String url = "https://" + bucketName + "." + endpoint + "/" + fileName; + return url; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } } diff --git a/src/main/java/com/peanut/modules/book/controller/BookChapterContentController.java b/src/main/java/com/peanut/modules/book/controller/BookChapterContentController.java index c4c341ff..1d854c2a 100644 --- a/src/main/java/com/peanut/modules/book/controller/BookChapterContentController.java +++ b/src/main/java/com/peanut/modules/book/controller/BookChapterContentController.java @@ -52,6 +52,62 @@ public class BookChapterContentController { private UserEbookBuyService userEbookBuyService; @Autowired private ShopProductBookService shopProductBookService; + + + //章节内容单句转成音频 + @RequestMapping("/contentToVoices") + public R contentToVoices(@RequestBody Map params){ + //调用百度语音合成 API + String voices = BaiduVoicesUtils.shortText(params.get("content").toString()); + if (StringUtils.isEmpty(voices)) { + return R.error("语音上传失败"); + } + return R.ok().put("voices", voices); + } + + //书籍全部章节转成音频 + @RequestMapping("/bookToVoices") + public R bookToVoices(@RequestBody Map params){ + // 1、创建服务,创建线程池 + ExecutorService service = Executors.newFixedThreadPool(5); + List list = bookChapterContentService.list(new LambdaQueryWrapper() + .eq(BookChapterContentEntity::getBookId,params.get("bookId"))); + for (BookChapterContentEntity bcc:list){ + if (!bcc.getContent().contains("https")&&!"".equals(bcc.getContent())){ + service.execute(new Runnable() { + @Override + public void run() { + //调用百度语音合成 API + String voices = BaiduVoicesUtils.shortText(bcc.getContent()); + bcc.setVoices(voices); + bookChapterContentService.updateById(bcc); + } + }); + } + } + return R.ok(); + } + + + + + + + + + + + + + + + + + + + + + /** * 列表