video.js视频播放器自定义样式
最近因为项目的需求,需要自定义HTML视频播放器样式。
因为之前没有接触过这方面的东西,所以第一感觉这个需求无非就是更改样式,实现的步骤无非就是将原生的video标签display:none之后,然后自己写一个控制面板,上面一堆按钮,包括播放、进度条、音量、倍速、进度条等,然后相应的东西调用对应的API即可
但是遇到了两个问题——
1.原生video标签的东西不好动
这要从它的DOM结构说起,先贴图
如图两个红框是原生video标签中的隐藏DOM,可以看见这两个东东还是嵌套的,最里层的隐藏DOM改动起来会很麻烦
2.如果跨浏览器兼容性会很不好,不能保持样式一致。
于是我们走上了第二条路——video.js
我对video.js的理解就是video.js把原生video标签里的内容拆成了一个一个组件,包括隐藏DOM里的东西,然后方便自定义使用,其次就是解决兼容性问题(这一点是最重要的我却没有使用进去,惭愧。。。)
video.js是开源插件,要使用video.js要做三件事——
第一、引入相关的css、js文件
第二、在video标签里添加class—— video-js、vjs-default-skin(这是最基本的两个,其中video-js是最重要的,其余的配置可以通过class的形式也可以在配置的js文件中)
第三、激活video.js(也就是实例化一个video.js)
当播放器出现这样的样式的时候,就说明video.js使用成功了
但是——新的风暴已经出现
使用的是angularJS框架,实例化video.js的时候会报错,提示找不到你要实例化的那个东西(id),原因是实例化的时候相关的DOM还没有生成,自然会报错,解决方式自然是写一个延迟函数,但这样的话就会有一个明显的延迟,相当不友好,所以我们可以把实例化的过程写到指令里面,这样从执行过程中来说就解决了报错的问题还解决了video加载明显延迟的问题。
但是,没错,还是有问题,因为现在都是单页面应用,当你从一个视频切换到另一个视频的时候,页面中只是更新了部分视图,也就是说video.js觉得自己已经实例化过了,而实则新的video标签并没有被实例化,解决这种情况的方式自然是手动刷新一下页面~
不不不,手动刷新怕是要被leader打死,自然是在自定义指令中做一些小小的操作,video.js有一个dispose方法用于手动清除,每次实例化之前先检查一下是否已经实例化,如果有就手动清除一次即可。
还有关于样式,一些固定的控件可以在实例化的时候通过提供的API调整,比如默认的音量样式是水平的,想要调整为纵向的可以通过这样的方式调整:
//音量条竖直
controlBar: {
volumePanel: {
inline: false,
CurrentTimeDisplay: true
}
一些控件的细节可以自己写css调整
如果想创建没有的控件,比如说这次需求里的调整倍速,自己添加一个DOM元素然后绑定相应的事件,调用video.js提供的API即可。
最后贴一张最终实现的效果图
对了,还有示例Demo
angular.module('myApp').directive('videoPlayer',function($timeout, $rootScope){
return{
restrict:"C",
link:function(scope,ele,attrs){
$timeout(function () {
var idName = attrs.id;
//$rootScope.player——将player设置为根作用域,每次重新解析videoJs
if ($rootScope.player){
$rootScope.player.dispose();
//实例化的过程
$rootScope.player = videojs(idName, {
//音量条竖直
controlBar: {
volumePanel: {
inline: false,
CurrentTimeDisplay: true
}, function () {
//定义倍速按钮——按照音量模块为模板
var newbtn = document.createElement('btn');
newbtn.innerHTML = '<div class="vjs-volume-panel vjs-control speedside"><button class="vjs-mute-control vjs-button vjs-vol-3 " type="button"><span id="speed-video">1X</span></button><div class="vjs-volume-control vjs-control vjs-volume-vertical video-bar" id="speedtab"></div></div>';
var controlBar = document.getElementsByClassName('vjs-control-bar')[0];
var insertBeforeNode = document.getElementsByClassName('vjs-fullscreen-control')[0];
controlBar.insertBefore(newbtn, insertBeforeNode);
//生成倍速选项、添加点击事件、增加选中样式
for (let i = 0, j = 0.5; i < 5; i++) {
var newchoose = document.createElement('span');
var newtext = document.createTextNode(j + 'x');
newchoose.appendChild(newtext);
newchoose.className = 'speed';
document.getElementById("speedtab").appendChild(newchoose);
newchoose.onclick = function () {
$rootScope.player.playbackRate(j - 0.25);
document.getElementById('speed-video').innerHTML = $rootScope.player.playbackRate() + 'x';
var arrs = document.getElementsByClassName('speed');
for (let k = 0; k < arrs.length; k++) {
arrs[k].className = 'speed';
this.className = 'speed speedsidechoose';
j += 0.25;
//默认1x是选中样式
document.getElementsByClassName('speed')[2].className = 'speed speedsidechoose';
$rootScope.player.removeChild('BigPlayButton');//开始的大按钮
$(document.getElementById(idName)).css("zoom", "1.25");
$(document.getElementById(idName)).css("width", "100%");
if( $(document.getElementById(idName)).width()>700){
$(document.getElementById(idName)).css("height", "414px");
else{
$(document.getElementById(idName)).css("height", "305.5px");
/*让控制面板在视频未开始之前常驻*/
$timeout(function(){
$(document.getElementById(idName)).addClass("vjs-has-started");
},100);