New TTS webpanel plugins
This commit is contained in:
parent
205903bc40
commit
076d766745
13 changed files with 143 additions and 394 deletions
|
@ -0,0 +1 @@
|
||||||
|
../tts/index.scss
|
|
@ -0,0 +1,32 @@
|
||||||
|
@import 'common/vars';
|
||||||
|
|
||||||
|
.tts-container {
|
||||||
|
max-width: 80rem;
|
||||||
|
min-height: 10rem;
|
||||||
|
margin: 3rem auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: $default-border-2;
|
||||||
|
border-radius: 3rem;
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 0;
|
||||||
|
width: 90%;
|
||||||
|
|
||||||
|
input[type=text] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, button {
|
||||||
|
&:hover {
|
||||||
|
border-color: $default-hover-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
26
platypush/backend/http/static/js/plugins/tts.google/index.js
Normal file
26
platypush/backend/http/static/js/plugins/tts.google/index.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Vue.component('tts-google', {
|
||||||
|
template: '#tmpl-tts-google',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
talking: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
talk: async function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const args = [...event.target.querySelectorAll('input')].reduce((obj, el) => {
|
||||||
|
if (el.value.length)
|
||||||
|
obj[el.name] = el.value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this.talking = true;
|
||||||
|
await request('tts.google.say', args);
|
||||||
|
this.talking = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
25
platypush/backend/http/static/js/plugins/tts/index.js
Normal file
25
platypush/backend/http/static/js/plugins/tts/index.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
Vue.component('tts', {
|
||||||
|
template: '#tmpl-tts',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
talking: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
talk: async function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const args = [...event.target.querySelectorAll('input')].reduce((obj, el) => {
|
||||||
|
if (el.value.length)
|
||||||
|
obj[el.name] = el.value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this.talking = true;
|
||||||
|
await request('tts.say', args);
|
||||||
|
this.talking = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -1,181 +0,0 @@
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='js/music.mpd.js') }}"></script>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/music.mpd.css') }}"></script>
|
|
||||||
|
|
||||||
<div id="music-search-modal" class="modal">
|
|
||||||
<div class="modal-container">
|
|
||||||
<div class="modal-header">
|
|
||||||
Search For Music
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-body">
|
|
||||||
<form id="music-search-form" action="#">
|
|
||||||
<div class="row form-row">
|
|
||||||
<div class="two columns">
|
|
||||||
<label for="music-search-any">Any</label>
|
|
||||||
</div>
|
|
||||||
<div class="ten columns">
|
|
||||||
<input type="text" name="any">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row form-row">
|
|
||||||
<div class="two columns">
|
|
||||||
<label for="music-search-artist">Artist</label>
|
|
||||||
</div>
|
|
||||||
<div class="ten columns">
|
|
||||||
<input type="text" name="artist">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row form-row">
|
|
||||||
<div class="two columns">
|
|
||||||
<label for="music-search-title">Title</label>
|
|
||||||
</div>
|
|
||||||
<div class="ten columns">
|
|
||||||
<input type="text" name="title">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row form-row">
|
|
||||||
<div class="two columns">
|
|
||||||
<label for="music-search-album">Album</label>
|
|
||||||
</div>
|
|
||||||
<div class="ten columns">
|
|
||||||
<input type="text" name="album">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row music-form-bottom">
|
|
||||||
<div class="six columns offset-by-six do-search-btns">
|
|
||||||
<input type="button" class="btn-default" data-dismiss-modal="#music-search-modal"
|
|
||||||
value="Close">
|
|
||||||
<input type="submit" class="btn-primary" value="Search">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form class="row" id="music-search-results-form">
|
|
||||||
<div class="six columns">
|
|
||||||
<button class="btn-default" id="music-results-add" disabled="disabled">
|
|
||||||
<i class="fa fa-plus"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn-default" id="music-results-play" disabled="disabled">
|
|
||||||
<i class="fa fa-play"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns right-side">
|
|
||||||
<input type="button" class="btn-default"
|
|
||||||
data-dismiss-modal="#music-search-modal" value="Close">
|
|
||||||
<input type="button" class="btn-primary"
|
|
||||||
id="music-search-reset" value="Reset">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="music-search-results-container" class="row">
|
|
||||||
<div id="music-search-results-head" class="row">
|
|
||||||
<div class="three columns">Artist</div>
|
|
||||||
<div class="four columns">Title</div>
|
|
||||||
<div class="four columns">Album</div>
|
|
||||||
<div class="one column">Time</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="music-search-results" class="row"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row track-info">
|
|
||||||
<span class="no-track">No media is being played</span>
|
|
||||||
<span class="artist"></span>
|
|
||||||
<span class="track"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="playback-controls">
|
|
||||||
<div class="row">
|
|
||||||
<div class="eight columns offset-by-two slider-container" id="track-seeker-container">
|
|
||||||
<span class="seek-time" id="seek-time-elapsed">-:--</span>
|
|
||||||
<input type="range" min="0" id="track-seeker" disabled="disabled" class="slider" style="width:75%">
|
|
||||||
<span class="seek-time" id="seek-time-length">-:--</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="ten columns offset-by-one">
|
|
||||||
<button data-action="previous">
|
|
||||||
<i class="fa fa-step-backward"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="repeat">
|
|
||||||
<i class="fa fa-repeat"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="play">
|
|
||||||
<i class="fa fa-play"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="pause">
|
|
||||||
<i class="fa fa-pause"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="stop">
|
|
||||||
<i class="fa fa-stop"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="random">
|
|
||||||
<i class="fa fa-random"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button data-action="next">
|
|
||||||
<i class="fa fa-step-forward"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="eight columns offset-by-two slider-container" id="volume-ctrl-container">
|
|
||||||
<i class="fa fa-volume-down"></i>
|
|
||||||
<input type="range" min="0" max="100" id="volume-ctrl" class="slider" style="width:80%">
|
|
||||||
<i class="fa fa-volume-up"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div id="player-left-side" class="three columns music-pane">
|
|
||||||
<div class="row">
|
|
||||||
<div id="browser-controls">
|
|
||||||
<button data-action="add">
|
|
||||||
<i class="fa fa-plus"></i>
|
|
||||||
</button>
|
|
||||||
<button data-action="search" data-modal="#music-search-modal">
|
|
||||||
<i class="fa fa-search"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="browser-filter-container">
|
|
||||||
<input type="text" id="browser-filter" placeholder="Filter">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="music-browser" class="music-pane"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="player-right-side" class="nine columns music-pane">
|
|
||||||
<div class="row">
|
|
||||||
<div id="playlist-controls">
|
|
||||||
<button data-action="clear">
|
|
||||||
<i class="fa fa-eraser"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="playlist-filter-container">
|
|
||||||
<input type="text" id="playlist-filter" placeholder="Filter">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="playlist-content"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,161 +0,0 @@
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='js/music.snapcast.js') }}"></script>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/music.snapcast.css') }}"></script>
|
|
||||||
|
|
||||||
<div id="snapcast-host-modal" class="modal snapcast-modal">
|
|
||||||
<div class="modal-container">
|
|
||||||
<div class="modal-header"></div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form id="snapcast-host-form" class="snapcast-form" action="#">
|
|
||||||
<div class="row snapcast-host-info">
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">IP Address</div>
|
|
||||||
<div class="nine columns info-value" data-bind="ip"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">MAC Address</div>
|
|
||||||
<div class="nine columns info-value" data-bind="mac"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Name</div>
|
|
||||||
<div class="nine columns info-value" data-bind="name"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">OS</div>
|
|
||||||
<div class="nine columns info-value" data-bind="os"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Architecture</div>
|
|
||||||
<div class="nine columns info-value" data-bind="arch"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Server Name</div>
|
|
||||||
<div class="nine columns info-value" data-bind="serverName"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Server Version</div>
|
|
||||||
<div class="nine columns info-value" data-bind="serverVersion"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Protocol Version</div>
|
|
||||||
<div class="nine columns info-value" data-bind="protocolVersion"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Control Protocol Version</div>
|
|
||||||
<div class="nine columns info-value" data-bind="controlProtocolVersion"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row snapcast-form-bottom">
|
|
||||||
<div class="six columns offset-by-six forms-btns">
|
|
||||||
<input type="button" class="btn-default" data-dismiss-modal="#snapcast-host-modal"
|
|
||||||
value="Close">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="snapcast-group-modal" class="modal snapcast-modal">
|
|
||||||
<div class="modal-container">
|
|
||||||
<div class="modal-header"></div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form id="snapcast-group-form" class="snapcast-form" action="#">
|
|
||||||
<div class="row snapcast-group-clients-container">
|
|
||||||
<div class="row snapcast-group-clients"></div>
|
|
||||||
</div>
|
|
||||||
<div class="row snapcast-group-stream">
|
|
||||||
<select name="stream"></select>
|
|
||||||
<label for="stream">Stream</label>
|
|
||||||
</div>
|
|
||||||
<div class="row snapcast-form-bottom">
|
|
||||||
<div class="six columns offset-by-six forms-btns">
|
|
||||||
<input type="button" class="btn-default" data-dismiss-modal="#snapcast-group-modal"
|
|
||||||
value="Close">
|
|
||||||
<input type="submit" class="btn-primary" value="Save">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="snapcast-client-modal" class="modal snapcast-modal">
|
|
||||||
<div class="modal-container">
|
|
||||||
<div class="modal-header"></div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form id="snapcast-client-form" class="snapcast-form" action="#">
|
|
||||||
<div class="row form-row">
|
|
||||||
<div class="two columns">
|
|
||||||
<label for="name">Name</label>
|
|
||||||
</div>
|
|
||||||
<div class="ten columns">
|
|
||||||
<input type="text" name="name">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row snapcast-client-info">
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">IP Address</div>
|
|
||||||
<div class="nine columns info-value" data-bind="ip"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">MAC Address</div>
|
|
||||||
<div class="nine columns info-value" data-bind="mac"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">OS</div>
|
|
||||||
<div class="nine columns info-value" data-bind="os"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Architecture</div>
|
|
||||||
<div class="nine columns info-value" data-bind="arch"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Client Name</div>
|
|
||||||
<div class="nine columns info-value" data-bind="clientName"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Client Version</div>
|
|
||||||
<div class="nine columns info-value" data-bind="clientVersion"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="three columns info-name">Protocol Version</div>
|
|
||||||
<div class="nine columns info-value" data-bind="protocolVersion"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row snapcast-client-delete">
|
|
||||||
<input type="checkbox" name="delete">
|
|
||||||
<label for="delete">Delete client</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row snapcast-form-bottom">
|
|
||||||
<div class="six columns offset-by-six forms-btns">
|
|
||||||
<input type="button" class="btn-default" data-dismiss-modal="#snapcast-client-modal"
|
|
||||||
value="Close">
|
|
||||||
<input type="submit" class="btn-primary" value="Save">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="snapcast-container" class="row">
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='js/tts.google.js') }}"></script>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/tts.css') }}"></script>
|
|
||||||
|
|
||||||
<div class="row" id="tts-container">
|
|
||||||
<form action="#" id="tts-form">
|
|
||||||
<div class="eight columns">
|
|
||||||
<input type="text" name="text" placeholder="Text to say">
|
|
||||||
</div>
|
|
||||||
<div class="two columns">
|
|
||||||
<input type="text" name="language" placeholder="Language code">
|
|
||||||
</div>
|
|
||||||
<div class="one column">
|
|
||||||
<button type="submit">
|
|
||||||
<i class="fa fa-volume-up"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<script type="text/x-template" id="tmpl-tts-google">
|
||||||
|
{% include 'plugins/tts/common.html' %}
|
||||||
|
</script>
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='js/tts.js') }}"></script>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/tts.css') }}"></script>
|
|
||||||
|
|
||||||
<div class="row" id="tts-container">
|
|
||||||
<form action="#" id="tts-form">
|
|
||||||
<div class="eight columns">
|
|
||||||
<input type="text" name="phrase" placeholder="Text to say">
|
|
||||||
</div>
|
|
||||||
<div class="two columns">
|
|
||||||
<input type="text" name="lang" placeholder="Lang code">
|
|
||||||
</div>
|
|
||||||
<div class="one column">
|
|
||||||
<button type="submit">
|
|
||||||
<i class="fa fa-volume-up"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
15
platypush/backend/http/templates/plugins/tts/common.html
Normal file
15
platypush/backend/http/templates/plugins/tts/common.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="row tts-container">
|
||||||
|
<form @submit="talk">
|
||||||
|
<div class="col-8">
|
||||||
|
<input type="text" name="text" placeholder="Text to say">
|
||||||
|
</div>
|
||||||
|
<div class="col-2">
|
||||||
|
<input type="text" name="language" placeholder="Language code">
|
||||||
|
</div>
|
||||||
|
<div class="col-1">
|
||||||
|
<button type="submit">
|
||||||
|
<i class="fa fa-volume-up"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
4
platypush/backend/http/templates/plugins/tts/index.html
Normal file
4
platypush/backend/http/templates/plugins/tts/index.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<script type="text/x-template" id="tmpl-tts">
|
||||||
|
{% include 'plugins/tts/common.html' %}
|
||||||
|
</script>
|
||||||
|
|
|
@ -17,17 +17,17 @@ class TtsPlugin(Plugin):
|
||||||
self.lang=lang
|
self.lang=lang
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def say(self, phrase, lang=None):
|
def say(self, text, language=None):
|
||||||
"""
|
"""
|
||||||
Say a phrase
|
Say a phrase
|
||||||
|
|
||||||
:param phrase: Phrase to say
|
:param text: Phrase to say
|
||||||
:type phrase: str
|
:type text: str
|
||||||
|
|
||||||
:param lang: Language code
|
:param language: Language code
|
||||||
:type lang: str
|
:type language: str
|
||||||
"""
|
"""
|
||||||
if lang is None: lang=self.lang
|
if language is None: language=self.lang
|
||||||
output = None
|
output = None
|
||||||
errors = []
|
errors = []
|
||||||
cmd = ['mplayer -ao alsa -really-quiet -noconsolecontrols ' +
|
cmd = ['mplayer -ao alsa -really-quiet -noconsolecontrols ' +
|
||||||
|
@ -35,8 +35,8 @@ class TtsPlugin(Plugin):
|
||||||
.format(urllib.parse.urlencode({
|
.format(urllib.parse.urlencode({
|
||||||
'ie' : 'UTF-8',
|
'ie' : 'UTF-8',
|
||||||
'client' : 'tw-ob',
|
'client' : 'tw-ob',
|
||||||
'tl' : lang,
|
'tl' : language,
|
||||||
'q' : phrase,
|
'q' : text,
|
||||||
}))]
|
}))]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -18,7 +18,7 @@ class TtsGooglePlugin(Plugin):
|
||||||
* **mplayer** - see your distribution docs on how to install the mplayer package
|
* **mplayer** - see your distribution docs on how to install the mplayer package
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, language='en-US', voice='en-US-Wavenet-C',
|
def __init__(self, language='en-US', voice=None,
|
||||||
gender='FEMALE', credentials_file='~/.credentials/platypush/google/platypush-tts.json'):
|
gender='FEMALE', credentials_file='~/.credentials/platypush/google/platypush-tts.json'):
|
||||||
"""
|
"""
|
||||||
:param language: Language code, see https://cloud.google.com/text-to-speech/docs/basics for supported languages
|
:param language: Language code, see https://cloud.google.com/text-to-speech/docs/basics for supported languages
|
||||||
|
@ -37,9 +37,34 @@ class TtsGooglePlugin(Plugin):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.language = language
|
self.language = language
|
||||||
self.voice = voice
|
self.voice = voice
|
||||||
|
|
||||||
|
self.language = self._parse_language(language)
|
||||||
|
self.voice = self._parse_voice(self.language, voice)
|
||||||
self.gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper())
|
self.gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper())
|
||||||
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = os.path.expanduser(credentials_file)
|
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = os.path.expanduser(credentials_file)
|
||||||
|
|
||||||
|
def _parse_language(self, language):
|
||||||
|
if language is None:
|
||||||
|
language = self.language or 'en-US'
|
||||||
|
|
||||||
|
if len(language) == 2:
|
||||||
|
language = language.lower()
|
||||||
|
if language == 'en':
|
||||||
|
language = 'en-US'
|
||||||
|
else:
|
||||||
|
language += '-' + language.upper()
|
||||||
|
|
||||||
|
return language
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_voice(language, voice):
|
||||||
|
if voice is not None:
|
||||||
|
return voice
|
||||||
|
|
||||||
|
if language == 'en-US':
|
||||||
|
return language + '-Wavenet-C'
|
||||||
|
return language + '-Wavenet-A'
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def say(self, text, language=None, voice=None, gender=None):
|
def say(self, text, language=None, voice=None, gender=None):
|
||||||
"""
|
"""
|
||||||
|
@ -61,17 +86,14 @@ class TtsGooglePlugin(Plugin):
|
||||||
client = texttospeech.TextToSpeechClient()
|
client = texttospeech.TextToSpeechClient()
|
||||||
synthesis_input = texttospeech.types.SynthesisInput(text=text)
|
synthesis_input = texttospeech.types.SynthesisInput(text=text)
|
||||||
|
|
||||||
if language is None:
|
language = self._parse_language(language)
|
||||||
language = self.language
|
voice = self._parse_voice(language, voice)
|
||||||
|
|
||||||
if gender is None:
|
if gender is None:
|
||||||
gender = self.gender
|
gender = self.gender
|
||||||
else:
|
else:
|
||||||
gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper())
|
gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper())
|
||||||
|
|
||||||
if voice is None:
|
|
||||||
voice = self.voice
|
|
||||||
|
|
||||||
voice = texttospeech.types.VoiceSelectionParams(
|
voice = texttospeech.types.VoiceSelectionParams(
|
||||||
language_code=language, ssml_gender=gender,
|
language_code=language, ssml_gender=gender,
|
||||||
name=voice)
|
name=voice)
|
||||||
|
|
Loading…
Reference in a new issue