<div style="background-color:#1e1f22;color:#bcbec4"><pre style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span style="color:#cf8e6d;"><?php<br></span><span style="color:#cf8e6d;">namespace </span>app\common\service;<br><br><span style="color:#cf8e6d;">use </span>think\Cache;<br><span style="color:#cf8e6d;">use </span>think\Log;<br><br><span style="color:#5f826b;font-style:italic;">/**<br></span><span style="color:#5f826b;font-style:italic;"> * </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">百度语音合成(</span><span style="color:#5f826b;font-style:italic;">ThinkPHP5 </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">版)<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">* </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">密钥通过后台配置读取<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">*/<br></span><span style="color:#cf8e6d;">class </span>BaiduTts<br>{<br><br><br> <span style="color:#cf8e6d;">const </span><span style="color:#9876aa;font-style:italic;">TOKEN_CACHE_KEY </span>= <span style="color:#6aab73;">'baidu_tts_token'</span>;<br> <span style="color:#cf8e6d;">const </span><span style="color:#9876aa;font-style:italic;">TOKEN_TTL </span>= <span style="color:#2aacb8;">7000</span>;<br><br> <span style="color:#cf8e6d;">private static </span><span style="color:#c77dbb;font-style:italic;">$instance </span>= <span style="color:#cf8e6d;">null</span>;<br><br> <span style="color:#cf8e6d;">private </span><span style="color:#c77dbb;">$appId</span>;<br> <span style="color:#cf8e6d;">private </span><span style="color:#c77dbb;">$apiKey</span>;<br> <span style="color:#cf8e6d;">private </span><span style="color:#c77dbb;">$secretKey</span>;<br><br> <span style="color:#cf8e6d;">public static function </span><span style="color:#56a8f5;">instance</span>()<br> {<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#57aaf7;">is_null</span>(<span style="color:#cf8e6d;">self</span>::<span style="color:#c77dbb;font-style:italic;">$instance</span>)) {<br> <span style="color:#cf8e6d;">self</span>::<span style="color:#c77dbb;font-style:italic;">$instance </span>= <span style="color:#cf8e6d;">new self</span>();<br> }<br> <span style="color:#cf8e6d;">return self</span>::<span style="color:#c77dbb;font-style:italic;">$instance</span>;<br> }<br><br> <span style="color:#cf8e6d;">private function </span><span style="color:#56a8f5;">__construct</span>(<span style="color:#9876aa;">$appId</span>, <span style="color:#9876aa;">$apiKey</span>, <span style="color:#9876aa;">$secretKey</span>)<br> {<br> <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">从后台读取<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">appId</span>=<span style="color:#9876aa;">$appId</span>;<br> <span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">apiKey</span>= <span style="color:#9876aa;">$apiKey</span>;<br> <span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">secretKey</span>=<span style="color:#9876aa;">$secretKey</span>;<br> <span style="color:#cf8e6d;">if </span>(!<span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">appId </span>|| !<span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">apiKey </span>|| !<span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">secretKey</span>) {<br> <span style="color:#cf8e6d;">throw new </span><span style="color:#6f737a;">\</span>Exception(<span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">请在后台配置百度语音合成密钥</span><span style="color:#6aab73;">'</span>);<br> }<br> }<br><br> <span style="color:#5f826b;font-style:italic;">/**<br></span><span style="color:#5f826b;font-style:italic;"> * </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">通过密钥生成单例<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">*/<br></span><span style="color:#5f826b;font-style:italic;"> </span><span style="color:#cf8e6d;">public static function </span><span style="color:#56a8f5;">create</span>(<span style="color:#9876aa;">$appId</span>, <span style="color:#9876aa;">$apiKey</span>, <span style="color:#9876aa;">$secretKey</span>): <span style="color:#cf8e6d;">self<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">支持多租户:用密钥</span><span style="color:#7a7e85;"> md5 </span><span style="color:#7a7e85;font-family:'宋体',monospace;">做区分<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#9876aa;">$key </span>= <span style="color:#6aab73;">'baidu_tts_' </span>. <span style="color:#57aaf7;">md5</span>(<span style="color:#9876aa;">$appId </span>. <span style="color:#9876aa;">$apiKey</span>);<br> <span style="color:#cf8e6d;">if </span>(!<span style="color:#cf8e6d;">isset</span>(<span style="color:#cf8e6d;">self</span>::<span style="color:#c77dbb;font-style:italic;">$instance</span>[<span style="color:#9876aa;">$key</span>])) {<br> <span style="color:#cf8e6d;">self</span>::<span style="color:#c77dbb;font-style:italic;">$instance</span>[<span style="color:#9876aa;">$key</span>] = <span style="color:#cf8e6d;">new self</span>(<span style="color:#9876aa;">$appId</span>, <span style="color:#9876aa;">$apiKey</span>, <span style="color:#9876aa;">$secretKey</span>);<br> }<br> <span style="color:#cf8e6d;">return self</span>::<span style="color:#c77dbb;font-style:italic;">$instance</span>[<span style="color:#9876aa;">$key</span>];<br> }<br><br> <span style="color:#7a7e85;">/* </span><span style="color:#7a7e85;font-family:'宋体',monospace;">主入口</span><span style="color:#7a7e85;"> */<br></span><span style="color:#7a7e85;"> </span><span style="color:#cf8e6d;">public function </span><span style="color:#56a8f5;">synthesis</span>(<span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$text</span>, <span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$saveDir </span>= <span style="color:#6aab73;">''</span>): <span style="color:#cf8e6d;">string<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#9876aa;">$text </span>= <span style="color:#9876aa;">$this</span>-><span style="color:#57aaf7;">plainText</span>(<span style="color:#9876aa;">$text</span>); <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">先净化<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#cf8e6d;">if </span>(<span style="color:#9876aa;">$text </span>=== <span style="color:#6aab73;">''</span>) {<br> <span style="color:#cf8e6d;">throw new </span><span style="color:#6f737a;">\</span>Exception(<span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">合成文本不能为空</span><span style="color:#6aab73;">'</span>);<br> }<br><br> <span style="color:#9876aa;">$saveDir </span>= <span style="color:#9876aa;">$saveDir </span>?: <span style="color:#9876aa;font-style:italic;">RUNTIME_PATH </span>. <span style="color:#6aab73;">'tts' </span>. <span style="color:#9876aa;font-style:italic;">DS</span>;<br> <span style="color:#cf8e6d;">if </span>(!<span style="color:#57aaf7;">is_dir</span>(<span style="color:#9876aa;">$saveDir</span>)) {<br> <span style="color:#57aaf7;">mkdir</span>(<span style="color:#9876aa;">$saveDir</span>, <span style="color:#2aacb8;">0755</span>, <span style="color:#cf8e6d;">true</span>);<br> }<br> <span style="color:#9876aa;">$mp3File </span>= <span style="color:#9876aa;">$saveDir </span>. <span style="color:#57aaf7;">md5</span>(<span style="color:#9876aa;">$text</span>) . <span style="color:#6aab73;">'.mp3'</span>;<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#57aaf7;">is_file</span>(<span style="color:#9876aa;">$mp3File</span>)) {<br> <span style="color:#cf8e6d;">return </span><span style="color:#9876aa;">$mp3File</span>;<br> }<br> <span style="color:#9876aa;">$token </span>= <span style="color:#9876aa;">$this</span>-><span style="color:#57aaf7;">getAccessToken</span>();<br> <span style="color:#9876aa;">$this</span>-><span style="color:#57aaf7;">doSynthesis</span>(<span style="color:#9876aa;">$text</span>, <span style="color:#9876aa;">$token</span>, <span style="color:#9876aa;">$mp3File</span>);<br> <span style="color:#cf8e6d;">return </span><span style="color:#9876aa;">$mp3File</span>;<br> }<br><br> <span style="color:#7a7e85;">/* </span><span style="color:#7a7e85;font-family:'宋体',monospace;">获取</span><span style="color:#7a7e85;">/</span><span style="color:#7a7e85;font-family:'宋体',monospace;">刷新</span><span style="color:#7a7e85;"> token */<br></span><span style="color:#7a7e85;"> </span><span style="color:#cf8e6d;">private function </span><span style="color:#56a8f5;">getAccessToken</span>(): <span style="color:#cf8e6d;">string<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#9876aa;">$token </span>= Cache::<span style="color:#57aaf7;font-style:italic;">get</span>(<span style="color:#cf8e6d;">self</span>::<span style="color:#9876aa;font-style:italic;">TOKEN_CACHE_KEY</span>);<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#9876aa;">$token</span>) <span style="color:#cf8e6d;">return </span><span style="color:#9876aa;">$token</span>;<br><br> <span style="color:#9876aa;">$url </span>= <span style="color:#6aab73;">'https://aip.baidubce.com/oauth/2.0/token?' </span>. <span style="color:#57aaf7;">http_build_query</span>([<br> <span style="color:#6aab73;">'grant_type' </span>=> <span style="color:#6aab73;">'client_credentials'</span>,<br> <span style="color:#6aab73;">'client_id' </span>=> <span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">apiKey</span>,<br> <span style="color:#6aab73;">'client_secret' </span>=> <span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">secretKey</span>,<br> ]);<br> <span style="color:#9876aa;">$resp </span>= <span style="color:#57aaf7;">json_decode</span>(<span style="color:#57aaf7;">file_get_contents</span>(<span style="color:#9876aa;">$url</span>), <span style="color:#cf8e6d;">true</span>);<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#cf8e6d;">empty</span>(<span style="color:#9876aa;">$resp</span>[<span style="color:#6aab73;">'access_token'</span>])) {<br> Log::<span style="color:#cf8e6d;">error</span>(<span style="color:#6aab73;">'BaiduTts getAccessToken failed: ' </span>. <span style="color:#57aaf7;">json_encode</span>(<span style="color:#9876aa;">$resp</span>));<br> <span style="color:#cf8e6d;">throw new </span><span style="color:#6f737a;">\</span>Exception(<span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">获取百度</span><span style="color:#6aab73;"> access_token </span><span style="color:#6aab73;font-family:'宋体',monospace;">失败</span><span style="color:#6aab73;">'</span>);<br> }<br> <span style="color:#9876aa;">$token </span>= <span style="color:#9876aa;">$resp</span>[<span style="color:#6aab73;">'access_token'</span>];<br> Cache::<span style="color:#57aaf7;font-style:italic;">set</span>(<span style="color:#cf8e6d;">self</span>::<span style="color:#9876aa;font-style:italic;">TOKEN_CACHE_KEY</span>, <span style="color:#9876aa;">$token</span>, <span style="color:#cf8e6d;">self</span>::<span style="color:#9876aa;font-style:italic;">TOKEN_TTL</span>);<br> <span style="color:#cf8e6d;">return </span><span style="color:#9876aa;">$token</span>;<br> }<br><br> <span style="color:#7a7e85;">/* </span><span style="color:#7a7e85;font-family:'宋体',monospace;">真正合成</span><span style="color:#7a7e85;"> */<br></span><span style="color:#7a7e85;"> </span><span style="color:#cf8e6d;">private function </span><span style="color:#56a8f5;">doSynthesis</span>(<span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$text</span>, <span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$token</span>, <span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$saveFile</span>): <span style="color:#cf8e6d;">void<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#9876aa;">$api </span>= <span style="color:#6aab73;">'https://tsn.baidu.com/text2audio'</span>;<br> <span style="color:#9876aa;">$param </span>= [<br> <span style="color:#6aab73;">'tok' </span>=> <span style="color:#9876aa;">$token</span>,<br> <span style="color:#6aab73;">'tex' </span>=> <span style="color:#9876aa;">$text</span>,<br> <span style="color:#6aab73;">'cuid' </span>=> <span style="color:#57aaf7;">md5</span>(<span style="color:#57aaf7;">uniqid</span>()),<br> <span style="color:#6aab73;">'ctp' </span>=> <span style="color:#2aacb8;">1</span>,<br> <span style="color:#6aab73;">'lan' </span>=> <span style="color:#6aab73;">'zh'</span>,<br> <span style="color:#6aab73;">'aue' </span>=> <span style="color:#2aacb8;">3</span>,<br> <span style="color:#6aab73;">'per' </span>=> <span style="color:#2aacb8;">0</span>,<br> <span style="color:#6aab73;">'spd' </span>=> <span style="color:#2aacb8;">5</span>,<br> <span style="color:#6aab73;">'pit' </span>=> <span style="color:#2aacb8;">5</span>,<br> <span style="color:#6aab73;">'vol' </span>=> <span style="color:#2aacb8;">5</span>,<br> ];<br> <span style="color:#9876aa;">$audio </span>= <span style="color:#9876aa;">$this</span>-><span style="color:#57aaf7;">httpPost</span>(<span style="color:#9876aa;">$api</span>, <span style="color:#57aaf7;">http_build_query</span>(<span style="color:#9876aa;">$param</span>));<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#57aaf7;">strpos</span>(<span style="color:#9876aa;">$audio</span>, <span style="color:#6aab73;">'{'</span>) === <span style="color:#2aacb8;">0</span>) {<br> <span style="color:#9876aa;">$err </span>= <span style="color:#57aaf7;">json_decode</span>(<span style="color:#9876aa;">$audio</span>, <span style="color:#cf8e6d;">true</span>);<br> Log::<span style="color:#cf8e6d;">error</span>(<span style="color:#6aab73;">'BaiduTts synthesis failed: ' </span>. <span style="color:#9876aa;">$audio</span>);<br> <span style="color:#cf8e6d;">throw new </span><span style="color:#6f737a;">\</span>Exception(<span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">合成失败:</span><span style="color:#6aab73;">' </span>. (<span style="color:#9876aa;">$err</span>[<span style="color:#6aab73;">'err_msg'</span>] ?? <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">未知</span><span style="color:#6aab73;">'</span>));<br> }<br> <span style="color:#57aaf7;">file_put_contents</span>(<span style="color:#9876aa;">$saveFile</span>, <span style="color:#9876aa;">$audio</span>);<br> }<br><br> <span style="color:#cf8e6d;">private function </span><span style="color:#56a8f5;">httpPost</span>(<span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$url</span>, <span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$body</span>): <span style="color:#cf8e6d;">string<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#9876aa;">$ch </span>= <span style="color:#57aaf7;">curl_init</span>();<br> <span style="color:#57aaf7;">curl_setopt_array</span>(<span style="color:#9876aa;">$ch</span>, [<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_URL </span>=> <span style="color:#9876aa;">$url</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_POST </span>=> <span style="color:#cf8e6d;">true</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_POSTFIELDS </span>=> <span style="color:#9876aa;">$body</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_RETURNTRANSFER </span>=> <span style="color:#cf8e6d;">true</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_SSL_VERIFYPEER </span>=> <span style="color:#cf8e6d;">false</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_TIMEOUT </span>=> <span style="color:#2aacb8;">30</span>,<br> <span style="color:#9876aa;font-style:italic;">CURLOPT_HTTPHEADER </span>=> [<span style="color:#6aab73;">'Content-Type: application/x-www-form-urlencoded'</span>],<br> ]);<br> <span style="color:#9876aa;">$resp </span>= <span style="color:#57aaf7;">curl_exec</span>(<span style="color:#9876aa;">$ch</span>);<br> <span style="color:#cf8e6d;">if </span>(<span style="color:#9876aa;">$resp </span>=== <span style="color:#cf8e6d;">false</span>) {<br> <span style="color:#cf8e6d;">throw new </span><span style="color:#6f737a;">\</span>Exception(<span style="color:#6aab73;">'Curl Error: ' </span>. <span style="color:#57aaf7;">curl_error</span>(<span style="color:#9876aa;">$ch</span>));<br> }<br> <span style="color:#57aaf7;">curl_close</span>(<span style="color:#9876aa;">$ch</span>);<br> <span style="color:#cf8e6d;">return </span><span style="color:#9876aa;">$resp</span>;<br> }<br> <span style="color:#5f826b;font-style:italic;">/**<br></span><span style="color:#5f826b;font-style:italic;"> * </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">把文字处理成适合 </span><span style="color:#5f826b;font-style:italic;">TTS </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">朗读的内容<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">* 1. </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">去 </span><span style="color:#5f826b;font-style:italic;">HTML </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">标签 </span><span style="color:#5f826b;font-style:italic;">& </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">实体 </span><span style="color:#5f826b;font-style:italic;">2. </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">去多余空白 </span><span style="color:#5f826b;font-style:italic;">3. </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">去不可见符号<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">* 4. </span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;">把常见符号转成口语<br></span><span style="color:#5f826b;font-style:italic;font-family:'宋体',monospace;"> </span><span style="color:#5f826b;font-style:italic;">*/<br></span><span style="color:#5f826b;font-style:italic;"> </span><span style="color:#cf8e6d;">private function </span><span style="color:#56a8f5;">plainText</span>(<span style="color:#cf8e6d;">string </span><span style="color:#9876aa;">$raw</span>): <span style="color:#cf8e6d;">string<br></span><span style="color:#cf8e6d;"> </span>{<br> <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">先统一编码<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">mb_convert_encoding</span>(<span style="color:#9876aa;">$raw</span>, <span style="color:#6aab73;">'UTF-8'</span>, <span style="color:#6aab73;">'UTF-8'</span>);<br><br> <span style="color:#7a7e85;">/* --- 1. </span><span style="color:#7a7e85;font-family:'宋体',monospace;">剥掉所有</span><span style="color:#7a7e85;"> HTML </span><span style="color:#7a7e85;font-family:'宋体',monospace;">标签</span><span style="color:#7a7e85;"> & </span><span style="color:#7a7e85;font-family:'宋体',monospace;">实体</span><span style="color:#7a7e85;"> --- */<br></span><span style="color:#7a7e85;"> </span><span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">strip_tags</span>(<span style="color:#9876aa;">$raw</span>);<br> <span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">html_entity_decode</span>(<span style="color:#9876aa;">$raw</span>, <span style="color:#9876aa;font-style:italic;">ENT_QUOTES </span>| <span style="color:#9876aa;font-style:italic;">ENT_HTML5</span>, <span style="color:#6aab73;">'UTF-8'</span>);<br><br> <span style="color:#7a7e85;">/* --- 2. </span><span style="color:#7a7e85;font-family:'宋体',monospace;">删掉非打印字符(除了空格、换行)</span><span style="color:#7a7e85;"> --- */<br></span><span style="color:#7a7e85;"> </span><span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">preg_replace</span>(<span style="color:#6aab73;">'/</span><span style="color:#6aab73;background-color:#293c40;">[\x{00}-\x{08}\x{0B}-\x{0C}\x{0E}-\x{1F}\x{7F}]+</span><span style="color:#6aab73;">/u'</span>, <span style="color:#6aab73;">''</span>, <span style="color:#9876aa;">$raw</span>);<br><br> <span style="color:#7a7e85;">/* --- 3. </span><span style="color:#7a7e85;font-family:'宋体',monospace;">把常见符号口语化</span><span style="color:#7a7e85;"> --- */<br></span><span style="color:#7a7e85;"> </span><span style="color:#9876aa;">$map </span>= [<br> <span style="color:#6aab73;">'&' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">和</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'@' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">在</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'#' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">号</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'©' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">版权</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'®' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">注册商标</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">℃</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">摄氏度</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">¥</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">元</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'$' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">美元</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'%' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">百分之</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'°' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">度</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'+' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">加</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'=' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">等于</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'×' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">乘</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'÷' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">除以</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'>' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">大于</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'<' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">小于</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'/' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">每</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#cf8e6d;">\\</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">、</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'|' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">或</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">【</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">(</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">】</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">)</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'[' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">(</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">']' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">)</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'{' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">(</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'}' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">)</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">(</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">(</span><span style="color:#6aab73;">'</span>, <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">全角括号保留<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">)</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">)</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'——' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">,</span><span style="color:#6aab73;">'</span>, <span style="color:#7a7e85;">// </span><span style="color:#7a7e85;font-family:'宋体',monospace;">破折号<br></span><span style="color:#7a7e85;font-family:'宋体',monospace;"> </span><span style="color:#6aab73;">'—' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">,</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'…' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">,</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'·' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">点</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'•' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">点</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">※</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">星</span><span style="color:#6aab73;">'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">①</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'1'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">②</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'2'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">③</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'3'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">④</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'4'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑤</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'5'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑥</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'6'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑦</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'7'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑧</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'8'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑨</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'9'</span>,<br> <span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">⑩</span><span style="color:#6aab73;">' </span>=> <span style="color:#6aab73;">'10'</span>,<br> ];<br> <span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">strtr</span>(<span style="color:#9876aa;">$raw</span>, <span style="color:#9876aa;">$map</span>);<br><br> <span style="color:#7a7e85;">/* --- 4. </span><span style="color:#7a7e85;font-family:'宋体',monospace;">连续空格、制表、换行 合并成单个空格</span><span style="color:#7a7e85;"> --- */<br></span><span style="color:#7a7e85;"> </span><span style="color:#9876aa;">$raw </span>= <span style="color:#57aaf7;">preg_replace</span>(<span style="color:#6aab73;">'/</span><span style="color:#6aab73;background-color:#293c40;">\s+</span><span style="color:#6aab73;">/u'</span>, <span style="color:#6aab73;">' '</span>, <span style="color:#9876aa;">$raw</span>);<br><br> <span style="color:#7a7e85;">/* --- 5. </span><span style="color:#7a7e85;font-family:'宋体',monospace;">去掉首尾空格</span><span style="color:#7a7e85;"> --- */<br></span><span style="color:#7a7e85;"> </span><span style="color:#cf8e6d;">return </span><span style="color:#57aaf7;">trim</span>(<span style="color:#9876aa;">$raw</span>);<br> }<br>}</pre></div>
<div>下面是调用代码</div><div><div style="background-color:#1e1f22;color:#bcbec4"><pre style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span style="color:#9876aa;">$text </span>= <span style="color:#9876aa;">$this</span>-><span style="color:#c77dbb;">request</span>-><span style="color:#57aaf7;">param</span>(<span style="color:#6aab73;">'text'</span>,<span style="color:#6aab73;">''</span>,<span style="color:#6aab73;">'trim'</span>);<br><span style="color:#cf8e6d;">if </span>(!<span style="color:#9876aa;">$text</span>){<br> <span style="color:#cf8e6d;">return </span><span style="color:#57aaf7;">json</span>([<span style="color:#6aab73;">'code'</span>=><span style="color:#2aacb8;">0</span>,<span style="color:#6aab73;">'msg'</span>=><span style="color:#6aab73;">'</span><span style="color:#6aab73;font-family:'宋体',monospace;">请输入要合成的文本</span><span style="color:#6aab73;">'</span>]);<br>}<br><span style="color:#cf8e6d;">try</span>{<br> <span style="color:#9876aa;">$site </span>= Config::<span style="color:#57aaf7;font-style:italic;">get</span>(<span style="color:#6aab73;">"site"</span>);<br> <span style="color:#9876aa;">$baidu </span>= <span style="color:#6f737a;">\app\common\service\</span>BaiduTts::<span style="color:#57aaf7;font-style:italic;">create</span>(<br> <span style="color:#9876aa;">$site</span>[<span style="color:#6aab73;">'baidu_api_id'</span>],<br> <span style="color:#9876aa;">$site</span>[<span style="color:#6aab73;">'baidu_api_key'</span>],<br> <span style="color:#9876aa;">$site</span>[<span style="color:#6aab73;">'baidu_secret_key'</span>]<br> );<br> <span style="color:#9876aa;">$mp3 </span>= <span style="color:#9876aa;">$baidu</span>-><span style="color:#57aaf7;">synthesis</span>(<span style="color:#9876aa;">$text</span>);<br> <span style="color:#57aaf7;">header</span>(<span style="color:#6aab73;">'Content-Type: audio/mpeg'</span>);<br> <span style="color:#57aaf7;">header</span>(<span style="color:#6aab73;">'Content-Disposition: inline; filename="' </span>. <span style="color:#57aaf7;">basename</span>(<span style="color:#9876aa;">$mp3</span>) . <span style="color:#6aab73;">'"'</span>);<br> <span style="color:#57aaf7;">readfile</span>(<span style="color:#9876aa;">$mp3</span>);<br> <span style="color:#cf8e6d;">exit</span>;<br>}<span style="color:#cf8e6d;">catch </span>(<span style="color:#6f737a;">\</span>Exception <span style="color:#9876aa;">$e</span>){<br> <span style="color:#cf8e6d;">return </span><span style="color:#57aaf7;">json</span>([<span style="color:#6aab73;">'code'</span>=><span style="color:#2aacb8;">0</span>,<span style="color:#6aab73;">'msg'</span>=><span style="color:#9876aa;">$e</span>-><span style="color:#57aaf7;">getMessage</span>()]);<br>}</pre></div></div>
相关文章