Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
DeepSpeech
提交
d4f863dc
D
DeepSpeech
项目概览
PaddlePaddle
/
DeepSpeech
大约 1 年 前同步成功
通知
206
Star
8425
Fork
1598
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
245
列表
看板
标记
里程碑
合并请求
3
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
DeepSpeech
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
245
Issue
245
列表
看板
标记
里程碑
合并请求
3
合并请求
3
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d4f863dc
编写于
5月 10, 2022
作者:
L
lym0302
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
improve, test=doc
上级
018dda6e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
161 addition
and
36 deletion
+161
-36
paddlespeech/server/bin/paddlespeech_client.py
paddlespeech/server/bin/paddlespeech_client.py
+51
-1
paddlespeech/server/bin/paddlespeech_server.py
paddlespeech/server/bin/paddlespeech_server.py
+7
-4
paddlespeech/server/utils/audio_handler.py
paddlespeech/server/utils/audio_handler.py
+23
-7
paddlespeech/server/utils/util.py
paddlespeech/server/utils/util.py
+20
-0
paddlespeech/server/ws/tts_api.py
paddlespeech/server/ws/tts_api.py
+60
-24
未找到文件。
paddlespeech/server/bin/paddlespeech_client.py
浏览文件 @
d4f863dc
...
...
@@ -18,6 +18,7 @@ import io
import
json
import
os
import
random
import
sys
import
time
from
typing
import
List
...
...
@@ -32,6 +33,7 @@ from paddlespeech.cli.log import logger
from
paddlespeech.server.utils.audio_handler
import
ASRWsAudioHandler
from
paddlespeech.server.utils.audio_process
import
wav2pcm
from
paddlespeech.server.utils.util
import
compute_delay
from
paddlespeech.server.utils.util
import
network_reachable
from
paddlespeech.server.utils.util
import
wav2base64
__all__
=
[
...
...
@@ -128,6 +130,7 @@ class TTSClientExecutor(BaseExecutor):
return
True
except
Exception
as
e
:
logger
.
error
(
"Failed to synthesized audio."
)
logger
.
error
(
e
)
return
False
@
stats_wrapper
...
...
@@ -154,6 +157,12 @@ class TTSClientExecutor(BaseExecutor):
"save_path"
:
output
}
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
res
=
requests
.
post
(
url
,
json
.
dumps
(
request
))
response_dict
=
res
.
json
()
if
output
is
not
None
:
...
...
@@ -236,6 +245,7 @@ class TTSOnlineClientExecutor(BaseExecutor):
return
True
except
Exception
as
e
:
logger
.
error
(
"Failed to synthesized audio."
)
logger
.
error
(
e
)
return
False
@
stats_wrapper
...
...
@@ -254,6 +264,12 @@ class TTSOnlineClientExecutor(BaseExecutor):
Python API to call an executor.
"""
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
if
protocol
==
"http"
:
logger
.
info
(
"tts http client start"
)
from
paddlespeech.server.utils.audio_handler
import
TTSHttpHandler
...
...
@@ -275,7 +291,7 @@ class TTSOnlineClientExecutor(BaseExecutor):
else
:
logger
.
error
(
"Please set correct protocol, http or websocket"
)
return
False
sys
.
exit
(
-
1
)
logger
.
info
(
f
"sentence:
{
input
}
"
)
logger
.
info
(
f
"duration:
{
duration
}
s"
)
...
...
@@ -399,6 +415,13 @@ class ASRClientExecutor(BaseExecutor):
# and paddlespeech_client asr only support http protocol
protocol
=
"http"
if
protocol
.
lower
()
==
"http"
:
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
from
paddlespeech.server.utils.audio_handler
import
ASRHttpHandler
logger
.
info
(
"asr http client start"
)
handler
=
ASRHttpHandler
(
server_ip
=
server_ip
,
port
=
port
)
...
...
@@ -503,6 +526,13 @@ class ASROnlineClientExecutor(BaseExecutor):
Returns:
str: the audio text
"""
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
logger
.
info
(
"asr websocket client start"
)
handler
=
ASRWsAudioHandler
(
server_ip
,
...
...
@@ -555,6 +585,7 @@ class CLSClientExecutor(BaseExecutor):
return
True
except
Exception
as
e
:
logger
.
error
(
"Failed to speech classification."
)
logger
.
error
(
e
)
return
False
@
stats_wrapper
...
...
@@ -567,6 +598,12 @@ class CLSClientExecutor(BaseExecutor):
Python API to call an executor.
"""
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
url
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
+
'/paddlespeech/cls'
audio
=
wav2base64
(
input
)
data
=
{
"audio"
:
audio
,
"topk"
:
topk
}
...
...
@@ -632,6 +669,12 @@ class TextClientExecutor(BaseExecutor):
str: the punctuation text
"""
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
url
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
+
'/paddlespeech/text'
request
=
{
"text"
:
input
,
...
...
@@ -728,6 +771,13 @@ class VectorClientExecutor(BaseExecutor):
Returns:
str: the audio embedding or score between enroll and test audio
"""
# Check if the network is reachable
network
=
'http://'
+
server_ip
+
":"
+
str
(
port
)
if
network_reachable
(
network
)
is
not
True
:
logger
.
error
(
f
"
{
network
}
unreachable, please check the ip address."
)
sys
.
exit
(
-
1
)
if
task
==
"spk"
:
from
paddlespeech.server.utils.audio_handler
import
VectorHttpHandler
logger
.
info
(
"vector http client start"
)
...
...
paddlespeech/server/bin/paddlespeech_server.py
浏览文件 @
d4f863dc
...
...
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import
argparse
import
sys
from
typing
import
List
import
uvicorn
...
...
@@ -79,10 +80,12 @@ class ServerExecutor(BaseExecutor):
def
execute
(
self
,
argv
:
List
[
str
])
->
bool
:
args
=
self
.
parser
.
parse_args
(
argv
)
config
=
get_config
(
args
.
config_file
)
if
self
.
init
(
config
):
uvicorn
.
run
(
app
,
host
=
config
.
host
,
port
=
config
.
port
,
debug
=
True
)
try
:
self
(
args
.
config_file
,
args
.
log_file
)
except
Exception
as
e
:
logger
.
error
(
"Failed to start server."
)
logger
.
error
(
e
)
sys
.
exit
(
-
1
)
@
stats_wrapper
def
__call__
(
self
,
...
...
paddlespeech/server/utils/audio_handler.py
浏览文件 @
d4f863dc
...
...
@@ -304,18 +304,24 @@ class TTSWsHandler:
receive_time_list
=
[]
chunk_duration_list
=
[]
# 1. Send websocket handshake
protocal
# 1. Send websocket handshake
request
async
with
websockets
.
connect
(
self
.
url
)
as
ws
:
# 2. Server has already received handshake protocal
# send text to engine
# 2. Server has already received handshake response, send start request
start_request
=
json
.
dumps
({
"task"
:
"tts"
,
"signal"
:
"start"
})
await
ws
.
send
(
start_request
)
msg
=
await
ws
.
recv
()
logger
.
info
(
f
"client receive msg=
{
msg
}
"
)
msg
=
json
.
loads
(
msg
)
session
=
msg
[
"session"
]
# 3. send speech synthesis request
text_base64
=
str
(
base64
.
b64encode
((
text
).
encode
(
'utf-8'
)),
"UTF8"
)
d
=
{
"text"
:
text_base64
}
d
=
json
.
dumps
(
d
)
request
=
json
.
dumps
({
"text"
:
text_base64
})
st
=
time
.
time
()
await
ws
.
send
(
d
)
await
ws
.
send
(
request
)
logging
.
info
(
"send a message to the server"
)
#
3.
Process the received response
# Process the received response
message
=
await
ws
.
recv
()
first_response
=
time
.
time
()
-
st
message
=
json
.
loads
(
message
)
...
...
@@ -348,6 +354,15 @@ class TTSWsHandler:
save_audio_success
=
save_audio
(
all_bytes
,
output
)
else
:
save_audio_success
=
False
# 5. send end request
end_request
=
json
.
dumps
({
"task"
:
"tts"
,
"signal"
:
"end"
,
"session"
:
session
})
await
ws
.
send
(
end_request
)
else
:
logger
.
error
(
"infer error"
)
...
...
@@ -458,6 +473,7 @@ class TTSHttpHandler:
final_response
=
time
.
time
()
-
st
duration
=
len
(
all_bytes
)
/
2.0
/
24000
html
.
close
()
# when stream=True
if
output
is
not
None
:
save_audio_success
=
save_audio
(
all_bytes
,
output
)
...
...
paddlespeech/server/utils/util.py
浏览文件 @
d4f863dc
...
...
@@ -13,6 +13,8 @@
import
base64
import
math
import
requests
def
wav2base64
(
wav_file
:
str
):
"""
...
...
@@ -146,3 +148,21 @@ def count_engine(logfile: str="./nohup.out"):
print
(
f
"max final response:
{
max
(
final_response_list
)
}
s, min final response:
{
min
(
final_response_list
)
}
s"
)
def
network_reachable
(
url
:
str
,
timeout
:
int
=
5
)
->
bool
:
"""Check if the network is reachable
Args:
url (str): http://server_ip:port or ws://server_ip:port
timeout (int, optional): timeout. Defaults to 5.
Returns:
bool: Whether the network is reachable.
"""
try
:
request
=
requests
.
get
(
url
,
timeout
=
timeout
)
return
True
except
(
requests
.
ConnectionError
,
requests
.
Timeout
)
as
exception
:
print
(
exception
)
return
False
paddlespeech/server/ws/tts_api.py
浏览文件 @
d4f863dc
...
...
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import
json
import
uuid
from
fastapi
import
APIRouter
from
fastapi
import
WebSocket
...
...
@@ -26,36 +27,71 @@ router = APIRouter()
@
router
.
websocket
(
'/paddlespeech/tts/streaming'
)
async
def
websocket_endpoint
(
websocket
:
WebSocket
):
"""PaddleSpeech Online TTS Server api
Args:
websocket (WebSocket): the websocket instance
"""
#1. the interface wait to accept the websocket protocal header
# and only we receive the header, it establish the connection with specific thread
await
websocket
.
accept
()
#2. if we accept the websocket headers, we will get the online tts engine instance
engine_pool
=
get_engine_pool
()
tts_engine
=
engine_pool
[
'tts'
]
try
:
# careful here, changed the source code from starlette.websockets
assert
websocket
.
application_state
==
WebSocketState
.
CONNECTED
message
=
await
websocket
.
receive
()
websocket
.
_raise_on_disconnect
(
message
)
while
True
:
# careful here, changed the source code from starlette.websockets
assert
websocket
.
application_state
==
WebSocketState
.
CONNECTED
message
=
await
websocket
.
receive
()
websocket
.
_raise_on_disconnect
(
message
)
message
=
json
.
loads
(
message
[
"text"
])
# get engine
engine_pool
=
get_engine_pool
()
tts_engine
=
engine_pool
[
'tts'
]
if
'signal'
in
message
:
# start request
if
message
[
'signal'
]
==
'start'
:
session
=
uuid
.
uuid1
().
hex
resp
=
{
"status"
:
0
,
"signal"
:
"server ready"
,
"session"
:
session
}
await
websocket
.
send_json
(
resp
)
# 获取 message 并转文本
message
=
json
.
loads
(
message
[
"text"
])
text_bese64
=
message
[
"text"
]
sentence
=
tts_engine
.
preprocess
(
text_bese64
=
text_bese64
)
# end request
elif
message
[
'signal'
]
==
'end'
:
resp
=
{
"status"
:
0
,
"signal"
:
"connection will be closed"
,
"session"
:
session
}
await
websocket
.
send_json
(
resp
)
# run
wav_generator
=
tts_engine
.
run
(
sentence
)
# speech synthesis request
elif
'text'
in
message
:
text_bese64
=
message
[
"text"
]
sentence
=
tts_engine
.
preprocess
(
text_bese64
=
text_bese64
)
while
True
:
try
:
tts_results
=
next
(
wav_generator
)
resp
=
{
"status"
:
1
,
"audio"
:
tts_results
}
await
websocket
.
send_json
(
resp
)
except
StopIteration
as
e
:
resp
=
{
"status"
:
2
,
"audio"
:
''
}
await
websocket
.
send_json
(
resp
)
logger
.
info
(
"Complete the transmission of audio streams"
)
break
# run
wav_generator
=
tts_engine
.
run
(
sentence
)
while
True
:
try
:
tts_results
=
next
(
wav_generator
)
resp
=
{
"status"
:
1
,
"audio"
:
tts_results
}
await
websocket
.
send_json
(
resp
)
except
StopIteration
as
e
:
resp
=
{
"status"
:
2
,
"audio"
:
''
}
await
websocket
.
send_json
(
resp
)
logger
.
info
(
"Complete the transmission of audio streams"
)
break
else
:
logger
.
error
(
"Invalid request, please check if the request is correct."
)
except
WebSocketDisconnect
:
pass
\ No newline at end of file
pass
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录