最近放了个MV在博客上,总觉得浏览器的自带控件不够美观,于是...我就自己动手写一个video播放器

觉得bilibili的播放器还可以,于是在外观上模仿了一下

截图:
001.jpg

下载

亮出我的代码:

html

<html>
    <head>
        <meta charset="UTF-8">
        <title>video</title>
        <script src='jquery.min.js'></script>
        <script src='video.js'></script>
        <link rel="stylesheet" href="video.css" type="text/css" />
    </head>
    <body height="100%">
        <div id="video" style="width:600px;height:400px;">
            <script>
                video('video','http://file.littlehands.site/MV/Shelter.mp4','https://i1.hdslb.com/bfs/archive/d7bec4f0ccd05ab2e85da8e1389add959e68ffa8.jpg');
            </script>
        </div>
    </body>
</html>

javascript

var touch_dblclick_time;
//触摸双击事件
/* $.fn.touch_dblclick = function(fc){
    $(this).on('touchstart',function(){
        touch_dblclick_time++;
        setTimeout(function(){
            touch_dblclick_time = 0;
        }, 1000);
        if (touch_dblclick_time > 1) {
            fc();
            touch_dblclick_time = 0;
        }
    });
} */

function video(id,url,img){
    /* @id 生成元素id
     * @url 视频链接
     * @img 预览图片链接,可空
     *
     * 该函数将会加载一个自定义视频和视频控件
     * video元素宽高由生成元素宽高决定
     */

    //处理空参数
    if (!img){
        img = '';
    }
    
    //打印html代码
    $('#' + id).html('' +
            '<div id="' + id + '_box" class="video_box">' +
                '<video id="' + id + '_video" style="display: none;" class="video_video"><br>你用这种浏览器,还好意思装逼!</video>' +
                '<div id="' + id + '_load" class="video_load">' +
                    '<img src="' + img + '"/>' +
                    '<div class="video_icon"></div>' +
                '</div>' +
                '<div id="' + id + '_control" class="video_control" style="display: none;">' +
                    '<div id="' + id + '_time" class="video_time">' +
                        '<span id="' + id + '_time_current" class="video_time_current">00:00</span>' +
                        '<span>/</span>' +
                        '<span id="' + id + '_time_total" class="video_time_total">00:00</span>' +
                    '</div>' +
                    '<div id="' + id + '_progress" class="video_progress">' +
                        '<div id="' + id + '_progress_bar" style="width:0;" class="video_progress_bar"></div>' +
                    '</div>' +
                    '<div class="video_right">' +
                        '<div class="video_icon video_voice_btn" id="' + id + '_voice_btn"></div>' +
                        '<div id="' + id + '_voice_div" class="video_voice_div" style="display: none;">' +
                            '<div id="' + id + '_voice" class="video_voice">' +
                                '<div id="' + id + '_voice_bar" class="video_voice_bar" style="height: 50%;"></div>' +
                            '</div>' +
                        '</div>' +
                        '<div style="width: 0.5rem;height: 2rem;"></div>' +
                        '<div class="video_icon video_screen" id="' + id + '_screen"></div>' +
                    '</div>' +
                    '<div class="video_icon video_state" id="' + id + '_state"></div>' +
                '</div>' +
                '<div id="' + id + '_display" class="video_display" style="display: none;"></div>' +
            '</div>' +
        ''
    );
    
    //打印全局变量
    $('#' + id).after('' +
        '<script>' +
            'var ' +
                id + '_display_mouse_xy,' +
                id + '_mobile,' +
                id + '_mobile_time = 0,' +
                id + '_control_mouse,' +
                id + '_control_touch,' +
                id + '_load_del' +
            ';' +
        '</script>'
    );
    
    /* icon 信息
     * @vocal -3.47222rem -1.725rem 有声的
     * @voicaless -4.86111rem -1.725rem 无声的
     * @screen_full -3.47222rem 0.38rem 全屏
     * @screen_restore -4.86111rem 0.38rem 还原屏幕
     * @play -0rem -0rem 播放
     * @pause -0rem -3.15rem 暂停
     */
     
    //局部变量声明
    var
        _ = $('#' + id),
        _box = $('#' + id + '_box'),
        _video = $('#' + id + '_video'),
        _state = $('#' + id + '_state'),
        _control = $('#' + id + '_control'),
        _screen = $('#' + id + '_screen'),
        _time_current = $('#' + id + '_time_current'),
        _time_total = $('#' + id + '_time_total'),
        _progress = $('#' + id + '_progress'),
        _progress_bar = $('#' + id + '_progress_bar'),
        _voice = $('#' + id + '_voice'),
        _voice_bar = $('#' + id + '_voice_bar'),
        _voice_btn = $('#' + id + '_voice_btn'),
        _voice_div = $('#' + id + '_voice_div'),
        _display = $('#' + id + '_display'),
        _load = $('#' + id + '_load')
    ;
    
    //load加载层被点击
    _load.click(function(){
        _load.remove();
        _video.css('display','inline');
        _control.css('display','inline');
        _video.html('<source src="' + url + '"><br>你用这种浏览器,还好意思装逼!');
        window[id + '_load_del'] = true;
        _display.css('display','inline');
        video_play_mobile_process(id);
        _video.get(0).play();
        _state.css('background-position','-0rem -3.15rem');
        _voice_bar.height(_voice.height() * _video.get(0).volume);
    });
    
    //播放控制
    _display.click(function(){
        video_play(id);
    });
    _display.on('touchend',function(){
        window[id + '_mobile'] = true;
        video_play(id,true);
    });
    _state.click(function(){
        if (window[id + '_mobile']){
            window[id + '_mobile'] = false;
        }else{
            if (_video.get(0).paused){
                _video.get(0).play();
                _state.css('background-position','-0rem -3.15rem');
            }else{
                _video.get(0).pause();
                _state.css('background-position','-0rem -0rem');
            }
        }
    });
    /*_video.touch_dblclick(function(){
        //window[id + '_mobile'] = true;
        video_play(id,true);
    });*/
    
    //屏幕按钮被点击
    _screen.click(function(){
        if (window[id + '_mobile']){
            window[id + '_mobile'] = false;
        }else{
            if (_box.css('position') !== 'fixed'){
                //全屏
                _box.addClass('video_box_screen_full');
                _video.addClass('video_video_screen_full');
                _screen.css('background-position','-4.86111rem 0.38rem');
            }else{
                //还原
                _box.removeClass('video_box_screen_full');
                _video.removeClass('video_video_screen_full');
                _screen.css('background-position','-3.47222rem 0.38rem');
            }
        }
    });
    _display.dblclick(function(){
        _screen.click();
    });
    
    //时间
    _video.on('loadedmetadata',function(){
        _time_total.html(video_time_conversion(this.duration));
    });
    _video.on('timeupdate',function(){
        if (!window[id + '_progress_click']){
            _time_current.html(video_time_conversion(this.currentTime));
            _progress_bar.width(this.currentTime / this.duration * 100 + '%');
        }
        _video.css('z-index','0');
    });
    
    //拖动进度条
    _progress.mousedown(function(e){
        //按下
        if (window[id + '_mobile']){
            window[id + '_mobile'] = false;
        }else{
            window[id + '_progress_click'] = true;
            video_progress_position(e.pageX,id);
        }
    });
    $(window).mouseup(function(){
        //放开
        if (window[id + '_progress_click']){
            _video.get(0).currentTime = _progress_bar.width() / _progress.width() * _video.get(0).duration;
            window[id + '_progress_click'] = false;
        }
    });
    $('body').mousemove(function(e){
        //移动
        video_progress_position(e.pageX,id);
    });
    
    //播放结束
    _video.on('ended',function(){
        _state.css('background-position','-0rem -0rem');
    });
    
    //控制组件
    _display.mousemove(function(e){
        //鼠标移动
        var xy = e.pageX + e.pageY;
        if (window[id + '_load_del'] && !window[id + '_mobile'] && !(xy == window[id + '_display_mouse_xy'])){
            _display.removeClass('video_control_hide');
            _control.css('display','inline');
            window[id + '_display_mouse_xy'] = xy;
            video_control_mouse_process(id);
        }
    });
    _control.mousemove(function(){
        video_control_mouse_process(id);
    });
    _control.mouseenter(function(){
        window[id + '_control_mouse_on'] = true;
        video_control_mouse_process(id);
    });
    _control.mouseleave(function(){
        window[id + '_control_mouse_on'] = false;
        video_control_mouse_process(id);
    });
    _control.on('touchstart',function(){
        clearTimeout(window[id + '_control_touch']);
    });
    _control.on('touchend',function(){
        video_play_mobile_process(id);
    });
    
    //拖动音量条
    _voice.mousedown(function(e){
        //按下
        if (window[id + '_mobile']){
            window[id + '_mobile'] = false;
        }else{
            window[id + '_voice_click'] = true;
            video_voice_position(e.pageY,id);
        }
    });
    $(window).mouseup(function(){
        //放开
        if (window[id + '_voice_click']){
            window[id + '_voice_click'] = false;
        }
    });
    $('body').mousemove(function(e){
        //移动
        video_voice_position(e.pageY,id);
        if(!window[id + '_voice_click'] && !window[id + '_voice_btn_mouse'] && !window[id + '_voice_div_mouse']){
            _voice_div.css('display','none');
        }
    });
    
    //静音
    _video.on('volumechange',function(){
        if(this.volume == 0){
            _voice_btn.css('background-position','-4.86111rem -1.725rem');
        }else{
            _voice_btn.css('background-position','-3.47222rem -1.725rem');
            window[id + '_volume'] = this.volume;
        }
    });
    _voice_btn.click(function(){
        if(!window[id + '_mobile']){
            voice_process(id);
        }else{
            window[id + '_mobile'] = false;
        }
    });
    
    //音量按钮
    _voice_btn.mouseenter(function(){
        window[id + '_voice_btn_mouse'] = true;
        _voice_div.css('display','inline');
    });
    _voice_btn.mouseleave(function(){
        window[id + '_voice_btn_mouse'] = false;
    });
    _voice_div.mouseenter(function(){
        window[id + '_voice_div_mouse'] = true;
    });
    _voice_div.mouseleave(function(){
        window[id + '_voice_div_mouse'] = false;
    });
    _voice_btn.on('touchend',function(){
        window[id + '_mobile'] = true;
        if(_voice_div.css('display') == 'none'){
            _voice_div.css('display','inline');
        }else{
            voice_process(id);
        }
    });
}

