项目需要使用科大讯飞提供的WebAPI进行语音合成

广泛搜罗后在知乎上找到相应解决方案,引用知乎作者 **浮木丶**已有的代码,结合评论区幽泉老哥等诸位大佬提出的意见进行了修改优化。
参考的知乎文章https://zhuanlan.zhihu.com/p/98049541

笔者采用的是原生的php,没有使用任何框架的函数方法

一、首先需要使用composer在项目根目录安装websocket
1、需要安装好composer,可以参考这篇文章,或者自行百度
composer传送门
2、打开项目根目录,然后在文件夹空白处摁住ctrl右键出现此选项,点击打开Power
![](https://img-blog.csdnimg.cn/b266a4f7b5e14382a6eca169a1f590eb.png

3、在出现的窗口里输入下面的代码后回车运行

 composer require textalk/websocket

在这里插入图片描述
项目根目录下出现如下文件则代表安装成功
在这里插入图片描述

二、前往科大讯飞官网注册,申请免费的appid,apikey和apisecret(有次数限制)
科大讯飞官网
使用的虽然是语音合成功能,但是科大讯飞的其他功能都是通用的

三、在此目录下建立php文件,文件内程序代码如下:

<?php

require __DIR__.'/vendor/autoload.php';

use WebSocket\Client;

class api
{
    
    /**
    * 调用科大讯飞接口合成语音
    * @param $params
    * @return array
    */
    public function createAudio($params)
    {
        //判断文件夹是否存在
        if (!is_dir('audio\\')) {
           @mkdir('audio\\');
        }
        $audio_name = $params['audio_name'];
        $audio_content = $params['audio_content'];
        $speed = $params['speed'];
        $volume = $params['volume'];
        $pitch = $params['pitch'];
        //获取科大讯飞参数
        $app_id = $params['APPID'];
        $api_key = $params['APIKEY'];
        $api_secret = $params['APISecret'];
        //拼接链接
        $url = $this->createUrl($api_key, $api_secret);
        $client = new Client($url);
        //拼接要发送的信息
        $message = $this->createMsg($app_id, $speed, $volume, $pitch, $audio_content);
        try {
            $client->send(json_encode($message, true));
            $date = date('YmdHis', time());
            $file_name = $audio_name . $date . '.mp3';
            //需要以追加的方式进行写文件
            $audio_file = fopen('audio\\' . $file_name, 'ab');
            $response = $client->receive();
            $response = json_decode($response, true);
            // 科达讯飞会分多次发送消息
            do {
                if ($response['code']) {
                    return $response;
                }
                //返回的音频需要进行base64解码
                $audio = base64_decode($response['data']['audio']);
                fwrite($audio_file, $audio);
                if ($response['data']['status'] == 2) {
                    break;
                }
                //继续接收消息
                $response = $client->receive();
                $response = json_decode($response, true);
            } while (true);
            fclose($audio_file);
            return [
                'code' => 0,
                'msg' => '合成成功',
            ];
        } catch (Exception $e) {
            return [
                'code' => -1,
                'msg' => $e->getMessage(),
            ];
        } finally {
            $client->close();
        }
    }

    /**
    * 拼接签名
    * @param $api_key
    * @param $api_secret
    * @param $time
    * @return string
    */
    private function sign($api_key, $api_secret, $time)
    {
        $signature_origin = 'host: ws-api.xfyun.cn' . "\n";
        $signature_origin .= 'date: ' . $time . "\n";
        $signature_origin .= 'GET /v2/tts HTTP/1.1';
        $signature_sha = hash_hmac('sha256', $signature_origin, $api_secret, true);
        $signature_sha = base64_encode($signature_sha);
        $authorization_origin = 'api_key="' . $api_key . '", algorithm="hmac-sha256", ';
        $authorization_origin .= 'headers="host date request-line", signature="' . $signature_sha . '"';
        $authorization = base64_encode($authorization_origin);
        return $authorization;
    }

    /**
    * 生成Url
    * @param $api_key
    * @param $api_secret
    * @return string
    */
    private function createUrl($api_key, $api_secret)
    {
        $url = 'wss://tts-api.xfyun.cn/v2/tts';
        $time = gmdate('D, d M Y H:i:s') . ' GMT';
        $authorization = $this->sign($api_key, $api_secret, $time);
        $url .= '?' . 'authorization=' . $authorization . '&date=' . urlencode($time) . '&host=ws-api.xfyun.cn';
        return $url;
    }

    /**
    * 生成要发送的消息体
    * @param $app_id
    * @param $speed
    * @param $volume
    * @param $pitch
    * @param $audio_content
    * @return array
    */
    private function createMsg($app_id, $speed, $volume, $pitch, $audio_content)
    {
        return [
            'common' => [
                'app_id' => $app_id,
            ],
            'business' => [
                'aue' => 'lame',
                'auf' => 'audio/L16;rate=16000',
                'vcn' => 'xiaoyan',
                'speed' => (int)$speed,
                'volume' => (int)$volume,
                'pitch' => (int)$pitch,
                'tte' => 'UTF8',
                'sfl' => 1,
            ],
            'data' => [
                'status' => 2,
                'text' => base64_encode($audio_content),
            ],
        ];
    }
}

$params = array(
    // 合成音频的前缀名称
    "audio_name"=>"test",
    // 需要合成语音的内容
    "audio_content"=>"第1次合成!第2次合成!第3次合成!第4次合成!第5次合成!第6次合成!第7次合成!",
    // 语速,可选值:[0-100],默认为50
    "speed"=>"50",
    // 音量,可选值:[0-100],默认为50
    "volume"=>"50",
    // 音高,可选值:[0-100],默认为50
    "pitch"=>"50",
    "APPID"=>"你申请的appid",
    "APIKEY"=>"你申请的apikey",
    "APISecret"=>"你申请的apisecret"
);

$test = new api();

$test->createAudio($params);

?>

最后结果能够在根目录的audio文件夹下生成test+时间戳的名称的mp3文件

更多推荐