首先整理一下思路:
1、认证后的微信公众号,设置项目域名绑定为微信JS安全域
2、使用微信JS编写录音事件,包括开始录音、停止录音、上传录音、服务器保存录音
3、后台负责微信JS签名生成,从微信服务器上下载录制好的音频
4、录音格式为amr文件,使用amr.js编码在线播放
微信开发文档地址:https://mp.weixin.qq.com/wiki
第一步,设置微信公众号JS安全域
需要下载JS安全域凭证文件放在安全域名的根目录下。
第二步,微信JS签名生成
@微信要求生成签名的逻辑必须在服务端完成
签名算法:(jsapi_ticket的获取方式参考微信开发文档)
jsapi_ticket(微信JS接口凭证)+noncestr(服务端生成随机字符串)+timestamp(请求时间戳)+url(请求页面的地址)
①将这些参数名进行ASCII码从小到大排序 sort(array $data);
②按照(key1=value1&key2=value2&key3...)格式组装成字符串
③对字符串sha1加密获得 signature $signature = sha1($str);
注意:access_token 与 jsapi_ticket 的有效时间为7200s,重新获取会生成新的凭证覆盖并消耗微信接口请求次数,注意缓存。
附上签名生成demo:
<?php
/*
* curl
*/
function http_exec($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$res = curl_exec($ch);
curl_close($ch);
return $res;
}
/*
生成随机字符串
*/
function create_random($length = 6){
$rand = '';
for ($i = 0; $i < $length; $i++)
{
$rand .= chr(mt_rand(65, 90));
}
return $rand;
}
$app_id = "微信公众号获取";
$app_secret = "微信公众号获取";
//获取access_token
$access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$app_id}&secret={$app_secret}";
$access_token = json_decode(http_exec($access_token_url),true);
//获取ticket
$ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token['access_token']}&type=jsapi";
$ticket = json_decode(http_exec($ticket_url),true);
//获取随机字符串
$noncestr = create_random(8);
//请求地址
$url = "6.48947.com/weixinjs/JSSDK.html";
$time = time();
//参数列表
$data = array(
"jsapi_ticket=" . $ticket['ticket'],
"noncestr=" . $noncestr,
"timestamp=" . $time,
"url=" . $url
);
//组装加密字符串
$sign_data = "";
sort($data);
foreach ($data as $value) {
$sign_data .= $value ."&";
}
$sign_data = substr($sign_data,0,-1);
//加密
$sign = sha1($sign_data);
echo $sign;
第三步,页面配置微信JS
引入微信JS
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
开启微信JS组件
$.post("./sign.php","url="+window.location.href,function(res){
token = res.token;
wx.config({
debug: true,//true显示提示消息,false隐藏提示消息
appId: res.appid,
timestamp: res.timestamp,
nonceStr: res.noncestr,
signature: res.sign,
jsApiList: ['startRecord','stopRecord','uploadVoice','downloadVoice'] //接口列表
});
//微信JS接口准备就绪时,所有接口逻辑在此方法内实现
wx.ready(function(){
$("#radio_start").on("click",function(event){//开始录音
wx.startRecord({
success: function(){
localStorage.rainAllowRecord = 'true';
},
cancel: function () {
alert('not radio driver');
}
});
});
$("#radio_stop").on("click",function(event){//结束录音
wx.stopRecord({
success: function (res) {
localId = res.localId;
//locaId为本地语音标识
radio_file_up();
$("#radio_stop").append("<p data="+localId+" >¼Òô"+localId+"</p>");
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
});
});
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
console.log(res);
});
},"json");
上传语音文件到微信服务器(微信服务器只对文件保存两天,上传成功后下载到服务器保存)
function radio_file_up(){
wx.uploadVoice({
localId: localId, // 本地微信语音文件标识
isShowProgressTips: 1, // 开启上传提示
success: function (res) {
//上传成功后从微信服务器下保存
var url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token="+token+"&media_id="+res.serverId;
// $.post("./download.php","url="+url,function(res){
// alert("上传成功");
// },"json");
},
error:function(res){
alert(res);
}
});
}
第四步,服务器保存语音文件
<?php
$url = $_POST["url"];
$str = date('YmdHis').time().'.amr';//微信录音文件名 扩展名为 .amr
$targetName = './'.$str; //保存目录
downAndSaveFile($url,$targetName); //保存
echo 1;
//根据URL地址,下载文件
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);
}
die();
第五步,如何在web播放amr格式的音频文件
一共发现了三个方案:
① 使用apple的quickTimePlayer播放器的插件实现播放
② 将amr文件进行base64转码播放,有flash实现和amr插件播放实现
因为时间紧张的原因选择最简单的amr转码播放的方法
参考技术博客:http://www.cnblogs.com/yuhongda0315/p/5224064.html
使用amr.js开源库 git地址:https://github.com/jpemartins/amr.js
demo下载地址:http://pan.baidu.com/s/1cEojoi
功能实现后发现的问题
1、微信JS签名生成时要注意请求发送的url是否正确,微信公众号上下载的凭证文件没有放在根目录下也会提示签名错误。
2、调试使用微信web开发者工具会提高效率
3、录音文件经过base64转码amr.js播放后音频会有一定比例损失,后期再仔细研究amr.js无损方法。