//播放控制
function video_play(id,mobile){
    var
        video = $('#' + id + '_video')[0],
        _state = $('#' + id + '_state'),
        _control = $('#' + id + '_control'),
        _display = $('#' + id + '_display')
    ;
    if (window[id + '_mobile']){
        if (mobile){
            clearTimeout(window[id + '_control_touch']);
            if (_control.css('display') == 'none'){
                _control.css('display','inline');
                video_play_mobile_process(id);
            }else{
                _control.css('display','none');
            }
        }else{
            window[id + '_mobile'] = false;
        }
    }else{
        if(!window[id + '_control_mouse_on']){
            if (video.paused){
                video.play();
                _state.css('background-position','-0rem -3.15rem');
            }else{
                video.pause();
                _state.css('background-position','-0rem -0rem');
            }
            video_control_mouse_process(id);
        }
    }
}
function video_play_mobile_process(id){
    var
        _control = $('#' + id + '_control')
    ;
    window[id + '_control_touch'] = setTimeout(function(){
            _control.css('display','none');
    },5000);
}

//时间转化 seconds => minutes
function video_time_conversion(time){
    var minutes,seconds;
    minutes = parseInt(time / 60);
    seconds = parseInt(time - 60 * minutes);
    if (seconds < 10){
        seconds = '0' + seconds;
    }
    if (minutes < 10){
        minutes = '0' + minutes;
    }
    return minutes + ':' + seconds;
};

