一、概述和通过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×tamp=$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
三、根据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格式
/**
* 将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
/**
* 上传指定的本地文件内容
*
* @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
也是可以通过上传文件来上传音频文件。
坑二
:
六、删除本地文件
由于我把微信音频文件存到阿里云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
语音后,后台下载,转码后如下图:
然后将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
秒左右(根据服务器配置而不同)。
完
参考资料如下: