使用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
FROM intersystemsdc/iris-community
USER root
ENV DEBIAN_FRONTEND noninteractive
# install libraries required to gTTS to process TTS
RUN apt-get -y update \
&& apt-get -y install apt-utils \
&& apt-get install -y build-essential unzip pkg-config wget \
&& apt-get install -y python3-pip
# use pip3 (the python zpm) to install gTTS dependencies
RUN pip3 install --upgrade pip setuptools wheel
RUN pip3 install --target /usr/irissys/mgr/python gTTS
USER root
WORKDIR /opt/irisbuild
RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisbuild
USER ${ISC_PACKAGE_MGRUSER}
WORKDIR /opt/irisbuild
COPY src src
COPY Installer.cls Installer.cls
COPY module.xml module.xml
COPY iris.script iris.script
USER ${ISC_PACKAGE_MGRUSER}
RUN iris start IRIS \
&& iris session IRIS < iris.script \
&& iris stop IRIS quietly
2. 用Python语言配置创建了一个ClassMethod,使用gTTS将文本转化为音频并记录在MP3文件中。:
Python method to generate audio from text
/// TTS engine
Class dc.tts.TTSEngine
{
/// Text to audio file
ClassMethod GenerateAudioFileFromText(sentence, language, domain) [ Language = python ]
{
from gtts import gTTS
import uuid
tts = gTTS(sentence, lang=str(language), tld=str(domain))
output = str(uuid.uuid1()) + '.mp3'
tts.save('/opt/irisbuild/' + output)
return output
}
}
3. 在ObjectScript中创建了一个REST API,将Python功能作为一个TTS微服务公开(非常Cool!)
TTS REST Service
Class dc.tts.TTSRESTApp Extends %CSP.REST
{
Parameter CHARSET = "utf-8";
Parameter CONVERTINPUTSTREAM = 1;
Parameter CONTENTTYPE = "application/json";
Parameter Version = "1.0.0";
Parameter HandleCorsRequest = 1;
{
<Routes>
<!-- Server Info -->
<Route Url="/" Method="GET" Call="GetInfo" Cors="true"/>
<!-- Swagger specs -->
<Route Url="/_spec" Method="GET" Call="SwaggerSpec" />
<!-- generate text from audio file -->
<Route Url="/texttoaudio" Method="POST" Call="GenerateAudioFromText" />
</Routes>
}
// Generate audio file from text
ClassMethod GenerateAudioFromText() As %Status
{
Set tSC = $$$OK
try {
// get the sentence to be processed
Set sentence = $ZCONVERT(%request.Content.Read(),"I","UTF8")
Set Language = %request.Get("lang")
Set Domain = %request.Get("domain")
Set Language = $GET(Language,0)
If Language = "" {
Set Language = "en"
}
Set Domain = $GET(Domain,0)
If Domain = "" {
Set Domain = "com"
}
//call embedded python classmethod to get mp3 audio file from text
Set output = ##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")="*"
Set stream=##class(%Stream.FileBinary).%New()
Set sc=stream.LinkToFile("/opt/irisbuild/"_output)
Do stream.OutputToDevice()
Set tSC=$$$OK
//returns error message to the user
} catch e {
Set tSC=e.AsStatus()
Set pOutput = tSC
}
Quit tSC
}
/// General information
ClassMethod GetInfo() As %Status
{
SET version = ..#Version
SET fmt=##class(%SYS.NLS.Format).%New("ptbw")
SET info = {
"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")="*"
Write info.%ToJSON()
Quit $$$OK
}
ClassMethod %ProcessResult(pStatus As %Status = {$$$OK}, pResult As %DynamicObject = "") As %Status [ Internal ]
{
#dim %response As %CSP.Response
SET tSC = $$$OK
IF $$$ISERR(pStatus) {
SET %response.Status = 500
SET tSC = ..StatusToJSON(pStatus, .tJSON)
IF $isobject(tJSON) {
SET pResult = tJSON
} ELSE {
SET pResult = { "errors": [ { "error": "Unknown error parsing status code" } ] }
}
}
ELSEIF pStatus=1 {
IF '$isobject(pResult){
SET pResult = {
}
}
}
ELSE {
SET %response.Status = pStatus
SET error = $PIECE(pStatus, " ", 2, *)
SET pResult = {
"error": (error)
}
}
IF pResult.%Extends("%Library.DynamicAbstractObject") {
WRITE pResult.%ToJSON()
}
ELSEIF pResult.%Extends("%JSON.Adaptor") {
DO pResult.%JSONExport()
}
ELSEIF pResult.%Extends("%Stream.Object") {
DO pResult.OutputToDevice()
}
QUIT tSC
}
ClassMethod SwaggerSpec() As %Status
{
Set tSC = ##class(%REST.API).GetWebRESTApplication($NAMESPACE, %request.Application, .swagger)
Do swagger.info.%Remove("x-ISC_Namespace")
Set swagger.basePath = "/iris-tts"
Set swagger.info.title = "TTS Service API"
Set swagger.info.version = "1.0"
Set swagger.host = "localhost:52773"
Return ..%ProcessResult($$$OK, swagger)
}
}
