微信小程序录音实现功能并上传(使用node解析接收)


Posted in Javascript onFebruary 26, 2020

背景

我在开发小程序的时候,有需求要实现录音功能,并能上传给服务器。小程序录音功能我是使用的微信的wx.getRecorderManager()实现的,通过该方法创建实例,实例录音得到的文件是本地临时文件,上传文件需要使用微信的wx.uploadFile(Object object)方法,这就是本次项目的背景。

小程序端

html页面主要是第一个按钮,两个事件,长按开始录音,松手停止录音。第二个按钮只是一个播放录音的功能,用于确定录音是否成功

<!--pages/record/record.wxml-->
<button bindtap="playVoice" type="primary" disabled="{{tempFilePath === ''}}">播放录音</button>
<button type="warn" bindtouchstart="beginRecord" bindtouchend="endRecord">长按开始录音,松手停止录音</button>

js部分主要就是两个事件

// pages/record/record.js
// 两个实例声明在Page之外,方便访问
const recorderManager = wx.getRecorderManager() //这是录音功能的实例,必须的
const innerAudioContext = wx.createInnerAudioContext(); //这是播放录音功能需要的实例
Page({
 data: {
 tempFilePath: '' //存放录音文件的临时路径
 },
 // 播放录音
 playVoice: function(e) {
 innerAudioContext.onPlay(() => {
 console.log('开始播放')
 })
 innerAudioContext.onError((res) => {
 console.log(res.errMsg)
 console.log(res.errCode)
 })
 innerAudioContext.play();
 },
 // 录音
 beginRecord:function(e) {
 // 监听录音开始事件
 recorderManager.onStart(() => {
 console.log('recorder start')
 })
 // 监听已录制完指定帧大小的文件事件。如果设置了 frameSize,则会回调此事件。
 recorderManager.onFrameRecorded((res) => {
 const { frameBuffer } = res
 console.log('frameBuffer.byteLength', frameBuffer.byteLength)
 })
 //录音的参数
 const options = {
 duration: 60000, //录音时间,默认是60s,提前松手会触发button的bindtouchend事件,执行停止函数并上传录音文件。超过60s不松手会如何并未测试过
 sampleRate: 44100,
 numberOfChannels: 1,
 encodeBitRate: 192000,
 format: 'mp3', //录音格式,这里是mp3
 frameSize: 50 //指定帧大小,单位 KB。传入 frameSize 后,每录制指定帧大小的内容后,会回调录制的文件内容,不指定则不会回调。暂仅支持 mp3 格式。
 }
 //开始录音
 recorderManager.start(options); 
 },
 //停止录音并上传数据
 endRecord:function(e) {
 const self = this;
 //停止录音
 recorderManager.stop();
 //监听录音停止事件,执行上传录音文件函数
 recorderManager.onStop((res) => {
 console.log('recorder stop', res)
 //返回值res.tempFilePath是录音文件的临时路径 (本地路径) 
 self.setData({
 tempFilePath: res.tempFilePath
 })
 innerAudioContext.src = res.tempFilePath
 //上传录音文件
 var uploadTask = wx.uploadFile({
 //没有method,自动为POST请求
 filePath: res.tempFilePath,
 name: 'recordFile',  //这个随便填
 url: 'http://localhost:3000/record', //填写自己服务器的地址。
 header: {
 "Content-Type": "multipart/form-data" //必须是这个格式
 },
 success:(e) => {
 console.log('succeed!');
 console.log(e); 
 },
 fail: (e) => {
 console.log('failed!');
 console.log(e); 
 }
 });
 uploadTask.onProgressUpdate((e) => {
 console.log(e);
 console.log('期望上传的总字节数:' + e.totalBytesExpectedToSend);
 console.log('已经上传的字节数' + e.totalBytesSent); 
 })
 })
 }
})

到这里,小程序部分的代码就已经完成了。

node服务器端

前提:

node服务器我是用的是 express 框架,如果有不会的朋友,可以先简单了解一下express。
要后端能解析用户上传的文件,需要合适的中间件。可以参考文章末尾的讲解nodejs使用connect-multiparty实现文件上传(文件接收)后端
首先项目需要安装 express 和 connect-multiparty

npm install express

npm install connnect-multiyparty

大家学node的,上面两句不应该看不懂。我不加 --save 是因为新版的node和npm不需要加就会给你保存在package.json文件内。

//这是我的路由文件的代码片段,监听端口号3000等设置在我的另一个文件内。
//这只是代码片段,大概率跑不起来,只起一个demo的作用。如果需要完整的代码,可以留言给我。

const express = require('express');
const multiparty = require('connect-multiparty');

var router = express.Router();
var multipartMiddleware = multiparty();
router.use(multiparty({uploadDir:'./temp'})); //将接收文件的地址更改为当前目录下的temp文件夹。如果没有,则需要新建该文件夹。

// 处理录音文件
//只需要这样处理,上传的MP3文件就会保存在指定的目录下了。
router.post('/record', multipartMiddleware, (request, response) => {
 console.log('received a request');
 console.log(request.files);
 request.on('end', () => {
 response.send('通信完成');
 })
 
})

