您好!欢迎访问家园网-www.jy.wang!

家园网

如何引入并初始化 Willes 手机播放器

网络 作者:本站 点击:

如何引入并初始化 Willes 手机播放器

html代码:



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"/>
    <title>HTML5手机播放器</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css"/>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.css">
    <link rel="stylesheet" type="text/css" href="css/willesPlay.css"/>
    <script src="js/jquery.min.js"></script>
    <script src="js/willesPlay.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div id="willesPlay">
                <div class="playHeader">
                    <div class="videoName">响应式设计</div>
                </div>
                <div class="playContent">
                    <div class="turnoff">
                        <ul>
                            <li><a href="javascript:;" title="喜欢" class="glyphicon glyphicon-heart-empty"></a></li>
                            <li><a href="javascript:;" title="关灯"
                                   class="btnLight on glyphicon glyphicon-sunglasses"></a></li>
                            <li><a href="javascript:;" title="分享" class="glyphicon glyphicon-share"></a></li>
                        </ul>
                    </div>
                    <video width="100%" height="100%" id="playVideo">
                        <source src="test.mp4" type="video/mp4">
                        </source>
                        当前浏览器不支持 video直接播放,点击这里下载视频: <a href="/">下载视频</a></video>
                    <div class="playTip glyphicon glyphicon-play"></div>
                </div>
                <div class="playControll">
                    <div class="playPause playIcon"></div>
                    <div class="timebar"><span class="currentTime">0:00:00</span>
                        <div class="progress">
                            <div class="progress-bar progress-bar-danger progress-bar-striped" role="progressbar"
                                 aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div>
                        </div>
                        <span class="duration">0:00:00</span></div>
                    <div class="otherControl"><span class="volume glyphicon glyphicon-volume-down"></span> <span
                            class="fullScreen glyphicon glyphicon-fullscreen"></span>
                        <div class="volumeBar">
                            <div class="volumewrap">
                                <div class="progress">
                                    <div class="progress-bar progress-bar-danger" role="progressbar" aria-valuemin="0"
                                         aria-valuemax="100" style="width: 8px;height: 40%;"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>


willesPlay.js代码:

