添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 IT修真院

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即可。


最后贴一张最终实现的效果图

没错,就是要求在视频播放前控制面板常驻,答应我,不要吐槽UI

对了,还有示例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);