阿里雲語音合成1.0版
阿新 • • 發佈:2018-12-24
官網文件https://helpcdn.aliyun.com/document_detail/84435.html
目前版本為2.0 ,但是發現限制:
- 傳入文字不能超過300個字元。
於是找到1.0的版本發現可以傳入幾千字,所以使用的1.0的版本,但是好像最近更新後1.0已經不存在了,好久之前就想就想整理的,真是可惜了。
@SuppressWarnings("unused") public String getYp(ContentTxt txt,HttpServletRequest request) throws Exception { //語音合成 if (txt != null && txt.getTxt()!= null) { NlsClient client = new NlsClient(); client.init(); String tts_text = txt.getTxt(); tts_text = tts_text.replaceAll("</?[^>]+>", ""); String fileName = UUID.randomUUID().toString(); int ttsTextLength = tts_text.length(); String[] longTexts; int i = 0; boolean isHead = false; //標識是否是第一個標頭檔案 String tts_part_text; //資料夾的路徑 String path = request.getSession().getServletContext().getRealPath("/"); path = path+"yyjs"; //資料夾不存在則新建 File fileDir = new File(path); if(!fileDir.exists()){ fileDir.setWritable(true); fileDir.mkdirs(); } //新建檔案 File file = new File(path,fileName+".pcm"); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } FileOutputStream outputStream = new FileOutputStream(file, true); longTexts = processLongText(tts_text); //處理文字,文字長度以50為限,擷取為多個檔案. while (ttsTextLength > 0) { tts_part_text = ""; if (ttsTextLength > 50) { if (i == 0) { isHead = true; } else { isHead = false; } for (; i < longTexts.length; i++) { tts_part_text = tts_part_text + longTexts[i]; if (i < longTexts.length - 1 && tts_part_text.length() + longTexts[i + 1].length() >= 50) { i = i + 1; break; } } } else { if (i == 0) { isHead = true; } for (; i < longTexts.length; i++) { tts_part_text = tts_part_text + longTexts[i]; } } NlsRequest req = new NlsRequest(); req.setApp_key("nls-service"); req.setTts_req(tts_part_text, "16000"); req.setTtsEncodeType("wav"); req.setTtsVoice("xiaoyun");//男聲:xiaogang req.setTtsVolume(50); req.setTtsSpeechRate(-100); req.setTtsBackgroundMusic(1, 0); req.authorize("", "");//此處填寫開通服務時的appKey, token NlsListener nlsListener = new LongTtsDemo(); NlsFuture future = client.createNlsFuture(req, nlsListener); int total_len = 0; byte[] data; while ((data = future.read()) != null) { if (data.length == 8044 ) { // 去掉wav頭,同時將多條wav轉成一條pcm outputStream.write(data, 44, data.length - 44); } else { outputStream.write(data, 0, data.length); } total_len += data.length; } future.await(10000); ttsTextLength = ttsTextLength - tts_part_text.length(); } outputStream.close(); //將pcm轉為wav,可以直接播放. 格式為:16kHz取樣率,16bit,單聲道 PcmToWav.copyWaveFile(path+"\\"+fileName+".pcm",path+"\\"+fileName+".wav"); client.close(); return path+"\\"+fileName+".wav"; } return null; }
這是官方提供的demo
package com.alibaba.idst.nls.demo; import com.alibaba.idst.nls.NlsClient; import com.alibaba.idst.nls.NlsFuture; import com.alibaba.idst.nls.event.NlsEvent; import com.alibaba.idst.nls.event.NlsListener; import com.alibaba.idst.nls.protocol.NlsRequest; import com.alibaba.idst.nls.protocol.NlsRequestASR; import com.alibaba.idst.nls.protocol.NlsRequestProto; import com.alibaba.idst.nls.protocol.NlsResponse; import com.alibaba.idst.nls.utils.PcmToWav; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Arrays; import java.util.UUID; /** * Created by songsong.sss on 16/12/12. */ public class LongTtsDemo implements NlsListener { static Logger logger = LoggerFactory.getLogger(LongTtsDemo.class); private NlsClient client = new NlsClient(); public String appKey = null; public String auth_Id = null; public String auth_Secret = null; public LongTtsDemo() { } public void shutDown() { logger.info("close NLS client"); client.close(); logger.info("demo done"); } public void start() { logger.info("init Nls client..."); client.init(); } public void sayIt(String tts_text,String fileName) throws Exception { int ttsTextLength = tts_text.length(); String[] longTexts; int i = 0; boolean isHead = false; //標識是否是第一個標頭檔案 String tts_part_text; File file = new File(fileName+".pcm"); if (!file.exists()) { try { file.createNewFile(); } catch (Exception e) { e.printStackTrace(); } } FileOutputStream outputStream = new FileOutputStream(file, true); longTexts = processLongText(tts_text); //處理文字,文字長度以50為限,擷取為多個檔案. while (ttsTextLength > 0) { tts_part_text = ""; if (ttsTextLength > 50) { if (i == 0) { isHead = true; } else { isHead = false; } for (; i < longTexts.length; i++) { tts_part_text = tts_part_text + longTexts[i]; if (i < longTexts.length - 1 && tts_part_text.length() + longTexts[i + 1].length() >= 50) { i = i + 1; break; } } } else { if (i == 0) { isHead = true; } for (; i < longTexts.length; i++) { tts_part_text = tts_part_text + longTexts[i]; } } NlsRequest req = new NlsRequest(); req.setApp_key("nls-service"); req.setTts_req(tts_part_text, "16000"); req.setTtsEncodeType("wav"); req.setTtsVoice("xiaoyun");//男聲:xiaogang req.setTtsVolume(50); req.setTtsBackgroundMusic(1, 0); req.authorize(auth_Id, auth_Secret); NlsFuture future = client.createNlsFuture(req, this); int total_len = 0; byte[] data; while ((data = future.read()) != null) { if (data.length == 8044 ) { // 去掉wav頭,同時將多條wav轉成一條pcm logger.debug("data length:{} , and head is:{}", (data.length - 44), isHead ? "true" : "false"); outputStream.write(data, 44, data.length - 44); } else { outputStream.write(data, 0, data.length); } total_len += data.length; } logger.info("tts audio file size is :" + total_len); future.await(10000); ttsTextLength = ttsTextLength - tts_part_text.length(); } outputStream.close(); //將pcm轉為wav,可以直接播放. 格式為:16kHz取樣率,16bit,單聲道 PcmToWav.copyWaveFile(fileName+".pcm",fileName+".wav"); logger.debug("close the wav file!"); } @Override public void onMessageReceived(NlsEvent e) { NlsResponse response = e.getResponse(); String result = ""; if (response.getDs_ret() != null) { result = "get ds result: " + response.getDs_ret(); } if (response.getAsr_ret() != null) { result += "\nget asr result: " + response.getAsr_ret(); } if (response.getTts_ret() != null) { result += "\nget tts result: " + response.getTts_ret(); } if (response.getGds_ret() != null) { result += "\nget gds result: " + response.getGds_ret(); } if (!result.isEmpty()) { logger.info(result); } else if (response.jsonResults != null) { logger.info(response.jsonResults.toString()); } else { logger.info("get an acknowledge package from server."); } } @Override public void onOperationFailed(NlsEvent e) { logger.error("Error message is: {}, Error code is: {}", e.getErrorMessage(), Integer.valueOf(e.getResponse().getStatus_code())); } //切分長文字 public static String[] processLongText(String text) { text = text.replaceAll("、", "、|"); text = text.replaceAll(",", ",|"); text = text.replaceAll("。", "。|"); text = text.replaceAll(";", ";|"); text = text.replaceAll("?", "?|"); text = text.replaceAll("!", "!|"); text = text.replaceAll(",", ",|"); text = text.replaceAll(";", ";|"); text = text.replaceAll("\\?", "?|"); text = text.replaceAll("!", "!|"); String[] texts = text.split("\\|"); return texts; } @Override public void onChannelClosed(NlsEvent e) { logger.info("on websocket closed."); } /** * @param args */ public static void main(String[] args) throws Exception { LongTtsDemo lun = new LongTtsDemo(); // if (args.length < 4) { // logger.info("NlsDemo <app-key> <Id> <Secret>"); // System.exit(-1); // } String fileName = UUID.randomUUID().toString(); String tts_text = "楊魯安先生捐贈大批個人藏品的義舉洞記遊圖卷 等,還有清代名家汪昉、王素、湯雨生、董婉貞、任薰、張熊、姜筠、吳昌碩、吳榖祥、王闓運及近代顏伯龍等人書畫扇面精品。民國時期書畫名家張謇、劉春霖、梁啟超、丁佛言、趙雲壑;當代王襄、吳玉如、潘主蘭、白銘、陶博吾的上乘之作。陶器、青銅器——這裡展示了仰韶渦紋雙耳彩陶罐;戰國到漢魏的一批瓦當;其中,西漢初期的“惟漢三年大並天下”瓦當為國內罕見。還有從商周到民國初年的一批銅器;春秋蟠螭紋六蛇圈足青銅簋,是晉國早期禮器。展出的還有漢族和少數民族各式帶鉤,戰國晚期各式匈奴帶鉤;鑄造精緻,花紋奇特。那柄馬首匈奴人帶鉤,露出匈奴人臉部真容,這為研究匈奴族和漢匈和親提供了重要材料。錢幣——先秦的貝幣、布幣、刀幣、環錢以及秦、漢、唐、宋各朝方孔圓錢。其中半兩與五銖錢都是成系列的,小直刀,戰國 楚)“郢爰”金版,西漢武帝四銖半兩金錢,新莽“六泉十布”及其錢範,北宋大觀通寶 行書 鐵母錢,均屬珍品。還陳列了遼、西夏、金、元各朝鑄錢。令人目不暇接,反映了中華錢幣文化的概貌。 印章——從古代璽印到近代篆刻家的作品百餘鈕,展示了我國傳統文化的一枝奇葩。西周“吳”字亞形印,為國內僅有;戰國官印“北路官”製造精美,文字奇逸;“晉率叟遷長”銀官印,西漢“姚禹”玉印,均屬珍品。 魯安作品——這裡展出的是楊老的書畫作品,書體有甲骨、金文、楷等,書風雄強,久為書法界所稱道。其畫作凝練、老辣,酣暢、靈動。 為了弘揚楊老留下的這批精神文化遺產,楊魯安藏珍館將長期陳列,並適時輪換陳列藏品,期望廣大觀眾熱情關注。地址:呼和浩特市回民區公園東路108號。電話 0471-6537871; 0471-6297893 ; 0471-6924915"; // String tts_text = "百草堂與三味書屋 魯迅 \n" + // "我家的後面有一個很大的園,相傳叫作百草園。現在是早已並屋子一起賣給朱文公的子孫了,連那最末次的相見也已經隔了七八年,其中似乎確鑿只有一些野草;但那時卻是我的樂園。\n" + // "不必說碧綠的菜畦,光滑的石井欄,高大的皂莢樹,紫紅的桑葚;也不必說鳴蟬在樹葉里長吟,肥胖的黃蜂伏在菜花上,輕捷的叫天子(雲雀)忽然從草間直竄向雲霄裡去了。\n"+ // "單是周圍的短短的泥牆根一帶,就有無限趣味。油蛉在這裡低唱,蟋蟀們在這裡彈琴。翻開斷磚來,有時會遇見蜈蚣;還有斑蝥,倘若用手指按住它的脊樑,便會啪的一聲,\n"+ // "從後竅噴出一陣煙霧。何首烏藤和木蓮藤纏絡著,木蓮有蓮房一般的果實,何首烏有臃腫的根。有人說,何首烏根是有像人形的,吃了便可以成仙,我於是常常拔它起來,牽連不斷地拔起來,\n" + // "也曾因此弄壞了泥牆,卻從來沒有見過有一塊根像人樣。如果不怕刺,還可以摘到覆盆子,像小珊瑚珠攢成的小球,又酸又甜,色味都比桑葚要好得遠。" ; lun.appKey = "nls-service"; lun.auth_Id = ""; lun.auth_Secret = ""; lun.start(); lun.sayIt(tts_text,fileName); lun.shutDown(); } }