微信小程序拖动按帧裁剪视频
时间: 2023-07-26 21:44:13 浏览: 305
微信小程序拖动按帧裁剪视频的具体实现方法如下:
1. 在 wxml 文件中添加 video 组件、两个按钮和一个 canvas 组件,用于渲染拖动进度条。
```
<video id="myVideo" src="{{src}}" controls></video>
<button type="primary" bindtap="startCutting">开始裁剪</button>
<button type="primary" bindtap="endCutting">结束裁剪</button>
<canvas id="progressCanvas"></canvas>
```
2. 在 js 文件中监听视频播放事件和按钮的点击事件,并在开始裁剪时记录当前时间,结束裁剪时计算裁剪后的时长。
```
data: {
src: '', // 视频地址
ctx: null, // video 组件的上下文
duration: 0, // 视频总时长
startTime: 0, // 裁剪开始时间
endTime: 0, // 裁剪结束时间
progressWidth: 0, // 进度条宽度
progressHeight: 0, // 进度条高度
progressLeft: 0 // 进度条左边距
},
onLoad() {
this.ctx = wx.createVideoContext('myVideo', this);
},
onReady() {
this.ctx.pause(); // 加载后暂停播放
this.ctx.duration((res) => {
this.duration = res.duration;
});
},
onPlay() {
this.drawProgress(); // 每次播放时绘制进度条
},
startCutting() {
this.ctx.play(); // 开始播放
this.startTime = this.ctx.currentTime; // 记录开始时间
},
endCutting() {
this.ctx.pause(); // 暂停播放
this.endTime = this.ctx.currentTime; // 记录结束时间
const cutDuration = this.endTime - this.startTime; // 计算裁剪后的时长
console.log(`裁剪后的时长为 ${cutDuration}`);
},
drawProgress() {
const query = wx.createSelectorQuery();
query.select('#progressCanvas').boundingClientRect((rect) => {
const canvasWidth = rect.width;
const canvasHeight = rect.height;
const progressWidth = canvasWidth * this.ctx.currentTime / this.duration; // 计算进度条宽度
const progressHeight = canvasHeight;
const progressLeft = 0;
const ctx = wx.createCanvasContext('progressCanvas', this);
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // 清空画布
ctx.setFillStyle('#f00');
ctx.fillRect(progressLeft, 0, progressWidth, progressHeight);
ctx.draw();
this.progressWidth = progressWidth;
this.progressHeight = progressHeight;
this.progressLeft = progressLeft;
}).exec();
}
```
3. 在 wxss 文件中设置 canvas 的样式。
```
canvas {
width: 100%;
height: 20rpx;
background-color: #eee;
}
```
4. 在 canvas 组件上绑定 touchstart、touchmove 和 touchend 事件,实现拖动进度条的功能。
```
onProgressTouchStart(e) {
const touch = e.touches[0];
this.progressTouchStartX = touch.clientX;
this.progressTouchStartLeft = this.progressLeft;
},
onProgressTouchMove(e) {
const touch = e.touches[0];
const distanceX = touch.clientX - this.progressTouchStartX;
const progressLeft = this.progressTouchStartLeft + distanceX;
if (progressLeft < 0) {
this.progressLeft = 0;
} else if (progressLeft > this.progressWidth) {
this.progressLeft = this.progressWidth;
} else {
this.progressLeft = progressLeft;
}
this.updateProgress();
},
onProgressTouchEnd(e) {
this.ctx.seek(this.duration * this.progressLeft / this.progressWidth); // 根据进度条位置跳转视频播放进度
},
updateProgress() {
const ctx = wx.createCanvasContext('progressCanvas', this);
ctx.clearRect(0, 0, this.progressWidth, this.progressHeight); // 清空画布
ctx.setFillStyle('#f00');
ctx.fillRect(this.progressLeft, 0, this.progressWidth - this.progressLeft, this.progressHeight);
ctx.draw(true);
}
```
注意:拖动进度条时需要记录开始触摸时的位置和进度条的左边距,然后根据移动距离计算进度条的位置,最后根据进度条位置跳转视频播放进度。由于视频播放的精度可能不够,裁剪时可能会有一些误差。如果需要更精确的裁剪,可以使用一些第三方的视频处理库。
阅读全文