前言
在开发小程序过程中,有一个实现录音功能并播放录音,将录音上传至服务器的需求。开发过程中使用了Taro框架,录音功能通过Taro.getRecorderManager()
接口实现,上传录音至服务器通过Taro.uploadFile
接口实现,播放录音使用Taro.createInnerAudioContext()
接口实现。下面就详细介绍整个流程是如何实现的。
小程序录音
首先获取录音管理器模块:
const recorderManager = Taro.getRecorderManager();
在组件挂载完毕时注册录音监听事件:
useEffect(() => {
// 监听录音开始
recorderManager.onStart(() => {
console.log('开始录音');
});
// 监听录音暂停
recorderManager.onPause(() => {
console.log('暂停录音');
});
// 监听录音继续
recorderManager.onResume(() => {
console.log('继续录音');
});
// 监听录音停止
recorderManager.onStop((res) => {
if (res.duration < 1000) {
Taro.showToast({
title: '录音时间太短',
duration: 1000,
icon: 'none',
});
} else {
console.log('停止录音');
fileUpload(res.tempFilePath);
}
});
recorderManager.onError(() => {
Taro.showToast({
title: '录音失败!',
duration: 1000,
icon: 'none',
});
});
}, []);
在录音onStop
的回调函数中,我们可以获取到录音的临时地址res.tempFilePath
,但这个地址是有有效期限的,所以我们需要将这个录音上传至服务器后台,进行保存,后续才能正常使用。
onStop
回调函数中我们调用了fileUpload
函数实现文件上传,fileUpload
函数的实现如下:
const fileUpload = (tempFilePath) => {
Taro.uploadFile({
url: 'http://127.0.0.1:7001/record', // 服务器地址
filePath: tempFilePath,
name: 'file', // 这个随便填
header: {
'content-type': 'multipart/form-data', // 格式必须是这个
Authorization: Taro.getStorageSync('token'),
},
// formData用于传输除文件以外的一些信息
formData: {
record_name: '朗诵作品',
poem_id: poemInfo.id,
category: poemInfo.category,
},
success: (res) => {
console.log(res);
const url = res.data;
playAudio(url); // 播放录音
},
fail: (error) => {
console.log('failed!');
console.error(error);
},
});
};
需要注意的点是:header
中的content-type
必须是multipart/form-data
。
录音事件的处理
第一次点击handleClick
就会触发开始录音,之后会通过当前状态判断是暂停录音还是继续录音。handleComplete
用于停止录音。
const handleClick = () => {
const curPause = pause;
setPause(!curPause);
if (firstRecord) {
setfirstRecord(false);
recorderManager.start({
duration: 60000,
sampleRate: 44100,
numberOfChannels: 1,
encodeBitRate: 192000,
format: 'mp3',
frameSize: 50,
});
Taro.showToast({
title: '开始录音',
duration: 1000,
icon: 'none',
});
} else {
if (curPause) {
recorderManager.pause(); // 暂停录音
} else {
recorderManager.resume(); // 继续录音
}
}
};
const handleComplete = () => {
recorderManager.stop(); // 停止录音
};
后台实现录音存储并返回录音地址
网上大多数博客都没有涉及这块内容,下面就介绍一下如何实现,后台框架我用的是阿里的egg.js
。
文件上传需要配置的东西可见官方文档:egg.js文件上传。我们这里使用它的第一种File
模式来实现。
因为egg.js
框架内置了Multipart
插件,可以解析上传的multipart/form-data
类型的数据。
首先,现在配置文件config.default.js
中写入multipart
配置:
module.exports = (app) => {
const config = (exports = {});
...
config.multipart = {
mode: 'file',
fileSize: '50mb',
}
...
return {
...config,
...userConfig,
};
};
然后,在router.js
中定义路由:
// 提交录音
router.post('/record', auth, controller.record.postRecord);
在controller
目录下定义record.js
文件写入如下内容:
const Controller = require('egg').Controller;
class RecordController extends Controller {
async postRecord() {
const { ctx } = this;
const file = ctx.request.files[0];
const { record_name, poem_id, category } = ctx.request.body;
const res = await ctx.service.record.postRecord(file, record_name, poem_id, category);
ctx.body = res;
}
}
module.exports = RecordController;
在service
目录下定义record.js
写入具体实现:
const Service = require('egg').Service;
let OSS = require('ali-oss');
let aliInfo = {
// https://help.aliyun.com/document_detail/31837.html
region: 'oss-cn-guangzhou',
bucket: 'poem-mini-program',
accessKeyId: 'xxx', // 填入阿里云的accessKeyId
accessKeySecret: 'xxx', // 填入阿里云的accessKeySecret
};
let client = new OSS(aliInfo);
class RecordService extends Service {
async postRecord(file, record_name, poem_id, category) {
const url = await this.uploadOSS(file);
await this.updateRecord(url, record_name, poem_id, category);
return url;
}
async uploadOSS(file) {
const { ctx } = this;
let result;
try {
// 处理文件,比如上传到云端
result = await client.put(file.filename, file.filepath);
} finally {
// 需要删除临时文件
await ctx.cleanupRequestFiles();
}
return result.url;
}
async updateRecord(url, record_name, poem_id, category) {
const { ctx } = this;
console.log('从ctx.locals中取openid');
console.log(ctx.locals.openid);
const openid = ctx.locals.openid;
// 将用户信息记录到数据库中
const res = await ctx.model.Record.create({
record_name: record_name,
record_url: url,
poem_id: poem_id,
category: category,
openid: openid,
});
}
}
module.exports = RecordService;
这里需要注意的是:
- 需要注册阿里云账号,并在对象存储那里新建一个存储桶用于存放音频,也就是云存储的实现。
- 需要安装
ali-oss
npm包,用于连接阿里云对象存储。在后台接收到前端上传的临时文件后,就会将音频上传至阿里云对象存储中(client.put
)。
播放录音
细心的小伙伴可以注意到在使用Taro.uploadFile
接口上传录音后,在success
回调中调用了playAudio
函数用于播放音频,接下来讲一下播放音频是如何实现的。
首先,使用Taro.createInnerAudioContext
获取audio
的上下文对象:
const innerAudioText = Taro.createInnerAudioContext();
和录音一样,在组件挂载完成时,注册监听事件:
useEffect(() => {
innerAudioText.onPlay(() => {
console.log('开始播放');
});
innerAudioText.onError((e) => {
console.log('播放异常');
console.log(e);
});
}, []);
在录音文件上传成功后,调用playAudio
方法用于播放录音:
const playAudio = (url) => {
innerAudioText.autoplay = true;
innerAudioText.src = url;
};
在src
被赋予值的时候,录音就会开始播放。
总结
以上就是整个录音功能和录音播放功能实现的整个流程,如有疑问欢迎大家一起交流。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!