$(function() {
    var playVideo = $('video');
    var playPause = $('.playPause'); //播放和暂停
    var currentTime = $('.timebar .currentTime'); //当前时间
    var duration = $('.timebar .duration'); //总时间
    var progress = $('.timebar .progress-bar'); //进度条
    var volumebar = $('.volumeBar .volumewrap').find('.progress-bar');
    playVideo[0].volume = 0.4; //初始化音量
    playPause.on('click', function() {
        playControl();
    });
    $('.playContent').on('click', function() {
        playControl();
    }).hover(function() {
        $('.turnoff').stop().animate({
            'right': 0
        }, 500);
    }, function() {
        $('.turnoff').stop().animate({
            'right': -40
        }, 500);
    });
    $(document).click(function() {
        $('.volumeBar').hide();
    });
    playVideo.on('loadedmetadata', function() {
        duration.text(formatSeconds(playVideo[0].duration));
    });

    playVideo.on('timeupdate', function() {
        currentTime.text(formatSeconds(playVideo[0].currentTime));
        progress.css('width', 100 * playVideo[0].currentTime / playVideo[0].duration + '%');
    });
    playVideo.on('ended', function() {
        $('.playTip').removeClass('glyphicon-pause').addClass('glyphicon-play').fadeIn();
        playPause.toggleClass('playIcon');
    });
   
    $(window).keyup(function(event){
        event = event || window.event;
            if(event.keyCode == 32)playControl();
            if(event.keyCode == 27){
            $('.fullScreen').removeClass('cancleScreen');
            $('#willesPlay .playControll').css({
                'bottom': -48
            }).removeClass('fullControll');
            };
        event.preventDefault();
    });
   
   
    //全屏
    $('.fullScreen').on('click', function() {
        if ($(this).hasClass('cancleScreen')) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.mozExitFullScreen) {
                document.mozExitFullScreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            }
            $(this).removeClass('cancleScreen');
            $('#willesPlay .playControll').css({
                'bottom': -48
            }).removeClass('fullControll');
        } else {
            if (playVideo[0].requestFullscreen) {
                playVideo[0].requestFullscreen();
            } else if (playVideo[0].mozRequestFullScreen) {
                playVideo[0].mozRequestFullScreen();
            } else if (playVideo[0].webkitRequestFullscreen) {
                playVideo[0].webkitRequestFullscreen();
            } else if (playVideo[0].msRequestFullscreen) {
                playVideo[0].msRequestFullscreen();
            }
            $(this).addClass('cancleScreen');
            $('#willesPlay .playControll').css({
                'left': 0,
                'bottom': 0
            }).addClass('fullControll');
        }
        return false;
    });
    //音量
    $('.volume').on('click', function(e) {
        e = e || window.event;
        $('.volumeBar').toggle();
        e.stopPropagation();
    });
    $('.volumeBar').on('click mousewheel DOMMouseScroll', function(e) {
        e = e || window.event;
        volumeControl(e);
        e.stopPropagation();
        return false;
    });
    $('.timebar .progress').mousedown(function(e) {
        e = e || window.event;
        updatebar(e.pageX);
    });
    //$('.playContent').on('mousewheel DOMMouseScroll',function(e){
    //  volumeControl(e);
    //});
    var updatebar = function(x) {
        var maxduration = playVideo[0].duration; //Video 
        var positions = x - progress.offset().left; //Click pos
        var percentage = 100 * positions / $('.timebar .progress').width();
        //Check within range
        if (percentage > 100) {
            percentage = 100;
        }
        if (percentage < 0) {
            percentage = 0;
        }

        //Update progress bar and video currenttime
        progress.css('width', percentage + '%');
        playVideo[0].currentTime = maxduration * percentage / 100;
    };
    //音量控制
    function volumeControl(e) {
        e = e || window.event;
        var eventype = e.type;
        var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1));
        var positions = 0;
        var percentage = 0;
        if (eventype == "click") {
            positions = volumebar.offset().top - e.pageY;
            percentage = 100 * (positions + volumebar.height()) / $('.volumeBar .volumewrap').height();
        } else if (eventype == "mousewheel" || eventype == "DOMMouseScroll") {
            percentage = 100 * (volumebar.height() + delta) / $('.volumeBar .volumewrap').height();
        }
        if (percentage < 0) {
            percentage = 0;
            $('.otherControl .volume').attr('class', 'volume glyphicon glyphicon-volume-off');
        }
        if (percentage > 50) {
            $('.otherControl .volume').attr('class', 'volume glyphicon glyphicon-volume-up');
        }
        if (percentage > 0 && percentage <= 50) {
            $('.otherControl .volume').attr('class', 'volume glyphicon glyphicon-volume-down');
        }
        if (percentage >= 100) {
            percentage = 100;
        }
        $('.volumewrap .progress-bar').css('height', percentage + '%');
        playVideo[0].volume = percentage / 100;
        e.stopPropagation();
        e.preventDefault();
    }

    function playControl() {
            playPause.toggleClass('playIcon');
            if (playVideo[0].paused) {
                playVideo[0].play();
                $('.playTip').removeClass('glyphicon-play').addClass('glyphicon-pause').fadeOut();
            } else {
                playVideo[0].pause();
                $('.playTip').removeClass('glyphicon-pause').addClass('glyphicon-play').fadeIn();
            }
        }
        //关灯
    $('.btnLight').click(function(e) {
        e = e || window.event;
        if ($(this).hasClass('on')) {
            $(this).removeClass('on');
            $('body').append('<div class="overlay"></div>');
            $('.overlay').css({
                'position': 'absolute',
                'width': 100 + '%',
                'height': $(document).height(),
                'background': '#000',
                'opacity': 1,
                'top': 0,
                'left': 0,
                'z-index': 999
            });
            $('.playContent').css({
                'z-index': 1000
            });
            $('.playControll').css({
                'bottom': -48,
                'z-index': 1000
            });

            $('.playContent').hover(function() {
                $('.playControll').stop().animate({
                    'height': 48,
                },500);
            }, function() {
                setTimeout(function() {
                    $('.playControll').stop().animate({
                        'height': 0,
                    }, 500);
                }, 2000)
            });
        } else {
            $(this).addClass('on');
            $('.overlay').remove();
            $('.playControll').css({
                'bottom': 0,
            });
        }
        e.stopPropagation();
        e.preventDefault();
    });
});

