个人语音实现

title: 个人语音实现
date: 2015-11-28 16:09:53
categories: "编程"
tags: [语音, 七牛, 微信JS-SDK, 高校之恋]


此处输入图片的描述
此处输入图片的描述

自己挖的坑,果然要自己填!

由于之前开启了CRSF,想增强安全性。过了一段时间,自己吧这事给忘了,导致JS的ajax消息无法发送到后台,一直提示400 BAD request。找了好久才发现,详情

但是也找到个可以检测并且建议的办法,ajax提供error反馈错误信息。

$.ajax({
    url: "/profile/{{ user_id }}",
    type: 'POST',
    data: {data: "failed"},
    error: function(e) { //增加错误反馈
        console.log(e);
    }
})
.done(function (data) {
    console.log(data);
});

前后端交互

  • 访问个人主页(wx_config)
  • 微信上传语音
  • 传递mediaId和record_time到后台
  • 获取token从微信下载语音
  • 上传语音到qiniu(发起任务转换amr为mp3)
  • 存储url+time到数据库

下载语音

获取token和ticket

说明一下:两处需要用到access_token,一是在微信账号绑定的域名下使用JS-SDK上传文件时,通过token来生成ticket来初始化JS-SDK;二是在下载文件时需要认证号产生的token。

本以为JS-SDK的可以使用未认证账号来产生access_token从而产生ticket用于JS端上传数据,从而避免出现提示“XXXX”需要使用录音功能。但是下载时发现,微信会校验mediaId是否来自同一个公众号(不校验才怪勒)。所以上传和下载必须使用同一个已认证微信公众号的APPID和APPSECRET来产生token。

两个不同的服务器都需要token和ticket,为了避免抢走导致一方失效。一个服务器产生token和ticket存于缓存中,每小时更新一次(微信限制每天不超过2000次),并提供其他服务器获取token和ticket的接口。其他服务器需要使用直接通过接口获取即可。

录音时间

录音时间不需要单独存储,直接存储在audio的链接中,通过锚点的方式
http://7xogxw.com1.z0.glb.clouddn.com/2015-11-26 23:11:06.709113#time23
每次读取audio_url,先分割获取录音时间,url和time分别传到前端渲染。

真正的自适应:关于图片,以后可以通过类似的方式,用锚点记录图片的实际长宽,而在前端加载之前,通过url即可获取长宽数据,从而根据设备实际分辨率,折算合适长宽并发起请求,减少大图加载缓慢。同时可以在图片加载之前就可以生成固定比例的图片占位符,避免加载过程中出现页面跳动。

上传语音

上传文件

之前已经实现过七牛图片的上传,但是当初的接口复杂难用(@Lee 佩服),想着要修改之前的上传接口来上传语音文件,我决定还是使用最新qiniu-sdk来上传文件,之前图床是用到过,使用简洁了很多。

但是一个麻烦的问题,新版本的sdk向下兼容性不是很好,如果使用最新的,之前的会报错,具体不知。而要去修改之前的接口和上传部分代码,工作量太大,于是两个版本sdk同时使用,导入新的包为qiniu2,修改所有引用qiniu位置为qiniu2,OK,一切正常。

一般情况,直接获取token上传数据,相当简单。

import qiniu2
from datetime import datetime
import config
from qiniu2 import BucketManager
import base64

def get_token():
    q = qiniu.Auth(config.QINIU_ACCESS_KEY, config.QINIU_SECRET_KEY)
    token = q.upload_token(config.PIC_BUCKET)
    return token
    
up_token, key = upload.get_token()
ret, info = qiniu2.put_data(up_token, key, resp)
assert ret['key'] == key

格式转换

而微信默认amr格式,html不支持。上传语音需要预处理,需要policy用于存储转换的格式、另存到位置和名称等信息来产生up_token。并且如果policy和put_data中的key相同且bucket相同,即可同名覆盖,减少空间使用。

这一段单独看七牛的文档你是啥也看不到的,只告诉你预处理格式。segmentfault上有七牛程序员入驻,可查到很多东西

def get_token():
    q = qiniu2.Auth(config.QN_ACCESS_KEY, config.QN_SECRET_KEY)
    # 文件名称
    key = str(datetime.now())
    # 转换格式
    format = "avthumb/ogg"
    # 另存到bucket和对应名称key
    entry_uri = config.AUDIO_BUCKET + ':' + key
    entry_uri = "saveas/"+ base64.urlsafe_b64encode(entry_uri)
    # 独立队列audioQueue转换
    policy = {
        "persistentOps": format + "|" + entry_uri,
        "persistentPipeline": "audioQueue"
    }
    token = q.upload_token(config.AUDIO_BUCKET, policy=policy)
    return token, key

up_token, key = upload.get_token()
ret, info = qiniu2.put_data(up_token, key, resp)
assert ret['key'] == key

删除文件

上传新的语音的时候,需要删除原来的语音文件。同样很简单,提供需要删除的问题件的key即可。

def del_file(upkey):
    q = qiniu2.Auth(config.QN_ACCESS_KEY, config.QN_SECRET_KEY)
    bucket = BucketManager(q)
    ret, info = bucket.delete(config.AUDIO_BUCKET, upkey)
    return ret, info

语音播放

兼容格式

一开始看html的audio标签的时候,默认ogg和mp3均可。所以默认转换为ogg。最后iOS上不无法播放,于是检查发现iOS压根就不兼容ogg格式,最终转换为mp3格式。

  • iOS录音PC能播放,不是前端、后台原因。
  • 确定iOS的微信兼容audio
    全民K哥能播放,全民K哥的js判断支持h5则使用audio否则flash,而微信支持h5。通过canPlayType属性即可检测。
  • 测试audio兼容性(如果最早就加入并进行检测,前面的都不用折腾)
// 检测能否兼容audio
function support_audio(){
    return !!document.createElement('audio').canPlayType;
}
// 检测能否兼容ogg
function support_audio_ogg(){
    var elem = document.createElement('audio');
    return elem.canPlayType('audio/ogg; codecs="vorbis"');
}
// 检测能否兼容mp3
function support_audio_mp3(){
    var elem = document.createElement('audio');
    return elem.canPlayType('audio/mpeg;');
}

console.log('audio:' + support_audio());
console.log('audio-ogg:'+ support_audio_ogg());
console.log('audio-mp3:'+ support_audio_mp3());

参考:http://www.vnadd.com/25160.htm

  • 使用jsconsole远程调试
    通过该工具可以远程查看访问机器输出到console的数据,即可知道是否兼容。

原文链接

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

推荐阅读更多精彩内容

  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,652评论 0 15
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 有关老家房装修始末原原本本跟你梳理一遍:我们之前一直想卖,但无人诚意接盘,去年我在美国又委托细哥降价到60万卖,因...
    pennyzhou阅读 158评论 0 0
  • 先看看这篇报道哈!共享单车首入英国,傻老外们:Amaing~~! 要求:请以一个网友的身份给这篇网文回帖,自选角度...
    efd4b77d14f0阅读 122评论 0 3
  • 看繁花落尽,岁月悠长。 瞅世间百态,五味杂陈。 品百味果蔬,酸甜苦辣。 闻天地之气,恬淡虚无。 听流言蜚语,颠倒黑...
    梅酒煮年华阅读 209评论 0 0