//拖动进度条
function video_progress_position(x,id){
    if (window[id + '_progress_click']){
        var x1 = x - $('#' +id + '_progress').offset().left,
            x2 = $('#' +id + '_progress').width();
        if (x1 <= x2){
            x = x1;
        }else{
            x = x2;
        }
        $('#' +id + '_progress_bar').width(x);
        $('#' + id + '_time_current').html(video_time_conversion(x / x2 * $('#' + id + '_video').get(0).duration));
    }
}

//拖动音量条
function video_voice_position(y,id){
    var
        _video = $('#' +id + '_video'),
        _voice = $('#' +id + '_voice'),
        _voice_bar = $('#' +id + '_voice_bar');
    if (window[id + '_voice_click']){
        var y1 = _voice.offset().top + _voice.height() -y,
            y2 = _voice.height();
        if (y1 <= y2){
            y = y1;
        }else{
            y = y2;
        }
        _voice_bar.height(y);
        _video.get(0).volume = _voice_bar.height() / _voice.height();
    }
}

//控制组件
function video_control_mouse_process(id){
    var
        _control = $('#' + id + '_control'),
        _display = $('#' + id + '_display')
    ;
    clearTimeout(window[id + '_control_mouse']);
    window[id + '_control_mouse'] = setTimeout(function(){
        if (!window[id + '_control_mouse_on'] && !window[id + '_voice_click'] && !window[id + '_progress_click']){
            _display.addClass('video_control_hide');
            _control.css('display','none');
        }
    },5000);
}

//静音
function voice_process(id){
    var
        _video = $('#' + id + '_video'),
        _voice = $('#' + id + '_voice'),
        _voice_bar = $('#' + id + '_voice_bar')
    ;
    if(_video.get(0).volume == 0){
        _video.get(0).volume = window[id + '_volume'] || 1;
    }else{
        _video.get(0).volume = 0;
    }
    _voice_bar.height(_video.get(0).volume * _voice.height());
}

