3

一、概述和通过config接口注入权限验证配置

由于微信的临时素材(如:录音文件)上传到微信服务器上,微信后台保存时间为3天。而我们需要长期保存,我们需要把资源从微信服务器转存到自己服务器,或者阿里云OSS/七牛云。

微信:新增临时素材

通过config接口注入权限验证配置:
步骤三:通过config接口注入权限验证配置

/**
 * 微信JS-SDK权限验证配置
 * 
 * @return array
 */
public function getSignPackage() {
    (new SignPackage())->goCheck();
    $url = input('get.url');
    $jsapiTicket = $this->getJsApiTicket();
    $nonceStr = getRandChar(16);
    $timestamp = time();

    $signature = $this->getSignature($jsapiTicket,$nonceStr,$timestamp,$url);

    $signPackage = array(
        "appId"     => config('wx.g_app_id'),
        "nonceStr"  => $nonceStr,
        "timestamp" => $timestamp,
        "signature" => $signature,
        'expire_id' => config('setting.access_token_expire_in'),
        'url'       => $url
    );
    return $signPackage;
}

/**
 * 获取签名
 * 
 * @param $jsapiTicket
 * @param $nonceStr
 * @param $timestamp
 * @param $url
 * @return string
 */
private  function getSignature($jsapiTicket,$nonceStr,$timestamp,$url)
{
    // 这里参数的顺序要按照 key 值 ASCII 码升序排序
    $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

    $signature = sha1($string);

    return $signature;
}

/**
 * 获取临时票据
 * {
 * "errcode": 0,
 * "errmsg": "ok",
 * "ticket": "kgt8ON7yVITDhtdwci0qeS9ULEKIkoU74AB_VMOQrWUhbW12MQht4FiX4qLA9Z5puKabs96SARo5f1bylEvwXw",
 * "expires_in": 7200
 * }
 * @return mixed
 * @throws Exception
 * @throws ParameterException
 */
private function getJsApiTicket() {

    $access_token = $this->getAccessToken();
    $wxJSapiTicketUrl = sprintf(config('wx.jsapi_ticket'), $access_token);

    $result = curl_get($wxJSapiTicketUrl);
    $wxResult = json_decode($result, true);

    if (empty($wxResult)) {

        throw new Exception('微信内部错误');

    }else if ($wxResult['errmsg'] != 'ok'){
        throw new ParameterException([
            'errorCode' => $wxResult['errcode'],
            'msg' => $wxResult['errmsg']
        ]);
    };

    return $wxResult['ticket'];
}

二、获取media_id

微信JS-SDK说明文档

三、根据media_id下载录音文件

获取临时素材

/**
 * 获取访问微信接口的access_token
 * 
 * @return mixed
 */
public function getAccessToken()
{
    $redis = Cache::store('redis');
    $wx_access_token = $redis->get('wx_access_token');
    if (!$wx_access_token){
        $access_token = $this->getWXAccessToken();
    }else{
        $access_token = $wx_access_token;
    }

    return $access_token;
}
    /**
     * 根据URL地址,下载文件
     *
     * @param $url
     * @param $savePath
     */
    public function downAndSaveFile($url,$savePath)
    {
        ob_start();
        readfile($url);
        $img  = ob_get_contents();
        ob_end_clean();
        $size = strlen($img);
        $fp = fopen($savePath, 'a');
        fwrite($fp, $img);
        fclose($fp);
    }

四、FFmpeg将amr格式音频文件转换未mp3格式

PHP 将amr音频文件转换为mp3格式

/**
 * 将amr格式转换成mp3格式
 *
 * @param $amr
 * @param $prefix_filename
 * @return mixed
 */
public function amrTransCodingMp3($amr, $prefix_filename)
{
    $msgId = $prefix_filename;
    $mp3 = $msgId.'.mp3';
    $dir = $_SERVER['DOCUMENT_ROOT'].'/static/audio/';

    exec("ffmpeg -y -i ".$dir.$amr." ".$dir.$mp3);
    return $mp3;
}

五、将转码后MP3文件上传至OSS

阿里云OSS视频上传概述
PHP-SDK上传文件