//秒转时间
function formatSeconds(value) {
    value = parseInt(value);
    var time;
    if (value > -1) {
        hour = Math.floor(value / 3600);
        min = Math.floor(value / 60) % 60;
        sec = value % 60;
        day = parseInt(hour / 24);
        if (day > 0) {
            hour = hour - 24 * day;
            time = day + "day " + hour + ":";
        } else time = hour + ":";
        if (min < 10) {
            time += "0";
        }
        time += min + ":";
        if (sec < 10) {
            time += "0";
        }
        time += sec;
    }
    return time;
}


willesPlay.css代码:

@charset "utf-8";
html,body{
    width: 100%;
    height: 100%;
    background: #ef6a6c;
}
a:hover{
    text-decoration: none;
}
#willesPlay{
    /*width: 1000px;
    height: 660px;*/
    /*width: 1024px;
    height: auto;*/
    margin: 100px auto;
    box-shadow: 0px 0px 15px #333333;
    position: relative;
}
/*播放器头部*/
#willesPlay .playHeader{
    width: 100%;
    height: 48px;
    background: url(../img/playheader.jpg) repeat-x;
    border-radius: 3px 3px 0px 0px;
}
#willesPlay .playHeader .videoName{
    font-size: 16px;
    width: 400px;
    height: 48px;
    line-height: 48px;
    text-align: center;
    margin: 0 auto;
    color: #7a7f82;

}
#willesPlay .playContent{
    position: relative;
    height: auto;
    overflow: hidden;
    background:#000;
    cursor: pointer;
}
#willesPlay .playContent .turnoff{
    position: absolute;
    z-index: 10;
    right: -40px;
    top: 50%;
    margin-top: -90px;
}
#willesPlay .playContent .turnoff li a{
    display: block;
    width: 40px;
    height: 40px;
    line-height: 40px;
    margin-bottom: 20px;
    text-align: center;
    font-size: 20px;
    color: #fff;
    background: rgba(0,0,0,.5);
}
#willesPlay .playContent .turnoff li a:hover{
    color: #666;
}
#willesPlay .playContent .playTip{
    position: absolute;
    width: 110px;
    height: 110px;
    text-align: center;
    line-height: 110px;
    top: 50%;
    left: 50%;
    margin-left: -55px;
    margin-top: -55px;
    background: #ef6a6c;
    font-size: 60px;
    border: 3px solid #FFFFFF;
    border-radius: 50%;
    color: #fff;
    cursor: pointer;
}
#willesPlay .playControll{
    position: absolute;
    z-index: 2147483650;
    width: 100%;
    height: 48px;
    bottom: -48px;
    background: url(../img/playheader.jpg) repeat-x;
    border-radius: 0px 0px 3px 3px;
    -moz-user-select:none;
    -webkit-user-select:none;
    user-select:none;  
}
#willesPlay .fullControll{
    background:rgba(0,0,0,.5);
}
#willesPlay .fullControll .timebar span{
    color: #FFFFFF;
}
#willesPlay .playControll .playPause{
    float: left;
    width: 20px;
    height: 25px;
    background: url(../img/control_01.png) 0px 0px no-repeat;
    margin: 11px 0px 0px 12px;
    cursor: pointer;
}
#willesPlay .playControll .playIcon{
    background-position: 0px -32px;
}
/*进度条*/
#willesPlay .playControll .timebar{
float: left;
width: calc(100% - 145px);
line-height: 48px;
overflow: hidden;
margin: 0 auto;
margin: 0px 0px 0px 20px;
}
#willesPlay .playControll .timebar .progress{
    float: left;
    width: 80%;
    margin: 19px 5px;
    height: 10px;
    cursor: pointer;
}
#willesPlay .playControll .timebar span{
    float: left;
    width: 8%;
    text-align: center;
}
#willesPlay .otherControl{
    float: right;
    position: relative;
}

