经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » 微信小程序 » 查看文章
小程序录音功能实现
来源:jb51  时间:2021/3/8 11:18:13  对本文有异议

前言

在开发小程序过程中,有一个实现录音功能并播放录音,将录音上传至服务器的需求。开发过程中使用了Taro框架,录音功能通过Taro.getRecorderManager()接口实现,上传录音至服务器通过Taro.uploadFile接口实现,播放录音使用Taro.createInnerAudioContext()接口实现。下面就详细介绍整个流程是如何实现的。

小程序录音

首先获取录音管理器模块:

  1. const recorderManager = Taro.getRecorderManager();

在组件挂载完毕时注册录音监听事件:

  1. useEffect(() => {
  2. // 监听录音开始
  3. recorderManager.onStart(() => {
  4. console.log('开始录音');
  5. });
  6. // 监听录音暂停
  7. recorderManager.onPause(() => {
  8. console.log('暂停录音');
  9. });
  10. // 监听录音继续
  11. recorderManager.onResume(() => {
  12. console.log('继续录音');
  13. });
  14. // 监听录音停止
  15. recorderManager.onStop((res) => {
  16. if (res.duration < 1000) {
  17. Taro.showToast({
  18. title: '录音时间太短',
  19. duration: 1000,
  20. icon: 'none',
  21. });
  22. } else {
  23. console.log('停止录音');
  24. fileUpload(res.tempFilePath);
  25. }
  26. });
  27.  
  28. recorderManager.onError(() => {
  29. Taro.showToast({
  30. title: '录音失败!',
  31. duration: 1000,
  32. icon: 'none',
  33. });
  34. });
  35. }, []);
  36.  

在录音onStop的回调函数中,我们可以获取到录音的临时地址res.tempFilePath,但这个地址是有有效期限的,所以我们需要将这个录音上传至服务器后台,进行保存,后续才能正常使用。

onStop回调函数中我们调用了fileUpload函数实现文件上传,fileUpload函数的实现如下:

  1. const fileUpload = (tempFilePath) => {
  2. Taro.uploadFile({
  3. url: 'http://127.0.0.1:7001/record', // 服务器地址
  4. filePath: tempFilePath,
  5. name: 'file', // 这个随便填
  6. header: {
  7. 'content-type': 'multipart/form-data', // 格式必须是这个
  8. Authorization: Taro.getStorageSync('token'),
  9. },
  10. // formData用于传输除文件以外的一些信息
  11. formData: {
  12. record_name: '朗诵作品',
  13. poem_id: poemInfo.id,
  14. category: poemInfo.category,
  15. },
  16. success: (res) => {
  17. console.log(res);
  18. const url = res.data;
  19. playAudio(url); // 播放录音
  20. },
  21. fail: (error) => {
  22. console.log('failed!');
  23. console.error(error);
  24. },
  25. });
  26. };

需要注意的点是:header中的content-type必须是multipart/form-data。

录音事件的处理

第一次点击handleClick就会触发开始录音,之后会通过当前状态判断是暂停录音还是继续录音。handleComplete用于停止录音。

  1. const handleClick = () => {
  2. const curPause = pause;
  3. setPause(!curPause);
  4.  
  5. if (firstRecord) {
  6. setfirstRecord(false);
  7.  
  8. recorderManager.start({
  9. duration: 60000,
  10. sampleRate: 44100,
  11. numberOfChannels: 1,
  12. encodeBitRate: 192000,
  13. format: 'mp3',
  14. frameSize: 50,
  15. });
  16.  
  17. Taro.showToast({
  18. title: '开始录音',
  19. duration: 1000,
  20. icon: 'none',
  21. });
  22.  
  23. } else {
  24. if (curPause) {
  25. recorderManager.pause(); // 暂停录音
  26. } else {
  27. recorderManager.resume(); // 继续录音
  28. }
  29. }
  30. };
  31.  
  32. const handleComplete = () => {
  33. recorderManager.stop(); // 停止录音
  34. };

后台实现录音存储并返回录音地址

网上大多数博客都没有涉及这块内容,下面就介绍一下如何实现,后台框架我用的是阿里的egg.js。

文件上传需要配置的东西可见官方文档:egg.js文件上传。我们这里使用它的第一种File模式来实现。

