php::开发微信公众号录音上传保存功能

首先整理一下思路:
1、认证后的微信公众号,设置项目域名绑定为微信JS安全域
2、使用微信JS编写录音事件,包括开始录音、停止录音、上传录音、服务器保存录音
3、后台负责微信JS签名生成,从微信服务器上下载录制好的音频
4、录音格式为amr文件,使用amr.js编码在线播放

微信开发文档地址:https://mp.weixin.qq.com/wiki

第一步,设置微信公众号JS安全域

配置JS安全域.png

需要下载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无损方法。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容