/**
 * 上传指定的本地文件内容
 *
 * @param OssClient $ossClient OSSClient实例
 * @param string $bucket 存储空间名称
 * @param string $object 名字
 * @return mixed
 */
function uploadFile($ossClient, $bucket, $object)
{
    $filePath = $_SERVER['DOCUMENT_ROOT'].'/static/audio/'.$object;

    try{
        $res = $ossClient->uploadFile($bucket, $object, $filePath);
        return $res;
    } catch(OssException $e) {
        return [
            'error' => 'FAILED',
            'msg'   => $e->getMessage()
        ];
    }
}

注:
坑一:貌似服务端只有JAVA的,其实通过PHP-SDK也是可以通过上传文件来上传音频文件。

clipboard.png
clipboard.png

坑二

clipboard.png

六、删除本地文件

由于我把微信音频文件存到阿里云OSS,所以将从微信服务器下载的amr和转码的mp3两个音频文件删除。

/**
 * 删除本地音频文件
 *
 * @param $filename
 * @return bool
 * @throws ParameterException
 */
public function deleteDownloadFile($filename)
{
    $filename = $_SERVER['DOCUMENT_ROOT'].'/static/audio/'.$filename;
    if (!unlink($filename))
    {
        throw new ParameterException([
            'msg' => "Error deleting $filename"
        ]);
    }
    else
    {
        return true;
    }
}

七、测试样例

微信录音时长最多为60s,经测试H5端录音60s语音后,后台下载,转码后如下图:

clipboard.png

然后将mp3文件上传OSS后返回给客户端如下:

{
    "server": "AliyunOSS",
    "date": "Mon, 09 Oct 2017 05:52:28 GMT",
    "content-length": "0",
    "connection": "keep-alive",
    "x-oss-request-id": "59DB0E9BE8DFE89CE466195A",
    "etag": "\"A6D50FD012FE2C6AA03EBF38CE23BEEB\"",
    "x-oss-hash-crc64ecma": "8903374940512099110",
    "content-md5": "ptUP0BL+LGqgPr84ziO+6w==",
    "x-oss-server-time": "243",
    "info": {
        "url": "http://xds-test.oss-cn-beijing.aliyuncs.com/wx_download_2017100913522559db0e99d3420.mp3",
        "content_type": null,
        "http_code": 200,
        "header_size": 335,
        "request_size": 472,
        "filetime": -1,
        "ssl_verify_result": 0,
        "redirect_count": 0,
        "total_time": 0.250512,
        "namelookup_time": 0.001418,
        "connect_time": 0.004533,
        "pretransfer_time": 0.004535,
        "size_upload": 60309,
        "size_download": 0,
        "speed_download": 0,
        "speed_upload": 240742,
        "download_content_length": 0,
        "upload_content_length": 60309,
        "starttransfer_time": 0.007707,
        "redirect_time": 0,
        "redirect_url": "",
        "primary_ip": "59.110.185.134",
        "certinfo": [],
        "method": "PUT"
    },
    "oss-request-url": "http://xds-test.oss-cn-beijing.aliyuncs.com/wx_download_2017100913522559db0e99d3420.mp3",
    "oss-redirects": 0,
    "oss-stringtosign": "PUT\n\naudio/mpeg\nMon, 09 Oct 2017 05:52:27 GMT\n/xds-test/wx_download_2017100913522559db0e99d3420.mp3",
    "oss-requestheaders": {
        "Accept-Encoding": "",
        "Content-Type": "audio/mpeg",
        "Date": "Mon, 09 Oct 2017 05:52:27 GMT",
        "Host": "xds-test.oss-cn-beijing.aliyuncs.com",
        "Authorization": "OSS LTAIiKza8Qoz9q4A:PB8WBZp75iaN/pvpbIewFs3Rn08="
    },
    "body": false,
    "process_time": "2.2304130s"
}

从返回process_time来看,从客户端请求到最后返回给客户端,60s音频后台大概需要处理2.3秒左右(根据服务器配置而不同)。

参考资料如下:

微信jssdk录音功能开发记录
PHP 将amr音频文件转换为mp3格式


Bohr
6.5k 声望3.3k 粉丝