实现video播放器截图并且在canvas上绘制矩形
只展示核心代码 安装 video-playe 全局引入 有可能代码复制不完全,逻辑不变
<div id="videoItem">
<video-player
class="video-player vjs-custom-skin tine-font-size"
ref="videoPlayer"
:playsinline="true"
:options="playerOptions"
id="video"
:crossOrigin="Anonymous"
:useCORS="true"
></video-player>
</div>
<div class="screenshotValue-item">
<div class="first" @click="btnScreenshot">截图</div>
<div class="firstTwo" @click="videoDialogFalse">取消</div>
</div>
<el-dialog
:visible.sync="showCutDialog"
v-if="showCutDialog"
:close-on-click-modal="false"
width="57%"
class="dialog-content"
height="800px"
title="截图绘制矩形"
id="dialog-content"
v-loading="videoLoading"
>
<div class="item-class-left">
<div style="position: relative;;"
id="icanvasImage"
>
<!-- 这里写一个img的原因是绘制矩形的时候会把当前canvas绘制的图片q清空 暂未找到更好的方法
-->
<img id="customPositionImg" ref="table" :src="listValue" height="400" width="700" crossOrigin="Anonymous"
/>
<canvas
ref="icanvas"
:width="canvasWidth"
:height="canvasHeight"
id="myCanvas"
class="item-color-font-size"
style="position: absolute;left:0;"
@mousedown="handlerMouseDown($event)"
@mousemove="handlerMouseMove($event)"
@contextmenu="contextmenu($event)"
@mouseup="handlerMouseUp($event)"
></canvas>
</div>
</div>
Anonymous:"Anonymous", // 实现跨越
showCutDialog:false,
listValue:null,
canvasWidth: 700, // canvas 初始化大小
canvasHeight: 400,
isMouseDown: false, // 判断鼠标是否按下 防止重复绘制
playerRef:null,
ctx:null,
tempImageCanvasList:[],
imageCanvas: new Image(), // 缓存当前初始截图
this.coordinate:{
X:null,
Y:null,
}
playerOptions: {
playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
autoplay: true, //如果true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 导致视频一结束就重新开始。
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: 'zh-CN',
aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
sources: [{
type: 'video/mp4' || 'video/ogg' || 'video/webm' || 'video/3gp',//这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目
// type: "video/ogg",
// type: "video/webm",
// type: "video/3gp",
// type: "video/avi",
// type: "video/mkv",
// type: "video/flv",
src: "" //url地址
}],
num:null,
crossOrigin:"Anonymous",
poster: '', //你的封面地址
// width: document.documentElement.clientWidth, //播放器宽度
notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true,
durationDisplay: true,
remainingTimeDisplay: false,
fullscreenToggle: true //全屏按钮
}
}
mounted
this.nextTick(_=>{
this.playerRef = this.$refs.videoPlayer
})
methods
btnScreenshot(){
this.playerRef.player.pause(); // 截图的时候暂停视频播放
this.$nextTick(() => {
this.tempImageCanvasList = [];
this.showCutDialog = true;
this.getCanvasImage();
});
}
getCanvasImage(){
this.$nextTick((_) => {
if (this.playerRef) {
const canvasEl = document.getElementById('myCanvas')
const videoEl = this.playerRef.$refs.video;
this.ctx = canvasEl.getContext("2d");
const img = new Image();
let that = this
let videoList = document.querySelector('video')
console.log(videoList);
videoList.useCORS= true
videoEl.setAttribute("crossOrigin",'Anonymous')
that.ctx.drawImage(videoList, 0, 0, 700, 400);
let tempImage = canvasEl.toDataURL('image/jpeg')
console.log(tempImage);
// 这里的意思是如果有清空操作 将当前的 tempImage 绘制给canvas重新绘制
this.imageCanvas.src = tempImage;
this.listValue = tempImage
this.tempImageCanvasList.push(tempImage);
}
})
},
handlerMouseDown(e){
console.log('handlerMouseDown',e);
this.isMouseDown = true;
// 记录鼠标点下的开始坐标
//如要保存 定义变量赋值即可
console.log(e.offsetX, e.offsetY;)
this.coordinate.X = e.offsetX;
this.coordinate.Y = e.offsetY;
},
handlerMouseUp(e) {
this.isMouseDown = false;
// 这里会拿到结束坐标 width 结束坐标的X轴 - 开始坐标的X轴 height 结束坐标的Y轴 - 开始坐标的Y轴
console.log(e.offsetX, e.offsetY;)
},
handlerMouseMove(e) {
if (this.isMouseDown) { // 判断重复点击
const {
X, Y,
} = this.coordinate;
const canvasEl = this.$refs.icanvas;
this.ctx = canvasEl.getContext('2d');
// const canvas = document.getElementById('myCanvas')
// 这里清楚会清除当前的背景图
this.ctx.clearRect(0,0,canvasEl.width,canvasEl.height); //
this.ctx.beginPath();
//设置线条颜色,必须放在绘制之前
this.ctx.strokeStyle = 'red';
// 线宽设置,必须放在绘制之前
this.ctx.lineWidth = 4;
// 进行矩形绘制(矩形左上角的 x 坐标,矩形左上角的 y 坐标,矩形的宽度,矩形的高度)
// 绘制
this.ctx.strokeRect(X,Y,e.offsetX-X,e.offsetY -Y);
}
},