video.js 添加截图功能
scrollLock() {
const fileName = `${new Date().getTime()}.png`;
let fileType = "png";
switch (fileName) {
case fileName.indexOf("png") > -1:
fileType = "png";
break;
case fileName.indexOf("jpg") > -1:
fileType = "jpg";
break;
case fileName.indexOf("jpeg") > -1:
fileType = "jpeg";
break;
case fileName.indexOf("bmp") > -1:
fileType = "bmp";
break;
case fileName.indexOf("gif") > -1:
fileType = "gif";
break;
default:
fileType = "png";
break;
}
const video = this.player.el().querySelector('video');
const canvas = window.canvas = document.createElement("canvas");
canvas.width = video.offsetWidth;
canvas.height = video.offsetHeight;
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
const strDataURL = canvas.toDataURL("image/" + fileType);
const arr = strDataURL.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = window.atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
const blob = new Blob([u8arr], {
type: mime
});
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 1000);
}
initPlayer() {
videojs.addLanguage('zh-CN',
{
"Play": "播放",
"Pause": "暂停",
"Current Time": "当前时间",
"Duration": "时长",
"Remaining Time": "剩余时间",
"Stream Type": "媒体流类型",
"LIVE": "直播",
"Loaded": "加载完成",
"Progress": "进度",
"Fullscreen": "全屏",
"Non-Fullscreen": "退出全屏",
"Picture-in-Picture": "画中画",
"Exit Picture-in-Picture": "退出画中画",
"Mute": "静音",
"Unmute": "取消静音",
"Playback Rate": "播放速度",
"Subtitles": "字幕",
"subtitles off": "关闭字幕",
"Captions": "内嵌字幕",
"captions off": "关闭内嵌字幕",
"Chapters": "节目段落",
"Close Modal Dialog": "关闭弹窗",
"Descriptions": "描述",
"descriptions off": "关闭描述",
"Audio Track": "音轨",
"You aborted the media playback": "视频播放被终止",
"A network error caused the media download to fail part-way.": "网络错误导致视频下载中途失败。",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "视频因格式不支持或者服务器或网络的问题无法加载。",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "由于视频文件损坏或是该视频使用了你的浏览器不支持的功能,播放终止。",
"No compatible source was found for this media.": "无法找到此视频兼容的源。",
"The media is encrypted and we do not have the keys to decrypt it.": "视频已加密,无法解密。",
"Play Video": "播放视频",
"Close": "关闭",
"Modal Window": "弹窗",
"This is a modal window": "这是一个弹窗",
"This modal can be closed by pressing the Escape key or activating the close button.": "可以按ESC按键或启用关闭按钮来关闭此弹窗。",
", opens captions settings dialog": ", 开启标题设置弹窗",
", opens subtitles settings dialog": ", 开启字幕设置弹窗",
", opens descriptions settings dialog": ", 开启描述设置弹窗",
", selected": ", 选择",
"captions settings": "字幕设定",
"Audio Player": "音频播放器",
"Video Player": "视频播放器",
"Replay": "重新播放",
"Progress Bar": "进度条",
"Volume Level": "音量",
"subtitles settings": "字幕设定",
"descriptions settings": "描述设定",
"Text": "文字",
"White": "白",
"Black": "黑",
"Red": "红",
"Green": "绿",
"Blue": "蓝",
"Yellow": "黄",
"Magenta": "紫红",
"Cyan": "青",
"Background": "背景",
"Window": "窗口",
"Transparent": "透明",
"Semi-Transparent": "半透明",
"Opaque": "不透明",
"Font Size": "字体尺寸",
"Text Edge Style": "字体边缘样式",
"None": "无",
"Raised": "浮雕",
"Depressed": "压低",
"Uniform": "均匀",
"Dropshadow": "下阴影",
"Font Family": "字体库",
"Proportional Sans-Serif": "比例无细体",
"Monospace Sans-Serif": "单间隔无细体",
"Proportional Serif": "比例细体",
"Monospace Serif": "单间隔细体",
"Casual": "舒适",
"Script": "手写体",
"Small Caps": "小型大写字体",
"Reset": "重置",
"restore all settings to the default values": "恢复全部设定至预设值",
"Done": "完成",
"Caption Settings Dialog": "字幕设定窗口",
"Beginning of dialog window. Escape will cancel and close the window.": "打开对话窗口。Escape键将取消并关闭对话窗口",
"End of dialog window.": "结束对话窗口",
"Seek to live, currently behind live": "尝试直播,当前为延时播放",
"Seek to live, currently playing live": "尝试直播,当前为实时播放",
"progress bar timing: currentTime={1} duration={2}": "{1}/{2}",
"{1} is loading.": "正在加载 {1}。"
});
const _this = this;
this.$nextTick(() => {
const parentVideo = document.getElementById(_this.setId);
const imgEle = document.createElement('img');
imgEle.src = require('@/assets/zixing/scrollL.png');
imgEle.style.width = '20px';
imgEle.style.position = 'absolute';
imgEle.style.top = '50%';
imgEle.style.transform = 'translate(0, -50%)';
imgEle.style.right = '0%';
imgEle.style.cursor = 'pointer';
imgEle.style.zIndex = '1';
imgEle.style.opacity = '0.5';
imgEle.addEventListener('click', function() {
_this.scrollLock();
});
imgEle.addEventListener('mouseenter', function(e) {
this.style.opacity = 1;
});
imgEle.addEventListener('mouseleave', function(e) {
this.style.opacity = 0.5;
})
parentVideo.appendChild(imgEle);
})
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构