参数配置
+合成结果
+ +使用提示
+-
+
- 建议单次合成文本不超过120字节(约60个汉字),过长文本可能导致合成失败 +
- 情感发音人(度逍遥、度丫丫)可获得更自然的语音效果 +
- 语速范围0-15,数值越大语速越快,默认5为正常语速 +
- 音调范围0-15,数值越大音调越高,默认5为正常音调 +
diff --git a/application/route.php b/application/route.php index ffec3cb..ab93d6d 100644 --- a/application/route.php +++ b/application/route.php @@ -1344,3 +1344,8 @@ Route::any('/xishuju1/ceshiyong', 'test/xishuju1/ceshiyong'); // return '404 Not Found(out)'; // // 或者你可以重定向到一个错误页面,或者进行其他处理 // }); + +################################################################下面是百度TTS语音合成################################################################ +Route::any('/tsf/baiduyuyin', 'tsf/index/index'); +Route::any('/tsf/index/synthesize', 'tsf/index/synthesize'); +Route::any('/tsf/index/clearToken', 'tsf/index/clearToken'); diff --git a/application/tsf/controller/Index.php b/application/tsf/controller/Index.php new file mode 100644 index 0000000..ada6af1 --- /dev/null +++ b/application/tsf/controller/Index.php @@ -0,0 +1,149 @@ +fetch(); + } + + public function synthesize() + { + $data = input('post.'); + + $text = isset($data['text']) ? trim($data['text']) : ''; + if (empty($text)) { + return $this->error('文本内容不能为空'); + } + + $params = [ + 'tex' => $text, + 'lan' => isset($data['lan']) ? $data['lan'] : 'zh', + 'ctp' => isset($data['ctp']) ? $data['ctp'] : 1, + 'cuid' => isset($data['cuid']) ? $data['cuid'] : 'php_tts_' . time(), + 'spd' => isset($data['spd']) ? intval($data['spd']) : 5, + 'pit' => isset($data['pit']) ? intval($data['pit']) : 5, + 'vol' => isset($data['vol']) ? intval($data['vol']) : 5, + 'per' => isset($data['per']) ? intval($data['per']) : 0, + 'aue' => isset($data['aue']) ? $data['aue'] : 3, + ]; + + $token = $this->getAccessToken(); + if (!$token) { + return $this->error('获取Access Token失败,请检查API配置'); + } + $params['tok'] = $token; + + $url = 'https://tsn.baidu.com/text2audio'; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + return $this->error('请求失败: ' . $error); + } + + if ($httpCode != 200) { + return $this->error('请求失败,HTTP状态码: ' . $httpCode); + } + + if (strpos($contentType, 'audio') === false) { + $result = json_decode($response, true); + if (isset($result['err_msg'])) { + return $this->error('TTS合成失败: ' . $result['err_msg']); + } + return $this->error('TTS合成失败,未知错误'); + } + + $fileSize = strlen($response); + $base64Data = base64_encode($response); + + $audioFormat = 'mp3'; + if (strpos($contentType, 'mp3') !== false) { + $audioFormat = 'mp3'; + } elseif (strpos($contentType, 'wav') !== false) { + $audioFormat = 'wav'; + } elseif (strpos($contentType, 'pcm') !== false) { + $audioFormat = 'pcm'; + } + + return json([ + 'code' => 0, + 'msg' => 'success', + 'data' => [ + 'audio_data' => $base64Data, + 'audio_format' => $audioFormat, + 'file_size' => $fileSize, + 'content_type' => $contentType, + ] + ]); + } + + private function getAccessToken() + { + if (!empty($this->accessToken)) { + return $this->accessToken; + } + + $cachedToken = cache($this->tokenCacheKey); + if ($cachedToken) { + return $cachedToken; + } + + $url = 'https://aip.baidubce.com/oauth/2.0/token'; + $params = [ + 'grant_type' => 'client_credentials', + 'client_id' => $this->apiKey, + 'client_secret' => $this->secretKey, + ]; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $response = curl_exec($ch); + curl_close($ch); + + $result = json_decode($response, true); + + if (isset($result['access_token'])) { + cache($this->tokenCacheKey, $result['access_token'], $this->tokenExpire); + return $result['access_token']; + } + + return false; + } + + public function clearToken() + { + cache($this->tokenCacheKey, null); + return $this->success('Token已清除,下次请求时会重新获取'); + } +} diff --git a/application/tsf/view/index/index.html b/application/tsf/view/index/index.html new file mode 100644 index 0000000..9acf72e --- /dev/null +++ b/application/tsf/view/index/index.html @@ -0,0 +1,650 @@ + + +
+ + +基于百度智能云短文本在线合成API
+正在合成语音...
+