郑重提示:保存下来的是临时文件,短时间内就会自动删除,所以大家需要及时处理文件,比如写入到新文件中

这个框架已经两年没更新了,所以这个框架这不一定是好的,但是是可行的

下面看下nodejs使用connect-multiparty实现文件上传(文件接收)后端

文件上传

文件上传是服务器经常会用到的一项功能。做了几次文件上传功能,发现文件接收后端还是没那么容易。尝试过不同的中间件,折腾来折腾去,发现connect-multiparty用起来比较简单,适配nodejs版本v0.12.11。

用法

var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.post('/upload', multipartMiddleware, function(req, resp) {
 console.log(req.body, req.files);
 // don't forget to delete all req.files when done
});

前端用multipart/form-data的形式上传数据,后端通过中间件connect-multipary接收。
注意,接收结果req.files是一个对象,包含POST上传的参数和一个临时文件,文件一般在/tmp目录下,可以将文件移动到指定位置。

var fs = require('fs');
var source = fs.createReadStream(path);
var dest = fs.createWriteStream(output);
source.pipe(dest);
source.on('end', function() { fs.unlinkSync(path);}); //delete
source.on('error', function(err) { });

参考

connect-multiparty

总结

到此这篇关于微信小程序录音实现功能并上传(使用node解析接收)的文章就介绍到这了,更多相关微信小程序录音上传内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript 三种编解码方式
Feb 01 Javascript
精通Javascript系列之数值计算
Jun 07 Javascript
javascript学习笔记(三) String 字符串类型介绍
Jun 19 Javascript
web css实现整站样式互相切换
Oct 29 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
JS创建对象几种不同方法详解
Mar 01 Javascript
jQuery实现按钮点击遮罩加载及处理完后恢复的效果
Jun 07 Javascript
jQuery的三种bind/One/Live/On事件绑定使用方法
Feb 23 Javascript
详解vue-router 2.0 常用基础知识点之导航钩子
May 10 Javascript
vue做网页开场视频的实例代码
Oct 20 Javascript
深入了解javascript 数组的sort方法
Jun 01 Javascript
jQuery实现基本淡入淡出效果的方法详解
Sep 05 jQuery
BootStrap前端框架使用方法详解
Feb 26 #Javascript
原生javascript制作贪吃蛇小游戏的方法分析
Feb 26 #Javascript
javascript 数组精简技巧小结
Feb 26 #Javascript
vue父子模板传值问题解决方法案例分析
Feb 26 #Javascript
jquery实现直播视频弹幕效果
Feb 25 #jQuery
JavaScript实现打砖块游戏
Feb 25 #Javascript
深入理解Antd-Select组件的用法
Feb 25 #Javascript
You might like
解决PHP4.0 和 PHP5.0类构造函数的兼容问题
2013/08/01 PHP
php增删改查示例自己写的demo
2013/09/04 PHP
PHP PDO fetch 模式各种参数的输出结果一览
2015/01/07 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
PHP7新功能总结
2019/04/14 PHP
javascript 复杂的嵌套环境中输出单引号和双引号
2009/05/26 Javascript
一起来写段JS drag拖动代码
2010/12/09 Javascript
利用JQuery动画制作滑动菜单项效果实现步骤及代码
2013/02/07 Javascript
Bootstrap标签页(Tab)插件使用方法
2017/03/21 Javascript
JS倒计时实例_天时分秒
2017/08/22 Javascript
js对象实例详解(JavaScript对象深度剖析,深度理解js对象)
2017/09/21 Javascript
实例详解Vue项目使用eslint + prettier规范代码风格
2018/08/20 Javascript
react 应用多入口配置及实践总结
2018/10/17 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
JS画布动态实现黑客帝国背景效果
2020/11/08 Javascript
vue使用transition组件动画效果的实例代码
2021/01/28 Vue.js
[04:19]完美世界携手游戏风云打造 卡尔工作室模型介绍篇
2013/04/24 DOTA
Python备份Mysql脚本
2008/08/11 Python
python随机生成指定长度密码的方法
2015/04/04 Python
简单了解OpenCV是个什么东西
2017/11/10 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
对python中数据集划分函数StratifiedShuffleSplit的使用详解
2018/12/11 Python
Python3实现统计单词表中每个字母出现频率的方法示例
2019/01/28 Python
Python求两点之间的直线距离(2种实现方法)
2019/07/07 Python
如何基于Python创建目录文件夹
2019/12/31 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
Django表单提交后实现获取相同name的不同value值
2020/05/14 Python
美国在线咖啡、茶和餐厅供应商:LollicupStore
2018/05/04 全球购物
Tostadora意大利:定制T恤
2019/04/08 全球购物
2014年幼儿园植树节活动方案
2014/03/02 职场文书
社会发展项目建议书
2014/08/25 职场文书
2014年小学教师工作自我评价
2014/09/22 职场文书
2014年高中班主任工作总结
2014/11/08 职场文书
2015年幼师个人工作总结
2015/10/15 职场文书
如何使用vue3打造一个物料库
2021/05/08 Vue.js