自定义播放器

全屏操作API
  • Node.requestFullScreen() 开启全屏显示
  • Node.cancelFullScreen() 关闭全屏显示

注意:cancelFullScreen() 的调用时document

h5的api兼容问题
  • 由于其兼容性原因,不同浏览器需要添加前缀如:
    webkit内核浏览器:webkitRequestFullScreen、webkitCancelFullScreen,如chrome浏览器。
    Gecko内核浏览器:mozRequestFullScreen、mozCancelFullScreen,如火狐浏览器。
  • document.isFullScreen检测当前是否处于全屏
    不同浏览器需要添加前缀
    document.webkitIsFullScreen、document.mozIsFullScreen

自定义播放器

多媒体API

音频和视频API一致

方法

方法 描述
addTextTrack() 向音频/视频添加新的文本轨道
canPlayType() 检测浏览器是否能播放指定的音频/视频类型
load() 重新加载音频/视频元素
play() 开始播放音频/视频
pause() 暂停当前播放的音频/视频

属性

属性 描述
audioTracks 返回表示可用音轨的 AudioTrackList 对象
autoplay 设置或返回是否在加载完成后随即播放音频/视频
buffered 返回表示音频/视频已缓冲部分的 TimeRanges 对象
controller 返回表示音频/视频当前媒体控制器的 MediaController 对象
controls 设置或返回音频/视频是否显示控件(比如播放/暂停等)
crossOrigin 设置或返回音频/视频的 CORS 设置
currentSrc 返回当前音频/视频的 URL
currentTime 设置或返回音频/视频中的当前播放位置(以秒计)
defaultMuted 设置或返回音频/视频默认是否静音
defaultPlaybackRate 设置或返回音频/视频的默认播放速度
duration 返回当前音频/视频的长度(以秒计)
ended 返回音频/视频的播放是否已结束
error 返回表示音频/视频错误状态的 MediaError 对象
loop 设置或返回音频/视频是否应在结束时重新播放
mediaGroup 设置或返回音频/视频所属的组合(用于连接多个音频/视频元素)
muted 设置或返回音频/视频是否静音
networkState 返回音频/视频的当前网络状态
paused 设置或返回音频/视频是否暂停
playbackRate 设置或返回音频/视频播放的速度
played 返回表示音频/视频已播放部分的 TimeRanges 对象
preload 设置或返回音频/视频是否应该在页面加载后进行加载
readyState 返回音频/视频当前的就绪状态
seekable 返回表示音频/视频可寻址部分的 TimeRanges 对象
seeking 返回用户是否正在音频/视频中进行查找
src 设置或返回音频/视频元素的当前来源
startDate 返回表示当前时间偏移的 Date 对象
textTracks 返回表示可用文本轨道的 TextTrackList 对象
videoTracks 返回表示可用视频轨道的 VideoTrackList 对象
volume 设置或返回音频/视频的音量

事件

事件 描述
abort 当音频/视频的加载已放弃时
canplay 当浏览器可以播放音频/视频时
canplaythrough 当浏览器可在不因缓冲而停顿的情况下进行播放时
durationchange 当音频/视频的时长已更改时
emptied 当目前的播放列表为空时
ended 当目前的播放列表已结束时
error 当在音频/视频加载期间发生错误时
loadeddata 当浏览器已加载音频/视频的当前帧时
loadedmetadata 当浏览器已加载音频/视频的元数据时
loadstart 当浏览器开始查找音频/视频时
pause 当音频/视频已暂停时
play 当音频/视频已开始或不再暂停时
playing 当音频/视频在已因缓冲而暂停或停止后已就绪时
progress 当浏览器正在下载音频/视频时
ratechange 当音频/视频的播放速度已更改时
seeked 当用户已移动/跳跃到音频/视频中的新位置时
seeking 当用户开始移动/跳跃到音频/视频中的新位置时
stalled 当浏览器尝试获取媒体数据,但数据不可用时
suspend 当浏览器刻意不获取媒体数据时
timeupdate 当目前的播放位置已更改时
volumechange 当音量已更改时
waiting 当视频由于需要缓冲下一帧而停止
细节注意
/*全屏操作后  自带的控制栏会显示  在显示的时候隐藏*/
video::-webkit-media-controls {
    display: none !important;
}
.controls {
    width: 700px;
    height: 40px;
    background-color: rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    position: absolute;
    left: 50%;
    margin-left: -350px;
    bottom: 5px;
    /*比全屏的状态下的视频元素高*/
    z-index: 100000000000;
    opacity: 1;
}

