微信小程序录音实现功能并上传(使用node解析接收)
作者:weixin_43188227 发布时间:2024-04-16 08:46:56
背景
我在开发小程序的时候,有需求要实现录音功能,并能上传给服务器。小程序录音功能我是使用的微信的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
来源:https://blog.csdn.net/weixin_43188227/article/details/104499705


猜你喜欢
- 导语哈喽!我是木木子,今天又想我了嘛?之前不是出过一期Python美颜相机嘛?不知道你们还记得不?这一期的话话题还是围绕上期关于颜值方面来走
- 需要分件html源代码 此例中的被抓取的html源代码如下 <p align=left>2004年8月24日星期二;白天:晴有时
- 每次说到javascript的面向对象,总感觉自己心里懂,但是却不知道该怎么说,这就是似懂非懂到表现,于是乎,每次一说,就要到处去查找资料,
- python保存文本文件的方法:使用python内置的open()类可以打开文本文件,向文件里面写入数据可以用write()函数,写完之后,
- 本文给大家分享一个远程更新目标库数据的存储过程,适用于更新列名一致,主键为Int类型,可远程链接的数据库。USE [Table]--切换到源
- property() 函数的作用是在新式类中返回属性值。Python中有一个property的语法,它类似于C#的get set语法,其功能
- 问题你的程序崩溃后该怎样去调试它?解决方案如果你的程序因为某个异常而崩溃,运行 python3 -i someprogram.py 可执行简
- 使用mysql5.5,突然root密码忘记,怎么也登录不了,很急人,该怎么解决呢?下面通过本文给大家介绍mysql5.5忘记root密码的解
- 自适应线性神经网络Adaptive linear network, 是神经网络的入门级别网络。相对于感知器,采用了f(z)=z的激活函数,属
- 工厂模式(Factory Pattern)是什么工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会
- 因为云服务器的centos是没有图形界面的,所以安装比较麻烦,刚好19c有本地rpm的安装方法,所以推荐用rpm安装。首先到官网下载rpm包
- 以下是演示**“如何在Python中复制文件”的九种方法**。shutil copyfile()方法shutil copy()方法shuti
- 一、什么是异常在python中,错误触发的异常如下二、异常的种类在python中不同的异常可以用不同的类型去标识,一个异常标识一种错误。1
- 不用说火爆一时,全网热议的Web3.0区块链技术,也不必说诸如微信支付、支付宝支付等人们几乎每天都要使用的线上支付业务,单是一个简简单单的注
- 万物皆对象这篇博客的内容主要是针对Python中万物皆对象的理解,对Python的类型、对象体系做一个整体的梳理。在Python中,一切皆为
- settings文件中配置:LOGGING = { 'version':1, 'disabl
- 前言在python的模块有两种组织方式,一种是单纯的python文件,文件名就是模块名,一种是包,包是一个包含了若干python文件的目录,
- 类的参数定义将conda环境设置为ai,conda activate ai这个文件的由来:由于在yolov1的pytorch实现的损失函数中
- 或者说有一条命令 hostname [string],当string是不包含2950时,是true,包含2950时是false。使用Exce
- 1、pip下载安装1.1 pip下载进入https://pypi.python.org/pypi/pip,下载 .tar.gz压缩包1.2&