css

.video_load img{
    width: 100%;
    height: 100%;
    filter: blur(0.34133rem);
    -webkit-filter: blur(0.34133rem);
    cursor: pointer;
}
.video_icon{
    background-image: url(icon.png);
    background-repeat: no-repeat;
    background-size: 6.25rem;
    cursor: pointer;
}
.video_load .video_icon{
    width: 3.438rem;
    height: 3rem;
    position: absolute;
    bottom: 0.5rem;
    right: 0.5rem;
}
.video_load{
    z-index: 3;
}
.video_box{
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    overflow: hidden;
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 2;
}
.video_control{
    position: absolute;
    bottom: 0px;
    left: 0px;
    width: 100%;
    height: 2rem;
    color: white;
    display: inline;
    background-color: rgba(0, 0, 0, 0.498039);
    z-index: 2;
}
.video_time{
    position: absolute;
    height: 2rem;
}
.video_time span{
    font-family: arial,sans-serif;
    float: left;
    height: 100%;
    line-height: 2rem;
}
.video_time_current{
    width: 3rem;
    text-align: right;
}
.video_time_total{
    width: 3rem;
    text-align: left;
}
.video_progress{
    background: #4c4c4c;
    position: absolute;
    bottom: 0.75em;
    left: 6.25rem;
    right: 4.5rem;
    height: 0.5rem;
    cursor: pointer;
}
.video_progress_bar{
    background-color: #de698c;
    height: 100%;
    position: absolute;
}
.video_progress_bar:after{
    content: "";
    background-color: #FFF;
    height: 1rem;
    width: 1rem;
    position: absolute;
    top: -0.25rem;
    right: -0.95rem;
    border-radius: 50%;
}
.video_right{
    height: 100%;
    float: right;
    margin-right: 0.5rem;
}
.video_right div{
    float: left;
}
.video_voice_btn {
    width: 1rem;
    height: 2rem;
    background-position: -3.47222rem -1.725rem;
    z-index: 3;
}
.video_screen {
    width: 1.3rem;
    height: 2rem;
    background-position: -3.47222rem 0.38rem;
}
.video_right .video_icon:hover{
    opacity: 0.75;
}
.video_state{
    position: absolute;
    top: -3rem;
    right: 0.5rem;
    width: 3.438rem;
    height: 3rem;
}
.video_video{
    //height: 130%;
    height: 100%;
    width: 100%;
    //top: -15%;
    //position: relative;
    //position: absolute;
    background: #000;
    color: #FFF;
}
.video_box_screen_full{
    position: fixed !important;
    width: auto !important;
    height: auto !important;
    top: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
    z-index: 999 !important;
}
.video_video_screen_full{
    height: 100% !important;
    top: auto !important;
}
.video_control_hide{
    cursor: none;
}
.video_control_hide .video_icon{
    cursor: none;
}
.video_display{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1;
}
.video_voice_div{
    background: rgba(0, 0, 0, 0.498039);
    position: absolute;
    width: 1rem;
    height: 5rem;
    top: -5rem;
    right: 2.3rem;
    z-index: 3;
}
.video_voice{
    position: absolute;
    top: 0.5rem;
    left: 0.35rem;
    background: #4c4c4c;
    width: 0.3rem;
    height: 4rem;
    cursor: pointer;
}
.video_voice_bar{
    position: absolute;
    bottom: 0;
    width: 100%;
    background: #de698c;
}
.video_voice_bar:before{
    content: "";
    position: absolute;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background-color: #FFF;
    top: -0.3rem;
    left: -0.1rem;
}
/* icon 信息
 * @vocal -3.47222rem -1.725rem 有声的
 * @voicaless -4.86111rem -1.725rem 无声的
 * @screen_full -3.47222rem 0.38rem 全屏
 * @screen_restore -4.86111rem 0.38rem 还原屏幕
 * @play -0rem -0rem 播放
 * @pause -0rem -3.15rem 暂停
 */

标签: none

已有 4 条评论

  1. jrotty jrotty 访客 Chrome Windows 10 回复

    同一个页面播放多个视频怎么办啊

    1. 小さな手は 小さな手は 博主 Chrome Windows 7 回复

      回复 @jrotty

      id不要重复就可以
      /diy/video/video1.html

      1. Sakura_Love Sakura_Love 访客 Chrome Windows 10 回复

        回复 @小さな手は

        示例的视频是什么啊,感觉很好看

        1. 小さな手は 小さな手は 博主 Chrome Windows 7 回复

          回复 @Sakura_Love

          Shelter

添加新评论

注意:已开启评论过滤器,无中文无法评论!
泡泡表情