use GuzzleHttp\Psr7\Response;
use Illuminate\Support\Facades\Cache;
-class Api {
- /**
- * @var string
- */
- protected $key;
-
- /**
- * @var string
- */
- protected $region;
-
- /**
- * @var null|string
- */
- protected $token = null;
-
- /**
- * @var int
- */
- protected $tokenTime = 0;
-
-
- /**
- * @var Client
- */
- protected $client;
-
- public function __construct($key, $region = 'francecentral') {
- $this->key = $key;
- $this->region = $region;
- $this->client = new Client();
- }
-
- public function textToSpeech($text, $locale, $gender, $voiceName, $saveToFile) {
- $ssml = "<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='$locale'><voice xml:lang='$locale' xml:gender='$gender' name='$voiceName'>";
- $ssml .= htmlspecialchars($text, ENT_XML1 | ENT_SUBSTITUTE | ENT_QUOTES);
- $ssml .= "</voice></speak>";
-
- $this->_call('/v1', 'post', [
- 'X-Microsoft-OutputFormat' => 'audio-48khz-192kbitrate-mono-mp3',
- 'Content-type' => 'application/ssml+xml'
- ], $ssml, ['sink' => $saveToFile]);
- }
-
- /**
- * @param $raw
- * @return array|false
- */
- public function listVoices($raw = false) {
- $cacheKey = 'azure_tts_voices_' . $raw;
- Cache::forget($cacheKey);
- return Cache::remember($cacheKey, 86400, function () use ($raw) {
- return $this->_listVoices($raw);
- });
- }
-
- /**
- * @param $raw bool
- * @return array|false
- */
- protected function _listVoices($raw = false) {
- $resp = $this->_call('/voices/list');
- if (!$resp) {
- return false;
- }
- $j = json_decode($resp->getBody()->getContents(), true);
- if ($raw) {
- return $j;
- }
- $res = [];
- foreach ($j as $voice) {
- $res[$voice['Locale'] . '/' . $voice['Gender'] . '/' . $voice['ShortName']] = $voice['DisplayName'] . ' / ' . $voice['Gender'] . ' / ' . $voice['LocaleName'];
- }
- return $res;
- }
-
- /**
- * @param string $url
- * @param string $method
- * @param array $headers
- * @param string|null $body
- * @param array $options
- * @return Response|false
- */
- protected function _call($url, $method = 'get', $headers = [], $body = null, $options = []) {
-
- if (!$this->checkToken()) {
- return false;
- }
- $baseURL = 'https://' . $this->region . '.tts.speech.microsoft.com/cognitiveservices/';
- $headers = array_merge([
- 'Authorization' => 'Bearer ' . $this->token,
- 'User-Agent' => 'Cubist TTS Client'], $headers);
-
- return $this->client->send(new Request($method, $baseURL . ltrim($url, '/'), $headers, $body), $options);
- }
-
- protected function checkToken() {
- if (null !== $this->token && $this->tokenTime > (time() - 540)) {
- return true;
- }
-
- try {
-
- $this->token = $this->client->post('https://' . $this->region . '.api.cognitive.microsoft.com/sts/v1.0/issuetoken',
- ['headers' =>
- [
- 'Ocp-Apim-Subscription-Key' => $this->key
- ]
- ]
- )->getBody()->getContents();
- return true;
- } catch (\Exception $e) {
-
- }
- return false;
- }
+class Api
+{
+ /**
+ * @var string
+ */
+ protected $key;
+
+ /**
+ * @var string
+ */
+ protected $region;
+
+ /**
+ * @var null|string
+ */
+ protected $token = null;
+
+ /**
+ * @var int
+ */
+ protected $tokenTime = 0;
+
+
+ /**
+ * @var Client
+ */
+ protected $client;
+
+ public function __construct($key, $region = 'francecentral')
+ {
+ $this->key = $key;
+ $this->region = $region;
+ $this->client = new Client();
+ }
+
+ public function textToSpeech($text, $locale, $gender, $voiceName, $saveToFile)
+ {
+ $ssml = "<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='$locale'><voice xml:lang='$locale' xml:gender='$gender' name='$voiceName'>";
+ $text = self::stripNonSSMLTags($text);
+ $ssml .= htmlspecialchars($text, ENT_XML1 | ENT_SUBSTITUTE | ENT_QUOTES);
+ $ssml .= "</voice></speak>";
+
+ $this->_call('/v1', 'post', [
+ 'X-Microsoft-OutputFormat' => 'audio-48khz-192kbitrate-mono-mp3',
+ 'Content-type' => 'application/ssml+xml'
+ ], $ssml, ['sink' => $saveToFile]);
+ }
+
+ public static function stripNonSSMLTags($text, $additional_allowed_tags = '')
+ {
+ return strip_tags($text, '<break><say-as><audio><p><s><sub><mark><prosody><emphasis><par><seq><media><phoneme><voice><lang>' . $additional_allowed_tags);
+ }
+
+ /**
+ * @param $raw
+ * @return array|false
+ */
+ public function listVoices($raw = false)
+ {
+ $cacheKey = 'azure_tts_voices_' . $raw;
+ Cache::forget($cacheKey);
+ return Cache::remember($cacheKey, 86400, function () use ($raw) {
+ return $this->_listVoices($raw);
+ });
+ }
+
+ /**
+ * @param $raw bool
+ * @return array|false
+ */
+ protected function _listVoices($raw = false)
+ {
+ $resp = $this->_call('/voices/list');
+ if (!$resp) {
+ return false;
+ }
+ $j = json_decode($resp->getBody()->getContents(), true);
+ if ($raw) {
+ return $j;
+ }
+ $res = [];
+ foreach ($j as $voice) {
+ $res[$voice['Locale'] . '/' . $voice['Gender'] . '/' . $voice['ShortName']] = $voice['DisplayName'] . ' / ' . $voice['Gender'] . ' / ' . $voice['LocaleName'];
+ }
+ return $res;
+ }
+
+ /**
+ * @param string $url
+ * @param string $method
+ * @param array $headers
+ * @param string|null $body
+ * @param array $options
+ * @return Response|false
+ */
+ protected function _call($url, $method = 'get', $headers = [], $body = null, $options = [])
+ {
+
+ if (!$this->checkToken()) {
+ return false;
+ }
+ $baseURL = 'https://' . $this->region . '.tts.speech.microsoft.com/cognitiveservices/';
+ $headers = array_merge([
+ 'Authorization' => 'Bearer ' . $this->token,
+ 'User-Agent' => 'Cubist TTS Client'], $headers);
+
+ return $this->client->send(new Request($method, $baseURL . ltrim($url, '/'), $headers, $body), $options);
+ }
+
+ protected function checkToken()
+ {
+ if (null !== $this->token && $this->tokenTime > (time() - 540)) {
+ return true;
+ }
+
+ try {
+
+ $this->token = $this->client->post('https://' . $this->region . '.api.cognitive.microsoft.com/sts/v1.0/issuetoken',
+ ['headers' =>
+ [
+ 'Ocp-Apim-Subscription-Key' => $this->key
+ ]
+ ]
+ )->getBody()->getContents();
+ return true;
+ } catch (\Exception $e) {
+
+ }
+ return false;
+ }
}
\ No newline at end of file