本地存储

document.cookie

使用:

1. 设置cookie数据:document.cookie = '键=值;Expires=日期'
2. 获取cookie数据:document.cookie

1、如果没有设置有效期,会话结束就失效
2、如果设置有效期,依据有效期时间失效
3、在会话过程中,每次请求在报文的头部会携带cookie信息

window.sessionStorage

使用:

1.获取sessionStorage的长度:window.sessionStorage.length
2.根据对应的索引去获取对应sessionStorage的key的值:window.sessionStorage.key(索引);
3.添加/编辑sessionStorage的内容:window.sessionStorage.setItem(键,值);
4.根据对应的key获取对应的的value:window.sessionStorage.getItem(键);
5.根据对应的key删除记录:window.sessionStorage.removeItem(键);
6.清空存储:window.sessionStorage.clear();

1、生命周期为关闭浏览器窗口
2、在同一个窗口(页面)下数据可以共享

window.localStorage

使用:

1.获取localStorage的长度:window.localStorage.length
2.根据对应的索引去获取对应localStorage的key的值:window.localStorage.key(索引);
3.添加/编辑localStorage的内容:window.localStorage.setItem(键,值);
4.根据对应的key获取对应的的value:window.localStorage.getItem(键);
5.根据对应的key删除记录:window.localStorage.removeItem(键);
6.清空存储:window.localStorage.clear();

1、永久生效,除非手动删除 关闭页面也会存在
2、可以多窗口(页面)共享(同一浏览器可以共享)

总结
特性 cookie sessionStorage localStorage
数据生命期 默认关闭浏览器失效 页面会话期间可用 除非数据被清除,否则一直存在
存放数据大小 4K左右(因为每次http请求都会携带cookie) 一般5M或更大 约20M
与服务器通信 由对服务器的请求来传递,每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 数据不是由每个服务器请求传递的,而是只有在请求时使用数据,不参与和服务器的通信
易用性 cookie需要自己封装setCookie,getCookie 可以用源生接口
共同点 都是保存在浏览器端,和服务器端的session机制不同

代码示例

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>视频播放</title>
    <!--字体图标文件-->
    <link rel="stylesheet" href="css/font-awesome.css"/>
    <!--修饰视频播放器样式-->
    <link rel="stylesheet" href="css/player.css"/>
</head>
<body>
<!--多媒体语义标签-->
<figure>
    <!--多媒体区域的标题解释-->
    <figcaption>视频播放器</figcaption>
    <div class="player">
        <!--一开始隐藏 加载可以播放就显示-->
        <video src="./media/fun.mp4"></video>
        <!--自定义控制栏-->
        <div class="controls">
            <!-- 开始播放按钮  -->
            <a href="javascript:;" class="switch fa fa-play"></a>
            <!-- 进度显示区域 -->
            <div class="progress">
                <!--进度显示条-->
                <div class="line"></div>
                <!--默认的灰色进度条-->
                <div class="bar"></div>
            </div>
            <!--时间区域-->
            <div class="timer">
                <span class="current">00:00:00</span> / <span class="total">00:00:00</span>
            </div>
            <!--全屏按钮 取消全屏按钮-->
            <a href="javascript:;" class="expand fa fa-arrows-alt"></a>
        </div>
    </div>
    <input type="text" class="dm"><button class="send">发射</button>
