林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
摘要:Text to Speech 服务提供的应用程序编程接口 (API) 使用 IBM 的语音合成功能将文本转换成音频信号。此服务提供了具象状态传输 (REST) 接口,支持将各种语言、口音和语音的文本合成自然语音。此服务目前可将英语或西班牙语的书面文本合成男声(英语和西班牙语)或女声(仅限英语)朗读的音频信号。音频可通过流式方法传输回客户机,延迟时间最短。
本文工程下载:http://download.csdn.net/detail/evankaka/9427964
本文实例访问:http://texttospeechtest.eu-gb.mybluemix.net/
BluxMix账号注册:https://apps.admin.ibmcloud.com/manage/trial/bluemix.html?cm_mmc=CMDeveloperGCG-_-Bluemix-_-CSDN-_-onlineeventQ2
1、创建Bluemix上的web工程.(如何创建工程可看基于IBM Bluemix部署Java Web项目实战演练)
2、添加文本转语音服务
添加服务
3、最后绑定的服务的工程如下:
这里需要创建一个dynamic 的web工程,本文是直接在https://github.com/watson-developer-cloud/text-to-speech-java这上工程的基础上来做修改的。
最终目录如下:
下面来分析一下关键的代码,这里是以Servlet来实现语音的获取的
(1)DemoServlet.java
这是本工程的核心代码
package com.ibm.cloudoe.samples; import java.io.IOException; import java.net.URI; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpStatus; import org.apache.http.client.fluent.Executor; import org.apache.http.client.fluent.Request; import org.apache.http.client.fluent.Response; import com.ibm.ws.xs.json.java.JSONArray; import com.ibm.ws.xs.json.java.JSONObject; @MultipartConfig public class DemoServlet extends HttpServlet { private static Logger logger = Logger.getLogger(DemoServlet.class.getName()); private static final long serialVersionUID = 1L; private String serviceName = "text_to_speech"; // 此处需要修改成您自己的 private String baseURL = "https://stream.watsonplatform.net/text-to-speech/api"; private String username = "bd546fff-2e43-42c9-8c76-71075c257128"; private String password = "AL7sK4TRu0T0"; /** * 处理前台传过来的请求 */ @Override protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { if (req.getParameter("text") == null || req.getParameter("voice") == null) { //如果文本或语音为空,返回到初始界面 req.getRequestDispatcher("/index.jsp").forward(req, resp); } else { boolean download = false; if (req.getParameter("download") != null && req.getParameter("download").equalsIgnoreCase("true")) { //判断是否下载语音 download = true; } req.setCharacterEncoding("UTF-8"); try { String queryStr = req.getQueryString(); String url = baseURL + "/v1/synthesize"; if (queryStr != null) { url += "?" + queryStr;//连接url } URI uri = new URI(url).normalize(); Request newReq = Request.Get(uri); //构造请求头 newReq.addHeader("Accept", "audio/ogg; codecs=opus"); //设置语音格式,还可以为"audio/wav"或者 "audio/flac" Executor executor = Executor.newInstance().auth(username, password); Response response = executor.execute(newReq);//发送请求报文,并取得返回 if (download) { resp.setHeader("content-disposition", "attachment; filename=transcript.ogg");//下载语音 } ServletOutputStream servletOutputStream = resp.getOutputStream(); response.returnResponse().getEntity() .writeTo(servletOutputStream);//将语音流返回前台 servletOutputStream.flush(); servletOutputStream.close(); } catch (Exception e) { // Log something and return an error message logger.log(Level.SEVERE, "got error: " + e.getMessage(), e); resp.setStatus(HttpStatus.SC_BAD_GATEWAY); } } } /** * 取得环境变量 */ private JSONObject getVcapServices() { String envServices = System.getenv("VCAP_SERVICES"); if (envServices == null) return null; JSONObject sysEnv = null; try { sysEnv = JSONObject.parse(envServices); } catch (IOException e) { // Do nothing, fall through to defaults logger.log(Level.SEVERE, "Error parsing VCAP_SERVICES: "+e.getMessage(), e); } return sysEnv; } @Override public void init() throws ServletException { super.init(); processVCAP_Services(); } /** * 取得环境变量的参数 */ private void processVCAP_Services() { logger.info("Processing VCAP_SERVICES"); JSONObject sysEnv = getVcapServices(); if (sysEnv == null) return; logger.info("Looking for: "+ serviceName ); for (Object key : sysEnv.keySet()) { String keyString = (String) key; logger.info("found key: " + key); if (keyString.startsWith(serviceName)) { JSONArray services = (JSONArray)sysEnv.get(key); JSONObject service = (JSONObject)services.get(0); JSONObject credentials = (JSONObject)service.get("credentials"); baseURL = (String)credentials.get("url"); username = (String)credentials.get("username"); password = (String)credentials.get("password"); logger.info("baseURL = "+baseURL); logger.info("username = "+username); logger.info("password = "+password); } else { logger.info("Doesn't match /^"+serviceName+"/"); } } } }
(2)前台关键代码
这是页面的内容:
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html lang="en"> <head> <title>文本转语音实例</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon"> <link rel="icon" href="images/favicon.ico" type="image/x-icon"> <link rel="stylesheet" href="css/watson-bootstrap-dark.css"> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-lg-7 col-md-7 col-xs-12"> <h2>文本转语音</h2> <div class="well"> <form method="get" class="form-horizontal"> <fieldset> <div class="row"> <div class="col-lg-12 col-xs-12"> <label for="textArea" class="control-label">请输入或复制要转换成语音的文本:</label> <textarea id="textArea" name="text" rows="8" required class="form-control"></textarea><span class="help-block"><small>注意只能输入现一种语言,语音返回会有点慢,请耐心等待</small></span> </div> </div> <div style="margin-bottom:30px;" class="row"> <label for="voice" class="col-lg-12 col-xs-12 control-label">请选择语音类型:</label> <div class="col-lg-12 col-xs-12"> <select class="select-voice" id="voice" style="width:100%" name="voice" required class="form-control"> </select> </div> </div> <div class="row"> <div class="col-lg-4 col-xs-4 download-container"> <input value="Download" class="btn btn-block download-button"> </div> <div class="col-lg-4 col-xs-4 text-center"></div> <div class="col-lg-4 col-xs-4 ie-speak"> <input value="Speak" class="btn btn-block speak-button"> <div class="arrow-box"> <p>请使用谷歌或火狐浏览器</p> </div> </div> </div> </fieldset> </form> </div> </div> <div class="col-lg-5 col-md-5 col-xs-12"> <h2>语音输出</h2> <div class="row"> <div class="col-lg-12 col-xs-12"> <div style="display:none" class="well result"> <div class="text-center"> <audio autoplay preload="auto" autobuffer controls class="audio"></audio> </div> <div><span class="help-block">返回的语音是以<a href="http://www.vorbis.com/">Ogg Vorbis</a> 格式的,它可以使用<a href="http://www.videolan.org/vlc/index.html">VLC</a>, <a href="http://audacity.sourceforge.net/">Audacity</a> 等来播放</span> </div> </div> <div style="display:none" class="well error"> <div class="form-group row"> <div class="col-lg-12 col-xs-12"> <p class="errorMsg">处理请求失败</p> </div> </div> </div> </div> </div> </div> </div> <div class="row"> <div class="help-block text-center"><small>请使用谷歌浏览器 <a href="https://www.google.com/intl/en/chrome/browser/desktop/" target="_blank">Chrome </a>火狐浏览器 <a href="https://www.mozilla.org/en-US/firefox/new/" target="_blank">Firefox.</a></small> </div> </div> </div> <script type="text/javascript" src="js/browser-detect.js"></script> <script type="text/javascript" src="js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="js/constants.js"></script> <script type="text/javascript" src="js/demo.js"></script> </body> </html>demo.js,引用的js文件内容:
'use strict'; //页面一加载完成就执行 $(function () { var audio = $('.audio').get(0),//语音播放器 textArea = $('#textArea'); //文本内容 //为语音选择器添加内容 Object.keys(VOICES).forEach(function(key) { $('<option>', { value : key }) .appendTo($('.select-voice')) .text(VOICES[key]); }); //设置初始文本内容 function updateSampleText() { var lang = $('.select-voice').val().substr(0,5); $('#textArea').text(SAMPLE_TEXT[lang]); } $('.select-voice').change(updateSampleText); updateSampleText(); // IE 和 Safari 不支持此实例语音播放,让speak按钮 无效 if ($('body').hasClass('ie') || $('body').hasClass('safari')) { $('.speak-button').prop('disabled', true); } if ($('.speak-button').prop('disabled')) { $('.ie-speak .arrow-box').show(); } //播放错误信息 $('.audio').on('error', function () { $('.result').hide(); $('.errorMgs').text('Error processing the request.'); $('.errorMsg').css('color','red'); $('.error').show(); }); //播放语音 $('.audio').on('loadeddata', function () { $('.result').show(); $('.error').hide(); }); //download点击事件 $('.download-button').click(function() { textArea.focus(); if (validText(textArea.val())) { window.location.href = '?download=true&' + $('form').serialize(); } }); //speak按钮点击事件 $('.speak-button').click(function() { $('.result').hide(); audio.pause(); $('#textArea').focus(); if (validText(textArea.val())) { audio.setAttribute('src','?&' + $('form').serialize()); } }); //校验文本的输入内容 function validText(text) { $('.error').hide(); $('.errorMsg').css('color','#5a5a5a'); if ($.trim(text).length === 0) { $('.errorMsg').text('Please enter the text you would like to synthesize in the text window.'); $('.errorMsg').css('color','#5a5a5a'); $('.error').show(); return false; } if (!containsAllLatin1(text)) { $('.errorMsg').text('Language not supported. Please use only ISO 8859 characters'); $('.error').show(); return false; } return true; } /** * Check that the text doesn't contains non latin-1 characters. * @param String The string to test * @return true if the string is latin-1 */ function containsAllLatin1(str) { return /^[A-z\u00C0-\u00ff\s?@¿''\.,-\/#!$%\^&\*;:{}=\-_`~()0-9]+$/.test(str); } });
(3)添加jar包
本地运行需要添加如下jar包,记得!
其中json-org.jar和ogclient.jar可到这里下载ftp://public.dhe.ibm.com/cloud/bluemix/datacache/
同时工程右键设置属性中,编辑的JDK选择1.6,web版本选择2.5
(4)本地发布运行
右键运行即可,
输入http://localhost:8088/app/
测试过后没有问题。下一步发布到个人bluemix中心。
(1)打包war包
因为本工程使用了ant.其实内容如下:
build.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE xml> <project basedir="." default="build" name="WebApp"> <property environment="env" /> <property name="srcDir" value="." /> <property name="debuglevel" value="source,lines,vars" /> <property name="target" value="1.6" /> <property name="source" value="1.6" /> <property name="ARCHIVE_DIR" value="output" /> <property name="LIB_DIR" value="./lib" /> <property name="WEB_INF_LIB_DIR" value="./WebContent/WEB-INF/lib" /> <property name="warname" value="webApp.war" /> <path id="classpathDir"> <pathelement location="build/bin" /> <fileset dir="${LIB_DIR}"> <include name="*.jar" /> </fileset> <fileset dir="${WEB_INF_LIB_DIR}"> <include name="*.jar" /> </fileset> </path> <target name="init"> <mkdir dir="build" /> <mkdir dir="build/bin" /> </target> <target name="clean"> <delete dir="build" /> <delete file="${ARCHIVE_DIR}/${warname}" /> </target> <target name="build" depends="build-project,build-war" /> <target name="cleanall" depends="clean" /> <target name="build-project" depends="clean,init"> <copy todir="${ARCHIVE_DIR}"> <fileset file="manifest.yml" /> </copy> <echo message="${ant.project.name}: ${ant.file}" /> <javac debug="true" debuglevel="${debuglevel}" destdir="build/bin" source="${source}" target="${target}" includeantruntime="false"> <src path="src" /> <classpath refid="classpathDir" /> </javac> </target> <target name="build-war" depends="build-project"> <war destfile="${ARCHIVE_DIR}/${warname}" webxml="WebContent/WEB-INF/web.xml"> <webinf dir="WebContent/WEB-INF" /> <zipfileset dir="src" prefix="WEB-INF/src" /> <fileset dir="WebContent"> <include name="**/*" /> </fileset> <lib dir="WebContent/WEB-INF/lib" /> <classes dir="build/bin" /> </war> </target> </project>另外,要发布到bluemix中去,本工程还配置了初始的参数
---
declared-services:
text-to-speech-service:
label: text_to_speech
plan: standard
applications:
- services:
- text-to-speech-service
name: TextToSpeechTest #改成你的Bluxmix中心上对应的web工程名
path: webApp.war #改成你的war包名,上传时这个注释要去掉
memory: 512M
打包后的输出路径:
(2)上传到个个Bluxmix中心
登陆
cf login 输入用户名、邮箱、选择工程空间(记得选择你此次web项目所在的空间)
上传
cf push TextToSpeechTest -p D:\marJee-workspace\text-to-speech-java-master\output\webApp.war -m 512M
最后,打开网址:http://texttospeechtest.eu-gb.mybluemix.net/
点击Speak按钮,即可!注意,等待语音返回比较慢,请耐心等待!注意,等待语音返回比较慢,请耐心等待!注意,等待语音返回比较慢,请耐心等待!
本文工程下载:http://download.csdn.net/detail/evankaka/9427964