Mini Program Recording Function Implementation

Mini Program Recording Function Implementation

Preface

In the process of developing a mini program, there is a need to implement a recording function, play the recording, and upload the recording to a server. The Taro framework was used during the development process. The recording function is implemented through the Taro.getRecorderManager() interface, uploading the recording to the server is implemented through the Taro.uploadFile interface, and playing the recording is implemented using the Taro.createInnerAudioContext() interface. The following is a detailed introduction on how the whole process is implemented.

Mini Program Recording

First get the recording manager module:

const recorderManager = Taro.getRecorderManager();

Register the recording monitoring event when the component is mounted:

useEffect(() => {
 // Listen for recording start recorderManager.onStart(() => {
   console.log('Start recording');
  });
 // Monitor recording pause recorderManager.onPause(() => {
   console.log('Pause recording');
  });
 // Listen for recording to continue recorderManager.onResume(() => {
   console.log('Continue recording');
  });
 // Monitor recording stop recorderManager.onStop((res) => {
   if (res.duration < 1000) {
    Taro.showToast({
     title: 'Recording time is too short',
     duration: 1000,
     icon: 'none',
    });
   } else {
    console.log('stop recording');
    fileUpload(res.tempFilePath);
   }
  });

  recorderManager.onError(() => {
   Taro.showToast({
    title: 'Recording failed! ',
    duration: 1000,
    icon: 'none',
   });
  });
 }, []);

In the callback function of recording onStop, we can get the temporary address of the recording res.tempFilePath, but this address has an expiration date, so we need to upload the recording to the server backend and save it before it can be used normally later.

In the onStop callback function, we call the fileUpload function to upload the file. The implementation of the fileUpload function is as follows:

const fileUpload = (tempFilePath) => {
  Taro.uploadFile({
   url: 'http://127.0.0.1:7001/record', // Server address filePath: tempFilePath,
   name: 'file', // This can be filled in at will header: {
    'content-type': 'multipart/form-data', // The format must be this Authorization: Taro.getStorageSync('token'),
   },
   // formData is used to transmit some information other than files formData: {
    record_name: 'Recitation Works',
    poem_id: poemInfo.id,
    category: poemInfo.category,
   },
   success: (res) => {
    console.log(res);
    const url = res.data;
    playAudio(url); // play recording},
   fail: (error) => {
    console.log('failed!');
    console.error(error);
   },
  });
 };

Points to note are: the content-type in the header must be multipart/form-data.

Recording event processing

The first click of handleClick will trigger the start of recording, and then the current state will be used to determine whether to pause or continue recording. handleComplete is used to stop recording.

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: 'Start recording',
    duration: 1000,
    icon: 'none',
   });

  } else {
   if (curPause) {
    recorderManager.pause(); // Pause recording } else {
    recorderManager.resume(); //Continue recording}
  }
 };

 const handleComplete = () => {
  recorderManager.stop(); // Stop recording};

The background realizes recording storage and returns the recording address

Most blogs on the Internet do not cover this content. Here I will introduce how to implement it. The background framework I use is Alibaba's egg.js.

For the configuration required for file upload, please refer to the official document: egg.js file upload. Here we use its first File mode to implement it.

Because the egg.js framework has a built-in Multipart plug-in, it can parse uploaded multipart/form-data type data.

First, write the multipart configuration in the configuration file config.default.js:

module.exports = (app) => {
 const config = (exports = {});
 
 ...

 config.multipart = {
  mode: 'file',
  fileSize: '50mb',
 }
 ...

 return {
  ...config,
  ...userConfig,
 };
};

Then, define the routes in router.js:

// Submit recording router.post('/record', auth, controller.record.postRecord);

Define the record.js file in the controller directory and write the following content:
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;

Define record.js in the service directory and write the specific implementation:

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', // Fill in Alibaba Cloud's accessKeyId
 accessKeySecret: 'xxx', // Fill in Alibaba Cloud's 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 {
   // Process files, such as uploading to the cloud result = await client.put(file.filename, file.filepath);
  finally
   // Need to delete temporary files await ctx.cleanupRequestFiles();
  }
  return result.url;
 }

 async updateRecord(url, record_name, poem_id, category) {
  const { ctx } = this;

  console.log('Get openid from ctx.locals');
  console.log(ctx.locals.openid);
  const openid = ctx.locals.openid;

  // Record user information into the database 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;

It is important to note that:

  • You need to register an Alibaba Cloud account and create a new bucket in the object storage to store audio, which is the implementation of cloud storage.
  • You need to install the ali-ossnpm package to connect to Alibaba Cloud Object Storage. After receiving the temporary file uploaded by the front end, the background will upload the audio to Alibaba Cloud Object Storage (client.put).

Play Recording

Careful friends may notice that after uploading the recording using the Taro.uploadFile interface, the playAudio function is called in the success callback to play the audio. Next, let's talk about how to play the audio.

First, use Taro.createInnerAudioContext to get the audio context object:

const innerAudioText = Taro.createInnerAudioContext();

Just like recording, register a listener event when the component is mounted:

useEffect(() => {
  innerAudioText.onPlay(() => {
   console.log('Start playing');
  });

  innerAudioText.onError((e) => {
   console.log('Playback abnormality');
   console.log(e);
  });
 }, []);

After the recording file is uploaded successfully, call the playAudio method to play the recording:

const playAudio = (url) => {
 innerAudioText.autoplay = true;
 innerAudioText.src = url;
};

When src is assigned a value, the recording will start playing.

Summarize

This is the end of this article about the implementation of the mini-program recording function. For more relevant mini-program recording content, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Mini Program to implement recording function
  • WeChat applet recording function and upload (using node to parse and receive)
  • WeChat applet realizes recording function
  • The applet realizes voice recognition by pressing and releasing the recording button
  • The applet collects recordings and uploads them to the backend
  • Mini Program implements recording upload function
  • WeChat applet to achieve microphone animation effect when recording
  • WeChat applet recording and playback recording function
  • WeChat applet development recorder audio playback animation example (real machine available)
  • WeChat applet - pictures, recordings, audio playback, music playback, videos, files code examples

<<:  Complete steps to build NFS file sharing storage service in CentOS 7

>>:  How to allow all hosts to access mysql

Recommend

Tutorial diagram of installing CentOS and Qt in Vmware virtual machine

Vmware Installation Installing Packages Download ...

Summary of Docker common commands and tips

Installation Script Ubuntu / CentOS There seems t...

MySQL incremental backup and breakpoint recovery script example

Introduction Incremental backup means that after ...

Solution to VMware virtual machine no network

Table of contents 1. Problem Description 2. Probl...

MySQL database rename fast and safe method (3 kinds)

Table of contents How to rename MySQL database Th...

MySQL 8.0.18 stable version released! Hash Join is here as expected

MySQL 8.0.18 stable version (GA) was officially r...

Example of how to identify the user using a linux Bash script

It is often necessary to run commands with sudo i...

Docker's flexible implementation of building a PHP environment

Use Docker to build a flexible online PHP environ...

Three ways to achieve background blur in CSS3 (summary)

1. Normal background blur Code: <Style> htm...

Call and execute host docker operations in docker container

First of all, this post is dedicated to Docker no...

Mysql master-slave synchronization configuration scheme under Centos7 system

Preface Recently, when working on a high-availabi...

Nginx/Httpd reverse proxy tomcat configuration tutorial

In the previous blog, we learned about the usage ...

PNG Alpha Transparency in IE6 (Complete Collection)

Many people say that IE6 does not support PNG tra...

Detailed explanation of the pitfalls of mixing MySQL order by and limit

In MySQL, we often use order by for sorting and l...