</figure>
<script src="js/jquery.min.js"></script>
<script>
    $(function () {
        /*需求*/
        /*适配jquery对象*/
        var $video = $('video');
        /*视频操作的相关api不在jquery 在dom上*/
        var video = $video.get(0); //$video[0]
        /*播放或者暂停按钮*/
        var $switch = $('.switch');
        /*默认的灰色进度条*/
        var $bar = $('.bar');
        /*显示进度的条*/
        var $line = $('.line');
        /*当前播放时间*/
        var $current = $('.current');
        /*总时间*/
        var $total = $('.total');
        /*全屏或取消按钮*/
        var $expand = $('.expand');

        /*转换格式的方法*/
        var formatTime = function (time) {
            /*处理的业务逻辑*/
            var h = Math.floor(time / 3600);
            var m = Math.floor(time % 3600 / 60);
            var s = Math.floor(time % 60);
            return (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
        };

        /*1. 实现加载效果(需要去判断当视频可以播放,视频显示)*/
        video.oncanplay = function () {
            $video.show();
            /*5. 时间显示 (实时的获取当前的播放时间 转换为需要的格式) 总时间*/
            var duration = video.duration;
            $total.html(formatTime(duration));
        }
        /*2. 播放功能 (点击播放图标 进行播放 需要把当前的按钮改为暂停)*/
        /*3. 暂停功能 (点击暂停图标 进行暂停 需要把当前的按钮改为播放)*/
        $switch.on('click', function () {
            /*播放操作*/
            if ($switch.hasClass('fa-play')) {
                video.play();
                $switch.removeClass('fa-play').addClass('fa-pause');
            }
            /*暂停操作*/
            else {
                video.pause();
                $switch.removeClass('fa-pause').addClass('fa-play');
            }
        });
        /*4. 进度显示 (实时的获取当前的播放时间 需要获取总时间  根据比设置宽度)*/
        video.ontimeupdate = function () {
            /*5. 时间显示 (实时的获取当前的播放时间 转换为需要的格式)*/
            var currentTime = video.currentTime;
            $current.html(formatTime(currentTime));
            /*设置宽度 使用的是 当前播放时间和总时间的比例*/
            var ratio = video.currentTime / video.duration * 100 + '%';
            $line.css('width', ratio);
        }
        /*8. 跃进功能 (获取当前点击的位置和总宽度的比例 去获取需要跳转的时间点)*/
        $bar.on('click', function (e) {
            /*获取点击的位置*/
            var offsetX = e.offsetX;
            /*获取进度条宽度*/
            var width = $bar.width();
            /*计算比例  获取需要跳转的时间点*/
            var ratio = offsetX/width;
            /*需要跳转的时间点*/
            var time = ratio * video.duration;
            /*怎么改变当前播放的时间*/
            video.currentTime = time;
        });

        /*6. 全屏功能 (全屏操作)*/
        /*7. 取消全屏功能 (取消全屏操作)*/
        $expand.on('click',function () {
            /*判断当前是全屏就是*/
            if($expand.hasClass('fa-arrows-alt')){
                $('.player')[0].webkitRequestFullScreen();
                $expand.removeClass('fa-arrows-alt').addClass('fa-compress');
            }
            /*如果不是执行取消全屏操作*/
            else {
                document.webkitCancelFullScreen();
                $expand.addClass('fa-arrows-alt').removeClass('fa-compress');
            }
        });
        /*问题:在使用esc取消全屏的时候  按钮样式不更改*/
        /*1. 方案:监听esc的按键事件 判断keyCode 去更改样式 在全屏操作的时候会禁用key相关事件*/
        /*2. 方案:监听页面尺寸改变  当视频处于取消全屏状态  才去修改样式*/
        $(window).on('resize',function () {
            /*判断全屏状态 如果不是全屏 需要改回全屏按钮*/
            if(!document.webkitIsFullScreen){
                $expand.addClass('fa-arrows-alt').removeClass('fa-compress');
            }
        });

        /*同学们的新需求 */
        $('.send').on('click',function () {
            var text = $('.dm').val();
            var $player = $('.player');
            $player.append($('<span></span>').text(text).css({
                width:200,
                position:'absolute',
                right:-200,
                fontWeight:'bold',
                top:300*Math.random(),
                color:'rgb('+Math.floor(256*Math.random())+','+Math.floor(256*Math.random())+','+Math.floor(256*Math.random())+')',
                zIndex:10000
            }).animate({right:720},10000,function () {
                $(this).remove();
            }));
        });

        /*1. 跃进功能  file://打开 */
        /*2. 谷歌浏览器62  你们的呢? 64版本以上兼容问题  全屏后控制栏可见 不可点击 */
        /*3. 插件 video.js  ckplayer.js */
    });
</script>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容