#willesPlay .otherControl span{
    display: inline-block;
    width: 30px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    vertical-align: middle;
    font-size: 20px;
    margin: 9px  7px;
    /*background: url(../images/control_01.png) no-repeat;*/
    cursor: pointer;
}
#willesPlay .otherControl span:nth-child(1){
    font-size: 28px;
    color: #ef6a6c;
}
/*#willesPlay .otherControl span:nth-child(2){
    background-position: -171px 0px;
}*/
#willesPlay .otherControl span:nth-child(2){
    color: #919597;
}
/*音量*/
#willesPlay .otherControl .volumeBar{
    display: none;
    position: absolute;
    top: -110px;
    left:4px;
    width: 26px;
    height: 100px;
    background:#f1f2f2;
    border-radius: 4px;
    cursor: pointer;
}
#willesPlay .otherControl .volumeBar:after{
    content:"";
    display: block;
    position:absolute;
    bottom: -7px;
    left: 5px;
    width: 0;
    height: 0;
    border-left:8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 8px solid #f1f2f2;
}
#willesPlay .otherControl .volumeBar .volumewrap{
    background: #a2a7aa;
    width: 8px;
    height: 80px;
    position: absolute;
    bottom: 10px;
    left: 9px;
    border-radius: 4px;
}

#willesPlay .otherControl .volumeBar .progress{
    background: none;
}
#willesPlay .otherControl .volumeBar .progress-bar{
    position: absolute;
    bottom: 0px;
    left: 0px;
    border-radius: 4px;
}
video::-webkit-media-controls-enclosure {
    /*禁用播放器控制栏的样式*/
    display: none !important;
}
:-webkit-full-screen{}

下面我来详细讲解这个代码是如何引入并初始化 Willes 手机播放器的。

一、HTML 中的引入方式

1. CSS 样式引入(第 9-11 行)

html

<link rel="stylesheet" type="text/css" href="css/reset.css"/><link rel="stylesheet" type="text/css" href="css/bootstrap.css"><link rel="stylesheet" type="text/css" href="css/willesPlay.css"/>

  • 第9行:引入 reset.css - 重置浏览器默认样式,保证跨浏览器一致性

  • 第10行:引入 bootstrap.css - Bootstrap 框架样式,提供响应式布局支持

  • 第11行:引入 willesPlay.css - 核心样式文件,定义了播放器的外观(控制栏、进度条、按钮等)

2. JavaScript 脚本引入(第 12-13 行)

html

<script src="js/jquery.min.js"></script><script src="js/willesPlay.js" type="text/javascript" charset="utf-8"></script>

  • 第12行:引入 jQuery 库(Willes 播放器依赖 jQuery)

  • 第13行核心脚本文件 willesPlay.js - 包含播放器所有交互逻辑

二、播放器 DOM 结构(第 17-51 行)

html

<div id="willesPlay">  <!-- 播放器容器,ID用于CSS和JS定位 -->
    <div class="playHeader">      <!-- 头部区域:显示视频标题 -->
        <div class="videoName">响应式设计</div>
    </div>
    
    <div class="playContent">     <!-- 视频播放区域 -->
        <div class="turnoff">...</div>  <!-- 右上角功能按钮区(喜欢、关灯、分享)-->
        <video width="100%" height="100%" id="playVideo">  <!-- 原生video标签 -->
            <source src="test.mp4" type="video/mp4">
        </video>
        <div class="playTip glyphicon glyphicon-play"></div>  <!-- 中央播放按钮 -->
    </div>
    
    <div class="playControll">    <!-- 底部控制栏 -->
        <div class="playPause playIcon"></div>      <!-- 播放/暂停按钮 -->
        <div class="timebar">                       <!-- 时间进度区域 -->
            <span class="currentTime">0:00:00</span>    <!-- 当前时间 -->
            <div class="progress">                      <!-- 进度条容器 -->
                <div class="progress-bar..."></div>     <!-- 进度条填充 -->
            </div>
            <span class="duration">0:00:00</span>       <!-- 总时长 -->
        </div>
        <div class="otherControl">                  <!-- 其他控制按钮 -->
            <span class="volume..."></span>             <!-- 音量图标 -->
            <span class="fullScreen..."></span>         <!-- 全屏按钮 -->
            <div class="volumeBar">...</div>            <!-- 音量调节条 -->
        </div>
    </div></div>

三、willesPlay.js 核心代码逐行讲解

初始化阶段(第 1-6 行)

javascript