因为egg.js框架内置了Multipart插件,可以解析上传的multipart/form-data类型的数据。

首先,现在配置文件config.default.js中写入multipart配置:

  1. module.exports = (app) => {
  2. const config = (exports = {});
  3. ...
  4.  
  5. config.multipart = {
  6. mode: 'file',
  7. fileSize: '50mb',
  8. }
  9. ...
  10.  
  11. return {
  12. ...config,
  13. ...userConfig,
  14. };
  15. };
  16.  

然后,在router.js中定义路由:

  1. // 提交录音
  2. router.post('/record', auth, controller.record.postRecord);
  3.  
  4. controller目录下定义record.js文件写入如下内容:
  5. const Controller = require('egg').Controller;
  6.  
  7. class RecordController extends Controller {
  8. async postRecord() {
  9. const { ctx } = this;
  10. const file = ctx.request.files[0];
  11. const { record_name, poem_id, category } = ctx.request.body;
  12. const res = await ctx.service.record.postRecord(file, record_name, poem_id, category);
  13.  
  14. ctx.body = res;
  15. }
  16. }
  17.  
  18. module.exports = RecordController;
  19.  

在service目录下定义record.js写入具体实现:

  1. const Service = require('egg').Service;
  2. let OSS = require('ali-oss');
  3.  
  4. let aliInfo = {
  5. // https://help.aliyun.com/document_detail/31837.html
  6. region: 'oss-cn-guangzhou',
  7. bucket: 'poem-mini-program',
  8. accessKeyId: 'xxx', // 填入阿里云的accessKeyId
  9. accessKeySecret: 'xxx', // 填入阿里云的accessKeySecret
  10. };
  11.  
  12. let client = new OSS(aliInfo);
  13.  
  14. class RecordService extends Service {
  15. async postRecord(file, record_name, poem_id, category) {
  16. const url = await this.uploadOSS(file);
  17. await this.updateRecord(url, record_name, poem_id, category);
  18.  
  19. return url;
  20. }
  21.  
  22. async uploadOSS(file) {
  23. const { ctx } = this;
  24.  
  25. let result;
  26. try {
  27. // 处理文件,比如上传到云端
  28. result = await client.put(file.filename, file.filepath);
  29. } finally {
  30. // 需要删除临时文件
  31. await ctx.cleanupRequestFiles();
  32. }
  33. return result.url;
  34. }
  35.  
  36. async updateRecord(url, record_name, poem_id, category) {
  37. const { ctx } = this;
  38.  
  39. console.log('从ctx.locals中取openid');
  40. console.log(ctx.locals.openid);
  41. const openid = ctx.locals.openid;
  42.  
  43. // 将用户信息记录到数据库中
  44. const res = await ctx.model.Record.create({
  45. record_name: record_name,
  46. record_url: url,
  47. poem_id: poem_id,
  48. category: category,
  49. openid: openid,
  50. });
  51. }
  52. }
  53. module.exports = RecordService;

这里需要注意的是:

  • 需要注册阿里云账号,并在对象存储那里新建一个存储桶用于存放音频,也就是云存储的实现。
  • 需要安装ali-ossnpm包,用于连接阿里云对象存储。在后台接收到前端上传的临时文件后,就会将音频上传至阿里云对象存储中(client.put)。

播放录音

细心的小伙伴可以注意到在使用Taro.uploadFile接口上传录音后,在success回调中调用了playAudio函数用于播放音频,接下来讲一下播放音频是如何实现的。

首先,使用Taro.createInnerAudioContext获取audio的上下文对象:

  1. const innerAudioText = Taro.createInnerAudioContext();

和录音一样,在组件挂载完成时,注册监听事件:

  1. useEffect(() => {
  2. innerAudioText.onPlay(() => {
  3. console.log('开始播放');
  4. });
  5.  
  6. innerAudioText.onError((e) => {
  7. console.log('播放异常');
  8. console.log(e);
  9. });
  10. }, []);
  11.  

在录音文件上传成功后,调用playAudio方法用于播放录音:

  1. const playAudio = (url) => {
  2. innerAudioText.autoplay = true;
  3. innerAudioText.src = url;
  4. };

在src被赋予值的时候,录音就会开始播放。

总结

到此这篇关于小程序录音功能实现的文章就介绍到这了,更多相关小程序 录音内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号