In my work, I need wechat mini program to record 15s videos and upload them. Some users feedback that they can’t record videos, so I would like to summarize my experience here
The picture below is a manifestation of the problem. When users of some models release the shooting, they are reminded that the shooting is not completed, so the video cannot be uploaded.
The problem above is use
wx.chooseVideo({
sourceType: ['camera'].maxDuration: 60.camera: 'back'.success(res) {
console.log(res.tempFilePath)
}
})
Copy the code
Wx. ChooseVideo is an official interface provided by wechat, which does not require user authorization and can be directly called to return the video address after shooting. However, the above problems may occur when some models use this interface, resulting in failure to complete shooting.
Solution: Use wx.createcameraconText () to define your own recording method.
Points to note:
- To use this method, you need to authorize camera and microphone permissions, and handle unauthorized situations
- The startRecord and stopRecord methods pay attention to the call timing. They cannot be called continuously, and need to deal with the user’s continuous click behavior
The code is as follows:
index.wxml
<view class="video">
<video wx:if="{{video}}" src="{{video}}" style="width: 100%; display: block;"></video>
<button type="primary" bindtap="checkSetting">Recording a Video Demo</button>
</view>
Copy the code
index.js
const app = getApp()
Page({
data: {
video: null
},
onShow() {
/** * Every time you enter the page to check whether there is a local video recording address, if there is, clear */
if (wx.getStorageSync('auth_video')) {
this.setData({
video: wx.getStorageSync('auth_video')
})
wx.removeStorageSync('auth_video')}},/** * Since the video page uses the camera label, the camera permission must be obtained when using this label, otherwise the picture cannot be captured * so every time you enter the page, check whether the user has authorized the camera permission */
checkSetting() {
wx.getSetting({
success: (res) = > {
console.log(res)
let authSetting = res.authSetting
/ * * * authSetting. HasOwnProperty (' scope. The camera ') = = true indicating the user is not authorized for the first time * authSetting [' scope. Camera] = = false shows that users are not allowed to authorize * You need to prompt the user to enable authorization */ only when both conditions are met
if (authSetting.hasOwnProperty('scope.camera') && !authSetting['scope.camera']) {
wx.showModal({
content: 'Detected that you are not currently enabled with camera permissions and will not be able to use camera functions'.confirmText: 'Go open'.success: (res) = > {
if (res.confirm) {
console.log('User hits OK')
wx.openSetting({
success(res) {
console.log(res.authSetting)
}
});
} else if (res.cancel) {
console.log('User hit Cancel')}}})}else {
wx.navigateTo({
url: ".. /camera/camera"})}}})Copy the code
camera.wxml
<view class="video">
<view wx:if="{{! video_url}}" style="position: relative;">
<cover-view class="time-container" wx:if="{{isRecording}}">
<cover-view class="time">Recording {{time}}s</cover-view>
</cover-view>
<cover-view class="change-btn" wx:else bindtap="changePosition">
<cover-view>Click toggle {{devicePosition=='front'? 'Back ':' front '}} camera</cover-view>
</cover-view>
<camera binderror="getError" device-position="{{devicePosition}}" style="width: 100vw; height: 100vh;"></camera>
<cover-view class="btn-container">
<cover-view class="btn-item" bindtap="back" style="background-color: #ddd;">return</cover-view>
<cover-view class="btn-item" bindtap="record">{{isRecording? 'End recording ':' Click record '}}</cover-view>
</cover-view>
</view>
<view wx:else style="position: fixed; width: 100vw; height: 100vh;">
<video src="{{video_url}}" style="width: 100%; height: 100%;" autoplay="{{true}}" loop="{{true}}" controls="{{false}}"></video>
<cover-view class="btn-container">
<cover-view class="btn-item" bindtap="recordAgain">re-recording</cover-view>
<cover-view class="btn-item" bindtap="sureVideo">Confirm the choice</cover-view>
</cover-view>
</view>
</view>
Copy the code
camera.wxss
.time-container{
position: absolute;
width: 100%;
left:0;
top: 0;
height: 240rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0.0.0.0.4);
z-index: 100;
}
.change-btn{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
height: 100rpx;
color: #fff;
font-size: 30rpx;
padding: 0 50rpx;
border-radius: 50rpx;
z-index: 100;
background-color: rgba(0.0.0.0.5);
}
.time{
font-size: 30rpx;
color: red;
padding: 0 20rpx;
margin-top: 30rpx;
}
.btn-container{
position: absolute;
width: 100%;
padding: 0 80rpx;
box-sizing: border-box;
bottom: 160rpx;
display: flex;
justify-content: space-between;
z-index: 100;
}
.btn-item{
padding: 30rpx 0;
border-radius: 45rpx;
background-color: #FF6685;
color: #fff;
font-size: 32rpx;
text-align: center;
width: 240rpx;
}
Copy the code
camera.js
const app = getApp()
Page({
data: {
ctx: null.isRecording: false.video_url: null.time: 0.min_time:5.// Minimum duration for recording a video
timer: null.devicePosition: "back".// Camera orientation
isStart:false.// Record the state when the user clicks start recording
isStop:false // Record the user click to end recording status
},
onLoad(options) {
const ctx = wx.createCameraContext()
this.setData({
ctx
})
},
onUnload() {
clearInterval(this.data.timer)
},
// Switch the front/rear camera
changePosition() {
this.setData({
devicePosition: this.data.devicePosition == 'back' ? 'front' : 'back'})},checkSetting() {
// Define a state isStart to record the user clicking to start recording, and restore the state after the startRecord interface request is successful
if(this.data.isStart){
return
}
this.data.isStart = true
/** * The wx.createcameracontext ().startRecord() method needs to obtain the user's microphone permission, otherwise it cannot be called and video cannot be recorded * so each time you enter the page, check whether the user has the microphone permission */
wx.getSetting({
success: (res) = > {
console.log(res)
let authSetting = res.authSetting
/** * The same principle as checking camera permissions */
if (authSetting.hasOwnProperty('scope.record') && !authSetting['scope.record']) {
wx.showModal({
content: 'Detected that you do not currently have microphone permission enabled and will not be able to record video'.confirmText: 'Go open'.success: (res) = > {
if (res.confirm) {
console.log('User hits OK')
wx.openSetting({
success(res) {
console.log(res.authSetting)
}
});
} else if (res.cancel) {
console.log('User hit Cancel')
// this.back()}}})}else {
this.startRecord()
}
}
})
},
// This method is triggered when the user clicks "Do not allow authorization" when entering the page for authorization. This method will be triggered every time after the user enters the page for authorization
getError() {
console.log("User is not authorized to use the camera.")
this.back()
},
// Click start recording/end recording
record() {
if (this.data.isRecording) {
console.log("End of recording video")
this.stopRecord()
} else {
console.log("Start recording video")
this.checkSetting()
}
},
// Start recording
startRecord() {
this.data.ctx.startRecord({
timeoutCallback: (res) = > {
/** * wechat official limit * Use this method to record a video maximum of 30 seconds, after 30 seconds automatically stop recording * stop recording timing */
console.log("Automatically stop recording after 30 seconds.")
console.log(res)
clearInterval(this.data.timer)
this.setData({
video_url: res.tempVideoPath,
isRecording: false})},success: (res) = > {
console.log(res)
this.timing()
this.setData({
isRecording: true
})
this.data.isStart = false
},
fail:(err) = >{
console.log(err)
this.data.isStart = false}})},// End recording
stopRecord() {
// The stopRecord method cannot be called consecutively, otherwise recording cannot be stopped
// Define a state isStop to record the user click to end the recording behavior, and restore the state after the stopRecord interface request is successful
if(this.data.isStop){
return
}
if(this.data.time<this.data.min_time){
wx.showToast({
title:"Video duration less than"+this.data.min_time+"Seconds".icon:"none"
})
return
}
wx.showLoading({
title:"One moment, please."
})
this.data.isStop = true
this.data.ctx.stopRecord({
//compressed: false, // Whether to compress the finished video
success: (res) = > {
console.log(res)
clearInterval(this.data.timer)
this.setData({
video_url: res.tempVideoPath,
isRecording: false
})
this.data.isStop = false
wx.hideLoading()
},
fail(err){
console.log(err)
this.data.isStop = false
wx.hideLoading()
}
})
},
/ / timing
timing() {
let time = 0
// Reset the time on the page to 0 before each time
this.setData({
time
})
let self = this
let timer = setInterval(function() {
time++
console.log(time)
self.setData({
time
})
}, 1000)
this.setData({
timer
})
},
// Re-record
recordAgain() {
this.setData({
video_url: null})},// return to the previous page
back() {
wx.navigateBack()
},
// Confirm the selection
sureVideo() {
/** * Save the address of the recorded video locally, return to the previous page in the onShow to check whether the address of the recorded video exists */
wx.setStorageSync('auth_video'.this.data.video_url)
wx.navigateBack()
}
})
Copy the code
Effect: