微信小程序开发之——仿微信视频录制上传

一 仿微信视频录制效果

二 业务说明

  1. 视频录制前,只显示取消和视频录制按钮
  2. 录制开始后,只显示视频录制按钮,并且上方显示时间、录制按钮显示录制进度
  3. 录制完成后,显示重拍、取消、上传按钮
  4. 录制完成后,点击按钮,可预览录制视频
  5. 点击重拍,录制视频消失,显示相机预览画面
  6. 点击取消,返回上一个界面
  7. 点击上传,将视频上传

三 可能遇到的问题(显示录制倒计时和录制进度)

3.1 布局文件(canvas绘制)

 <!--底部布局-中间部分-canvas绘制-->
 <view>
    <text class="delay-time" hidden="{{!isRecord||isFinish}}">{{timeDelay}}</text>
    <view class="container-record" style="width: 200rpx;height: 200rpx;">
    <view class='video-button-container' bindlongpress="startRecordLong" bindtouchend="bindtouchend" hidden="{{!initState||isFinish}}">
    <canvas canvas-id="circleOuterLayer" style="position: absolute;margin: auto 0;width: 200rpx;height: 200rpx;"></canvas>
    <canvas canvas-id="circleInnerLayer" style="position: absolute;margin: auto 0;width: 200rpx;height: 200rpx;" hidden="{{isRecord||(!isRecord&&isFinish)}}"> </canvas>
    <canvas canvas-id="circleRectLayer" style="position: absolute;margin: auto 0;width: 200rpx;height: 200rpx;" hidden="{{!isRecord}}"> </canvas>
     <canvas canvas-id="circleProgressLayer" style="position: absolute;margin: auto 0;width: 200rpx;height: 200rpx;"> </canvas>
     </view>
    </view>
</view>

3.2 样式文件

.container-camera {
  width: 100%;
  height: 100%;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;

}

/**相机布局 */
.container-camera camera {
  width: 100vh;
  height: 100vh;

}

/**视频回放布局 */
.container-camera video {
  width: 100vh;
  height: 100vh;
}

.container-bottom {
  position: absolute;
  bottom: 40rpx;
  width: 90%;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  z-index: 100;
}

.retake {
  position: absolute;
  bottom: 220rpx;
  left: 20px;
  color: white;
  background: #7E91AD;
  padding: 20rpx 50rpx;
  border-radius: 20rpx;

}

.container-bottom-left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
}

.container-bottom-left view {
  background: #7E91AD;
  padding: 20rpx 50rpx;
  border-radius: 20rpx;
  color: white;

}

.container-bottom-left view:first-child {
  margin-bottom: 20rpx;
  /* margin-top: -60rpx; */
  /* position: absolute;
  margin-bottom: 140rpx; */
}

.container-bottom-right {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
}

.container-bottom-right view {
  background: #377EF0;
  padding: 20rpx 50rpx;
  border-radius: 20rpx;
  color: white;
}


/**最外层布局 */
.container-record {

  width: 200rpx;
  height: 200rpx;

}

.video-button-container {
  width: 200rpx;
  height: 200rpx;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;

}

3.3 逻辑文件

  /**
   * 页面的初始数据
   */
  data: {
    position: 'back', //摄像头的位置,有前置和后置
    timeDelay: "15秒", //视频最大时长
    countTimer: null, // 设置 定时器 初始为null
    intervalNum: 15, //视频最大时长倒计时
    initState: true, //初始化状态
    isRecord: false, //是否正在录制
    isFinish: false, //是否录制完成
    startRecord: false, //是否开始录像,控制录像的默认状态,
    videoSrc: '' //录像文件的位置
  },
  
/**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

    //1-内层实体圆-白色-默认状态显示
    var circleInnerCtx = wx.createCanvasContext('circleInnerLayer')

    // 绘制图形
    circleInnerCtx.arc(50, 50, 30, 0, 2 * Math.PI)
    circleInnerCtx.setFillStyle('#EEEEEE')
    circleInnerCtx.fill()
    circleInnerCtx.draw()

    //2-外层圆圈-白色-默认状态显示
    var circleOuterCtx = wx.createCanvasContext('circleOuterLayer')

    // 绘制图形
    circleOuterCtx.arc(50, 50, 40, 0, 2 * Math.PI)
    circleOuterCtx.setStrokeStyle('#EEEEEE')
    circleOuterCtx.setLineWidth(5)
    circleOuterCtx.stroke()
    circleOuterCtx.draw()

    //3-正方形-红色-录制视频时显示-与2不可能共存
    var context = wx.createCanvasContext('circleRectLayer')

    // context.fillRect(30, 30, 40, 40)
    const pi = Math.PI;
    const left = 30;
    const top = 30;
    const r = 10;
    const width = 40;
    const height = 40;
    context.beginPath();
    context.arc(left + r, top + r, r, -pi, -pi / 2);
    context.arc(left + width - r, top + r, r, -pi / 2, 0);
    context.arc(left + width - r, top + height - r, r, 0, pi / 2);
    context.arc(left + r, top + height - r, r, pi / 2, pi);
    context.closePath();
    context.setFillStyle('red')
    context.fill()
    context.draw()
    //4-绘制圆
    //5-倒计时
  },
  
/**录制视频时,外圈显示录制进度 */
  recordingCanvas() {
    this.setData({
      isRecord: true,
    })
    // debugger
    var totalTime = this.data.intervalNum;

    this.data.countTimer = setInterval(() => {

      if (totalTime > 0) {
        //num++
        totalTime--;
        this.setData({
          timeDelay: totalTime + "秒"
        })

        //context.moveTo(0,0)
        //cxtProgress = wx.createCanvasContext('circleProgressLayer')
        // context.rotate(-1 / 2 * Math.PI / 180);
        cxtProgress.beginPath();
        cxtProgress.arc(50, 50, 40, -Math.PI / 2, 2 * Math.PI * ((15 - totalTime) / 15) - Math.PI / 2)
        //cxtProgress.arc(50, 50, 40, -1 / 2 * Math.PI, 3 / 2 * Math.PI * ((15 - totalTime) / 15))
        cxtProgress.setStrokeStyle('red')
        cxtProgress.setLineWidth(5)
        cxtProgress.stroke()
        cxtProgress.draw()
      } else {
        clearInterval(this.data.countTimer)
        this.bindtouchend();
      }
    }, 1000)
  },  
 bindtouchend(options) {
    console.log("--bindtouchend");
    if (this.data.isRecord) //已经开始录制视频时
    {
      clearInterval(this.data.countTimer) //清除计数器
      this.clearCanvasRect(); //清除Canvas绘制的内容
      this.stopRecord(); //停止录像
      this.setData({
        isFinish: true,
        isRecord: false
      })
    },
  //清除Canvas绘制的内容
  clearCanvasRect() {
    //清除画布上的所有内容
    cxtProgress.clearRect(0, 0, wx.getSystemInfoSync().windowWidth, wx.getSystemInfoSync().windowHeight)
    cxtProgress.draw()
  },    
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值