总结video.js的使用
video.js引入
<link href="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.21.1/video-js.min.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/8.21.1/video.min.js"></script>
简单使用
<video id="ctyunplayer-container" class="video-js" :width="props.width" :height="props.height" controls="true"><source :src="videoConfig.value.videoUrl" type="application/x-mpegURL"></video>
多个用视频使用同一个播放器推荐使用以下富文本方式播放
<div v-html="idVideoShowUrl" :style="`position:relative;width:${props.width}px;height:${props.height}px`"></div> idVideoShowUrl.value = '<video id="ctyunplayer-container" class="video-js" key='+videoConfig.value.videoUrl + Math.random()+' width='+ props.width +' height='+ props.height +' controls="true"><source src='+videoConfig.value.videoUrl+' type="application/x-mpegURL"></video>'
初始化播放器
ctPlayer.value = videojs('ctyunplayer-container', { // language: 'zh-CN', autoplay: false, //是否自动播放 loop: false, //是否循环播放 controls: true, //控制器 controlBar: { // 设置控制条组件 playbackRateMenuButton: true } });
常用配置如下
autoplay: false, //自动播放:true/false controls: true, //是否显示底部控制栏:true/false width: 300, //视频播放器显示的宽度 height: 300, //视频播放器显示的高度 loop: false, //是否循环播放:true/false muted: false, //设置默认播放音频:true/false poster:"", //视频开始播放前显示的图像的URL。这通常是一个帧的视频或自定义标题屏幕。一旦用户点击“播放”图像就会消失 src:"", //要嵌入的视频资源url,The source URL to a video source to embed. techOrder: ['html5', 'flash'], //使用播放器的顺序,下面的示例说明优先使用html5播放器,如果不支持将使用flash notSupportedMessage: false, //是否允许重写默认的消息显示出来时,video.js无法播放媒体源 plugins: {}, //插件 sources: [{src: '//path/to/video.mp4', type: 'video/mp4'}] //资源文件等价于html中的形式source标签 aspectRatio:"1:1" //将播放器置于流体模式下,计算播放器动态大小时使用该值。 //该值应该是比用冒号隔开的两个数字(如“16:9”或“4:3”)。 fluid: false, //是否自适应布局,播放器将会有流体体积。换句话说,它将缩放以适应容器。 // 如果<video>标签有“vjs-fluid”样式时,这个选项会自动设置为true。 preload: "metadata", //建议浏览器是否在加载<video>元素时开始下载视频数据。(预加载) //auto:立即加载视频(如果浏览器支持它)。一些移动设备将不会预加载视频,以保护用户的带宽/数据使用率。这就是为什么这个值被称为“自动”,而不是更确凿的东西 // metadata:只加载视频的元数据,其中包括视频的持续时间和尺寸等信息。有时,元数据会通过下载几帧视频来加载。
controls的基本配置
controlBar : {
playToggle: true, // 播放暂停按钮
volumePanel: true,
currentTimeDisplay: true,
timeDivider: true,
durationDisplay: true,
progressControl: true,
liveDisplay: true,
seekToLive: true,
remainingTimeDisplay: true,
customControlSpacer: true,
playbackRateMenuButton: [0.5, 1, 1.5, 2],
chaptersButton: true,
descriptionsButton: true,
subsCapsButton: true,
audioTrackButton: true,
fullscreenToggle: true
}
如果用上面的配置,那顺序都是 videojs 自动安排的,如果还想定义控件顺序,比如进度条在最前面,播放暂停按钮在进度条后面,可以写 children 配置,显示按 children 的配置走。
var controlBar = { children: [ { name: 'progressControl' }, { name: 'playToggle' }, { name: 'playbackRateMenuButton', playbackRates: [0.5, 1, 1.5, 2] } ] }
自定义插件配置
var myPlayer = videojs('player', { controlBar: { children: [] } }, function() { var progressControl = videojs.getComponent('progressControl') // 获取进度条控件 videojs.registerComponent('progressControl', progressControl) //注册该组件 // 找到 controlBar 节点,添加控件 myPlayer.getChild('controlBar').addChild('progressControl') })
自定义新的控件

var myPlayer = videojs('player', { controlBar: { children: [] } }, function() { var baseComponent = videojs.getComponent('Component') var myComponent = videojs.extend(baseComponent, { constructor: function(player, options) { baseComponent.apply(this, arguments) this.on('click', this.clickIcon) }, createEl: function() { var divObj = videojs.dom.createEl('div', { // Prefixing classes of elements within a player with "vjs-" // is a convention used in Video.js. // 给元素加vjs-开头的样式名,是videojs内置样式约定俗成的做法 className: 'vjs-my-components', innerHTML: '<img style="width:30px;height:30px;" src="https://gitee.com/Jioho/img/raw/master/ficusjs/20210509183431.jpg" />' }) return divObj }, clickIcon: function() { alert('你点击了图片') } }) videojs.registerComponent('myComponent', myComponent) // 找到 controlBar 节点,添加控件 myPlayer.getChild('controlBar').addChild('myComponent') })
视频常用事件
// var myPlayer = this; //在回调函数中,this代表当前播放器, //可以调用方法,也可以绑定事件。 /** * 事件events 绑定事件用on 移除事件用off */ this.on('suspend', function () {//延迟下载 console.log("延迟下载") }); this.on('loadstart', function () { //客户端开始请求数据 console.log("客户端开始请求数据") }); this.on('progress', function () {//客户端正在请求数据 console.log("客户端正在请求数据") }); this.on('abort', function () {//客户端主动终止下载(不是因为错误引起) console.log("客户端主动终止下载") }); this.on('error', function () {//请求数据时遇到错误 console.log("请求数据时遇到错误") }); this.on('stalled', function () {//网速失速 console.log("网速失速") }); this.on('play', function () {//开始播放 console.log("开始播放") }); this.on('pause', function () {//暂停 console.log("暂停") }); this.on('loadedmetadata', function () {//成功获取资源长度 console.log("成功获取资源长度") }); this.on('loadeddata', function () {//渲染播放画面 console.log("渲染播放画面") }); this.on('waiting', function () {//等待数据,并非错误 console.log("等待数据") }); this.on('playing', function () {//开始回放 console.log("开始回放") }); this.on('firstplay', function () {//开始回放 console.log("首次播放") }); this.on('canplay', function () {//可以播放,但中途可能因为加载而暂停 console.log("可以播放,但中途可能因为加载而暂停") }); this.on('canplaythrough', function () { //可以播放,歌曲全部加载完毕 console.log("可以播放,歌曲全部加载完毕") }); this.on('seeking', function () { //寻找中 console.log("寻找中") }); this.on('seeked', function () {//寻找完毕 console.log("寻找完毕") }); this.on('timeupdate', function () {//播放时间改变 console.log("播放时间改变") }); this.on('ended', function () {//播放结束 console.log("播放结束") }); this.on('ratechange', function () {//播放速率改变 console.log("播放速率改变") }); this.on('fullscreenchange', function () {//播放速率改变 console.log("全屏切换改变") }); this.on('durationchange', function () {//资源长度改变 console.log("资源长度改变") }); this.on('volumechange', function () {//音量改变 console.log("音量改变") });
应用案例
第一次播放视频不显示进度条,显示当前时间
ctPlayer.value = videojs('ctyunplayer-container', { language: 'zh-CN', autoplay: false, //是否自动播放 loop: false, //是否循环播放 controls: true, //控制器 controlBar: { // 设置控制条组件 playbackRateMenuButton: true, durationDisplay: true, // 显示总时长 currentTimeDisplay: true, // 显示当前时间 children: [ { name: 'playToggle' }, // 播放/暂停按钮 { name: 'volumePanel', // 音量控制 inline: false // 不使用水平方式 }, { name: 'FullscreenToggle' } // 全屏 ] } });
视频显示进度条和播放总时间
ctPlayer.value = videojs('ctyunplayer-container', { language: 'zh-CN', autoplay: false, //是否自动播放 loop: false, //是否循环播放 controls: true, //控制器 controlBar: { // 设置控制条组件 playbackRateMenuButton: true, children: [{ name: 'playToggle' }, // 播放/暂停按钮 { name: 'progressControl' }, // 播放进度条 { name: 'durationDisplay' }, // 视频播放总时间 { name: 'volumePanel', // 音量控制 inline: false // 不使用水平方式 }, { name: 'FullscreenToggle' } // 全屏 ] } });
添加监听事件并更新数据
// 添加视频监听事件 const addPlayerEvent = () => { // 在错误时 ctPlayer.value.on('error',(e) => { console.log('ERR',e); }); // 在错误时 ctPlayer.value.on('canplay',(e) => { console.log('canplay',e); }); // 在开始播放时 ctPlayer.value.on('play', (e) => { console.log('onPlayonPlayonPlayonPlay',e); countDownTimer.value = setInterval(rotationTime, 60000); // 1分钟更新一次 isClear.value = false; const stime = videoConfig.value.startTime; if(!stime || stime === null || stime === '') {emit('sentVideoStartTimeEvent')} // 记录开始时间 }); // 在暂停时 ctPlayer.value.on('pause',(e) => { console.log('onPause',e); updataVideoLoadData(); // 记录视频播放位置 }); // 在停止时 ctPlayer.value.on('ended',(e) => { console.log('onStop',e); updataVideoLoadData(); // 记录视频播放位置 closeCountDownTimer(); // 关闭定时器 }); // 视频跳转结束 // ctPlayer.value.on('seeked',(e) => { // console.log('seeked',e); // // const error = ctPlayer.value.error(); // // console.log('log== ~ error ~ ', 'color:#2ecc71', error) // updataVideoLoadData(); // 记录视频播放位置 // }); };

// 倒计时定时器 const countDownTimer = ref(null); const isClear = ref(true); const closeCountDownTimer = () => { isClear.value = true; countDownTimer.value && clearInterval(countDownTimer.value); } // 更新视频数据 const updataVideoLoadData = () => { if(!isClear.value || ctPlayer.value) { const seconds = ctPlayer.value.currentTime(); // 获取当前播放到视频的哪个时间(位置),返回的单位为秒。 const duration = ctPlayer.value.duration(); // 获取当前播放到视频的时长,返回的单位为秒。 const per = parseFloat(seconds / duration) console.log('log== ~ seconds ~ ', 'color:#2ecc71', seconds, duration, per) const currentVideoData = { percentage: per, currentPosition: seconds } if(per === 1) { emit('sentVideoPlayDataEvent', currentVideoData, 'end'); } else { emit('sentVideoPlayDataEvent', currentVideoData); } } }
视频播放状态
myPlayer.currentTime = value; //当前播放的位置,赋值可改变位置 myPlayer.startTime; //一般为0,如果为流媒体或者不从0开始的资源,则不为0 myPlayer.duration; //当前资源长度 流返回无限 myPlayer.paused; //是否暂停 myPlayer.defaultPlaybackRate = value;//默认的回放速度,可以设置 myPlayer.playbackRate = value;//当前播放速度,设置后马上改变 myPlayer.played; //返回已经播放的区域,TimeRanges,关于此对象见下文 myPlayer.seekable; //返回可以seek的区域 TimeRanges myPlayer.ended; //是否结束 myPlayer.autoPlay; //是否自动播放 myPlayer.loop; //是否循环播放
设置从第几秒开始播放
if(videoConfig.value.videoSeekTime > 0) ctPlayer.value.currentTime(videoConfig.value.videoSeekTime); // 从第几秒开始播放
设置播放控件语言,悬浮在控件上显示英文,动态设置语言需要引入语言包,我将语言包下载至本地通过script标签引入
<script src="./ctyunplayer/lang/zh-CN.js"></script>
初始化播放器时设置语言
ctPlayer.value = videojs('ctyunplayer-container', { language: 'zh-CN', // 中文 autoplay: false, //是否自动播放 loop: false, //是否循环播放 controls: true, //控制器 controlBar: { // 设置控制条组件 playbackRateMenuButton: true } });
参考博客 https://blog.csdn.net/qq_59747594/article/details/131461844/
https://juejin.cn/post/6988479071474679844