语音听写(流式版)WebAPI PHP版demo

该代码示例展示了如何在Laravel应用中使用php-wss库与科大讯飞的语音识别接口进行交互,包括建立Websocket连接、发送音频数据、接收识别结果等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于科大讯飞官方文档没有给出php版本的demo,自己手撸了一个
在laravel中使用了 php-wss完成

<?php

namespace App\Http\Services;

use WSSC\WebSocketClient;
use \WSSC\Components\ClientConfig;

class xfyunIat
{

    public function index()
    {
        $hostUrl = "ws://iat-api.xfyun.cn/v2/iat";
        $appid = "xxxxxx";
        $apiSecret = "xxxxx";
        $apiKey = "xxxxx";
        // 请填写您的音频文件路径
        $file = storage_path() . '/app/public/audio/1675996119143.mp3';

        define('STATUS_FIRST_FRAME', 0);
        define('STATUS_CONTINUE_FRAME', 1);
        define('STATUS_LAST_FRAME', 2);


        $st = microtime(true);

        $authUrl = $this->assembleAuthUrl($hostUrl, $apiKey, $apiSecret);
        //echo $authUrl;
        //握手并建立websocket 连接
        $conn = new WebSocketClient($authUrl, new ClientConfig());

        //$conn = new Client($authUrl);
        if (!$conn->isConnected()) {
            throw new \Exception('socket closed!');
        }

        //打开音频文件
        $audioFile = fopen($file, 'rb');
        if ($audioFile === false) {
            throw new \Exception('open file error');
        }

        $frameSize = 1280; //每一帧的音频大小
        $intervel = 40 * 1000; //发送音频间隔
        $status = 0;

        //发送数据
        while (true) {
            $len = fread($audioFile, $frameSize);
            if ($len === false) {
                break;
            }
            if ($len === '') { //文件读取完了,改变status = STATUS_LAST_FRAME
                $status = STATUS_LAST_FRAME;
            }

            switch ($status) {
                case STATUS_FIRST_FRAME: //发送第一帧音频,带business 参数
                    $frameData = array(
                        'common' => array(
                            'app_id' => $appid //appid 必须带上,只需第一帧发送
                        ),
                        'business' => array( //business 参数,只需一帧发送
                            'language' => 'en_us',
                            'domain' => 'iat',
                            //  'accent' => 'mandarin'
                        ),
                        'data' => array(
                            'status' => STATUS_FIRST_FRAME,
                            'format' => 'audio/L16;rate=16000',
                            'audio' => base64_encode($len),
                            'encoding' => 'lame'
                        )
                    );
                    $conn->send(json_encode($frameData));
                    $status = STATUS_CONTINUE_FRAME;
                    break;
                case STATUS_CONTINUE_FRAME:
                    $frameData = array(
                        'data' => array(
                            'status' => STATUS_CONTINUE_FRAME,
                            'format' => 'audio/L16;rate=16000',
                            'audio' => base64_encode($len),
                            'encoding' => 'raw'
                        )
                    );
                    $conn->send(json_encode($frameData));
                    break;
                case STATUS_LAST_FRAME:
                    $frameData = array(
                        'data' => array(
                            'status' => STATUS_LAST_FRAME,
                            'format' => 'audio/L16;rate=16000',
                            'audio' => base64_encode($len),
                            'encoding' => 'raw'
                        )
                    );
                    $conn->send(json_encode($frameData));
                    break 2;
            }

            //模拟音频采样间隔
            usleep($intervel);
        }

        //获取返回的数据
        while (true) {
            $msg = $conn->receive();
            if ($msg === null) {
                break;
            }

            $resp = json_decode($msg, true);

            $code = $resp['code'];
            $message = $resp['message'];
            $data = $resp['data'];
            $result = $data['result'];
            $status = $data['status'];
            $sid = $resp['sid'];

            if ($code != 0) {
                echo sprintf('%d %s %f', $code, $message, microtime(true) - $st);
                break;
            }


            var_dump($resp, $result);
//            echo $result[0], "\n";

            if ($status === 2) {
                echo sprintf('%d %s %f', $code, $message, microtime(true) - $st);
                break;
            }
        }

        fclose($audioFile);
        usleep(1); //等待数据接收完成
        $conn->close();
    }

    function assembleAuthUrl($hostUrl, $apiKey, $apiSecret)
    {
        $ul = parse_url($hostUrl);
        $date = gmdate('D, d M Y H:i:s T');
        $signString = array(
            'host: ' . $ul['host'],
            'date: ' . $date,
            'GET ' . $ul['path'] . ' HTTP/1.1'
        );
        $sgin = implode("\n", $signString);
        $sha = $this->HmacWithShaTobase64("hmac-sha256", $sgin, $apiSecret);
        $authUrl = sprintf('hmac username="%s", algorithm="%s", headers="%s", signature="%s"',
            $apiKey, "hmac-sha256", "host date request-line", $sha);
        $authorization = base64_encode($authUrl);
        $v = array(
            'host' => $ul['host'],
            'date' => $date,
            'authorization' => $authorization
        );
        $query = http_build_query($v);
        $callurl = $hostUrl . '?' . $query;
        return $callurl;
    }

    function HmacWithShaTobase64($algorithm, $data, $key)
    {
        $encodeData = hash_hmac('sha256', $data, $key, true);
        return base64_encode($encodeData);
    }

}

测试

 $o = new xfyunIat();
 $o->index();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值