$(function() {  // jQuery 文档就绪事件,DOM加载完成后执行
    var playVideo = $('video');           // 获取video元素
    var playPause = $('.playPause');      // 播放/暂停按钮
    var currentTime = $('.timebar .currentTime'); // 当前时间显示
    var duration = $('.timebar .duration');       // 总时长显示
    var progress = $('.timebar .progress-bar');   // 进度条
    var volumebar = $('.volumeBar .volumewrap').find('.progress-bar'); // 音量条
    playVideo[0].volume = 0.4;  // 设置初始音量为40%(0.4)

播放控制(第 7-15 行)

javascript

    playPause.on('click', function() {  // 点击播放/暂停按钮
        playControl();  // 调用播放控制函数
    });
    $('.playContent').on('click', function() {  // 点击视频画面区域
        playControl();  // 同样触发播放/暂停
    }).hover(function() {  // 鼠标悬停时
        $('.turnoff').stop().animate({'right': 0}, 500);  // 显示右上角按钮(从右滑入)
    }, function() {  // 鼠标离开时
        $('.turnoff').stop().animate({'right': -40}, 500); // 隐藏右上角按钮(滑出)
    });

视频元数据加载(第 19-21 行)

javascript

    playVideo.on('loadedmetadata', function() {  // 视频元数据加载完成事件
        duration.text(formatSeconds(playVideo[0].duration)); // 显示总时长(秒转时间格式)
    });

播放进度更新(第 23-27 行)

javascript

    playVideo.on('timeupdate', function() {  // 播放时间更新事件(每秒触发多次)
        currentTime.text(formatSeconds(playVideo[0].currentTime)); // 更新当前时间
        progress.css('width', 100 * playVideo[0].currentTime / playVideo[0].duration + '%'); 
        // 计算播放进度百分比并设置进度条宽度
    });

播放结束处理(第 28-30 行)

javascript

    playVideo.on('ended', function() {  // 视频播放结束事件
        $('.playTip').removeClass('glyphicon-pause').addClass('glyphicon-play').fadeIn();
        // 中央图标从暂停改为播放并显示
        playPause.toggleClass('playIcon');  // 切换底部按钮样式
    });

全屏功能(第 47-78 行)

javascript

    $('.fullScreen').on('click', function() {  // 点击全屏按钮
        if ($(this).hasClass('cancleScreen')) {  // 如果是退出全屏状态
            // 退出全屏(兼容不同浏览器)
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.mozExitFullScreen) {
                document.mozExitFullScreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            }
            $(this).removeClass('cancleScreen');  // 移除退出全屏标识
        } else {  // 进入全屏
            // 请求全屏(兼容各浏览器)
            if (playVideo[0].requestFullscreen) {
                playVideo[0].requestFullscreen();
            } else if (playVideo[0].mozRequestFullScreen) {
                playVideo[0].mozRequestFullScreen();
            } else if (playVideo[0].webkitRequestFullscreen) {
                playVideo[0].webkitRequestFullscreen();
            }
            $(this).addClass('cancleScreen');  // 添加退出全屏标识
        }
    });

核心播放控制函数(第 135-145 行)

javascript

    function playControl() {  // 播放/暂停核心逻辑
        playPause.toggleClass('playIcon');  // 切换底部按钮图标样式
        if (playVideo[0].paused) {  // 如果视频是暂停状态
            playVideo[0].play();  // 播放视频
            $('.playTip').removeClass('glyphicon-play').addClass('glyphicon-pause').fadeOut();
            // 中央图标从播放改为暂停并淡出
        } else {  // 如果视频是播放状态
            playVideo[0].pause();  // 暂停视频
            $('.playTip').removeClass('glyphicon-pause').addClass('glyphicon-play').fadeIn();
            // 中央图标从暂停改为播放并淡入
        }
    }

时间格式化函数(第 156-178 行)

javascript

function formatSeconds(value) {  // 将秒数转换为 HH:MM:SS 格式
    value = parseInt(value);
    var time;
    hour = Math.floor(value / 3600);   // 计算小时
    min = Math.floor(value / 60) % 60; // 计算分钟
    sec = value % 60;                   // 计算秒数
    time = hour + ":";                  // 拼接小时部分
    if (min < 10) time += "0";          // 分钟补零
    time += min + ":";
    if (sec < 10) time += "0";          // 秒数补零
    time += sec;
    return time;}

总结

Willes 播放器的引入流程:

  1. HTML 结构:通过特定 class 和 id 构建播放器骨架

  2. CSS 引入willesPlay.css 提供样式和响应式布局

  3. JS 引入willesPlay.js 依赖 jQuery,实现完整的播放控制逻辑

  4. 核心机制:对原生 <video> 标签进行封装,通过事件监听(timeupdate、loadedmetadata、ended)和控制函数(playControl、volumeControl)实现交互


标签: