preface
During the development of the applets, there was a requirement to implement the recording function, play the recording, and upload the recording to the server. Taro framework is used in the development process, recording function is realized through Taro. GetRecorderManager () interface, upload recording to server through Taro. UploadFile interface. Play the tape use Taro. CreateInnerAudioContext () interface implementation. Here’s how the whole process is implemented in detail.
Applet recording
First get the recording Manager module:
const recorderManager = Taro.getRecorderManager();
Copy the code
Register a recording listening event when the component is mounted:
useEffect(() = > {
// Listen for the recording
recorderManager.onStart(() = > {
console.log('Start recording');
});
// Listen recording paused
recorderManager.onPause(() = > {
console.log('Pause recording');
});
// Listen to the recording continue
recorderManager.onResume(() = > {
console.log('Continue recording');
});
// Stop listening
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'}); }); } []);Copy the code
In the callback function of recording onStop, we can obtain the temporary address of recording res.tempFilepath, but this address has an expiry date, so we need to upload the recording to the server background, save it, and then use it normally.
In the onStop callback function, fileUpload is called to upload files. The implementation of fileUpload is as follows:
const fileUpload = (tempFilePath) = > {
Taro.uploadFile({
url: 'http://127.0.0.1:7001/record'.// Server address
filePath: tempFilePath,
name: 'file'.// Fill this in freely
header: {
'content-type': 'multipart/form-data'.// The format must be this
Authorization: Taro.getStorageSync('token'),},// formData is used to transfer information other than files
formData: {
record_name: 'Spoken work'.poem_id: poemInfo.id,
category: poemInfo.category,
},
success: (res) = > {
console.log(res);
const url = res.data;
playAudio(url); // Play the recording
},
fail: (error) = > {
console.log('failed! ');
console.error(error); }}); };Copy the code
Note that the content-type in the header must be multipart/form-data.
Handling recording events
Clicking handleClick for the first time triggers the recording to begin, which is then used to determine whether to pause or resume recording. HandleComplete is used to stop recording.
const handleClick = () = > {
constcurPause = 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 the recording
} else {
recorderManager.resume(); // Continue recording}}};const handleComplete = () = > {
recorderManager.stop(); // Stop recording
};
Copy the code
The background realizes recording storage and returns recording address
Most blogs on the Internet are not involved in this content, the following is to introduce how to achieve the background framework I use Ali’s egg.js.
File uploads require configuration of something visible in the official documentation: egg.js file uploads. We use its first File mode here.
Because the Multipart plug-in is built into the egg.js framework, it can parse uploaded Multipart /form-data data.
First, now write the multipart configuration to the config file config.default.js:
module.exports = (app) = > {
const config = (exports= {}); . config.multipart = {mode: 'file'.fileSize: '50mb',}...return{... config, ... userConfig, }; };Copy the code
Then, define the route in router.js:
// Submit the recording
router.post('/record', auth, controller.record.postRecord);
Copy the code
Define the record.js file in the Controller directory and write the following:
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 = awaitctx.service.record.postRecord(file, record_name, poem_id, category); ctx.body = res; }}module.exports = RecordController;
Copy the code
Define record.js in the service directory and write the concrete 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'.// Enter the accessKeyId of Ali Cloud
accessKeySecret: 'xxx'.// Add accessKeySecret to aliyun
};
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 {
// Temporary files need to be deleted
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 to 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;
Copy the code
Here are some things to note:
- You need to register an Ali Cloud account, and create a bucket for storing audio in the object storage, which is the implementation of cloud storage.
- You need to install
ali-oss
NPM package, used to connect ali Cloud object storage. After receiving the temporary file uploaded by the front-end, the background will upload the audio to aliyun object storage (client.put
).
Play the tape
UploadFile (tarono. uploadFile); playAudio (tarono. uploadFile); playAudio (tarono. uploadFile);
First, use Taro. CreateInnerAudioContext for audio context object:
const innerAudioText = Taro.createInnerAudioContext();
Copy the code
As with recording, register listening events when the component is mounted:
useEffect(() = > {
innerAudioText.onPlay(() = > {
console.log('Start playing');
});
innerAudioText.onError((e) = > {
console.log('Playback exception');
console.log(e); }); } []);Copy the code
After the recording file is uploaded successfully, call the playAudio method to play the recording:
const playAudio = (url) = > {
innerAudioText.autoplay = true;
innerAudioText.src = url;
};
Copy the code
When SRC is assigned a value, the recording starts playing.
conclusion
The above is the whole recording function and recording playback function to achieve the whole process, if you have any questions, welcome to communicate with us.