使用IRIS 和Python gTTS 实现文本转化声音的REST服务
Hi 社区,
想象一下,使您的应用程序能够阅读文本?现在有了IRIS的新功能--嵌入式Python,这就成为可能。有了这个新功能,IRIS可以原生地运行任何开源或商业的Python库。gTTS(https://pypi.org/project/gTTS/)是一个免费的库,使用谷歌翻译服务将文本转换成音频。
怎么做
只要通过参数传递文本,gTTS就会返回一个将文本转换为音频的MP3文件。也就是说,你的应用程序可以播放任何文本的音频! 请看如何做到这一点。
1. 进入https://openexchange.intersystems.com/package/IRIS-Text2Audio,点击下载按钮。
2. 克隆/git pull repo到任何本地目录中
$ git clone https://github.com/yurimarx/iris-tts.git
3. 在这个目录中打开一个Docker终端,运行:
$ docker-compose build
4. 运行IRIS container:
$ docker-compose up -d
5. 到Postman (或其他类似的 REST 客户端) 来配置请求,如图所示:
- Method: POST
- URL: http://localhost:52773/iris-tts/texttoaudio
- Body: raw (try any text sentence)
6. 点击发送,就会收到一个播放器的回复,可以播放MP3文件,如上图
背后的代码
1. Docker文件安装IRIS与Python和gTTS库
Dockerfile
FROMintersystemsdc/iris-community
USERroot
ENVDEBIAN_FRONTENDnoninteractive
# install libraries required to gTTS to process TTS
RUNapt-get-yupdate\
&&apt-get-yinstallapt-utils\
&&apt-getinstall-ybuild-essentialunzippkg-configwget\
&&apt-getinstall-ypython3-pip
# use pip3 (the python zpm) to install gTTS dependencies
RUNpip3install--upgradepipsetuptoolswheel
RUNpip3install--target/usr/irissys/mgr/pythongTTS
USERroot
WORKDIR/opt/irisbuild
RUNchown${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP}/opt/irisbuild
USER${ISC_PACKAGE_MGRUSER}
WORKDIR/opt/irisbuild
COPY srcsrc
COPYInstaller.clsInstaller.cls
COPYmodule.xmlmodule.xml
COPYiris.scriptiris.script
USER${ISC_PACKAGE_MGRUSER}
RUNirisstartIRIS\
&&irissessionIRIS<iris.script\
&&irisstopIRISquietly
2. 用Python语言配置创建了一个ClassMethod,使用gTTS将文本转化为音频并记录在MP3文件中。:
Python method to generate audio from text
///TTS engine
Classdc.tts.TTSEngine
{
///Text to audio file
ClassMethodGenerateAudioFileFromText(sentence,language,domain)[Language=python]
{
fromgttsimportgTTS
importuuid
tts =gTTS(sentence,lang=str(language),tld=str(domain))
output =str(uuid.uuid1()) + '.mp3'
tts.save('/opt/irisbuild/' +output)
returnoutput
}
}
3. 在ObjectScript中创建了一个REST API,将Python功能作为一个TTS微服务公开(非常Cool!)
TTS REST Service
Classdc.tts.TTSRESTAppExtends%CSP.REST
{
ParameterCHARSET="utf-8";
ParameterCONVERTINPUTSTREAM=1;
ParameterCONTENTTYPE="application/json";
ParameterVersion="1.0.0";
ParameterHandleCorsRequest=1;
{
<Routes>
<!--ServerInfo-->
<RouteUrl="/"Method="GET"Call="GetInfo"Cors="true"/>
<!--Swaggerspecs-->
<RouteUrl="/_spec"Method="GET"Call="SwaggerSpec"/>
<!--generatetextfromaudiofile-->
<RouteUrl="/texttoaudio"Method="POST"Call="GenerateAudioFromText"/>
</Routes>
}
//Generate audio file from text
ClassMethodGenerateAudioFromText()As%Status
{
SettSC=$$$OK
try{
// get the sentence to be processed
Setsentence=$ZCONVERT(%request.Content.Read(),"I","UTF8")
SetLanguage=%request.Get("lang")
SetDomain=%request.Get("domain")
SetLanguage=$GET(Language,0)
IfLanguage=""{
SetLanguage="en"
}
SetDomain=$GET(Domain,0)
IfDomain=""{
SetDomain="com"
}
//call embedded python classmethod to get mp3 audio file from text
Setoutput=##class(dc.tts.TTSEngine).GenerateAudioFileFromText(sentence,Language,Domain)
Set%response.ContentType="audio/mp3"
Do%response.SetHeader("Content-Disposition","attachment;filename="""_output_"""")
Set%response.NoCharSetConvert=1
Set%response.Headers("Access-Control-Allow-Origin")="*"
Setstream=##class(%Stream.FileBinary).%New()
Setsc=stream.LinkToFile("/opt/irisbuild/"_output)
Dostream.OutputToDevice()
SettSC=$$$OK
//returns error message to the user
}catche{
SettSC=e.AsStatus()
SetpOutput=tSC
}
QuittSC
}
///General information
ClassMethodGetInfo()As%Status
{
SETversion=..#Version
SETfmt=##class(%SYS.NLS.Format).%New("ptbw")
SETinfo={
"Service":"TTS Service API",
"version":(version),
"Developer":"Yuri Gomes",
"Status":"Ok",
"Date":($ZDATETIME($HOROLOG))
}
Set%response.ContentType=..#CONTENTTYPEJSON
Set%response.Headers("Access-Control-Allow-Origin")="*"
Writeinfo.%ToJSON()
Quit$$$OK
}
ClassMethod%ProcessResult(pStatusAs%Status={$$$OK},pResultAs%DynamicObject="")As%Status[Internal]
{
#dim%responseAs%CSP.Response
SETtSC=$$$OK
IF$$$ISERR(pStatus){
SET%response.Status=500
SETtSC=..StatusToJSON(pStatus,.tJSON)
IF$isobject(tJSON){
SETpResult=tJSON
}ELSE{
SETpResult={"errors":[{"error":"Unknown error parsing status code"}]}
}
}
ELSEIFpStatus=1{
IF'$isobject(pResult){
SETpResult={
}
}
}
ELSE{
SET%response.Status=pStatus
SETerror=$PIECE(pStatus," ",2,*)
SETpResult={
"error":(error)
}
}
IFpResult.%Extends("%Library.DynamicAbstractObject"){
WRITEpResult.%ToJSON()
}
ELSEIFpResult.%Extends("%JSON.Adaptor"){
DOpResult.%JSONExport()
}
ELSEIFpResult.%Extends("%Stream.Object"){
DOpResult.OutputToDevice()
}
QUITtSC
}
ClassMethodSwaggerSpec()As%Status
{
SettSC=##class(%REST.API).GetWebRESTApplication($NAMESPACE,%request.Application,.swagger)
Doswagger.info.%Remove("x-ISC_Namespace")
Setswagger.basePath="/iris-tts"
Setswagger.info.title="TTS Service API"
Setswagger.info.version="1.0"
Setswagger.host="localhost:52773"
Return..%ProcessResult($$$OK,swagger)
}
}
