网页自定义播放器控件时,需要解决比较棘手的问题一般来说就是媒体文件的缓冲效果数据的来源,和任意跳转播放的缓冲数据来源;

这里我只做音频播放控件,以audio为例:

对于媒体的加载可以js触发监控的事件有:

audio.addEventListener("loadstart", function() {// 开始加载
});
audio.addEventListener("durationchange", function() {// 已获得播放时长
});
audio.addEventListener("loadeddata", function() {// 已获得播放头文件
});
audio.addEventListener("progress", function() {// 缓冲下载中
});
audio.addEventListener("canplay", function() {// 可以播放
});
audio.addEventListener("timeupdate", function() {// 播放中
});
audio.addEventListener("canplaythrough", function() {// 可以不发生缓冲下载从头播放到结束,一般来说是加载完成过一次的判断
});

而常用的一般是:

audio.addEventListener("progress", function() {// 缓冲下载中
});audio.addEventListener("timeupdate", function() {// 播放中
});

缓冲下载事件用来监控缓冲数据,目的是为了得到缓冲数据的播放时长,通过该时长再和总时长 duration 相比较就能得到缓冲比例,通过这个比例参数我们就可以根据播放器控件的宽度*比例参数得到缓冲数据需要的偏移量;

通过timeupdate对播放的时间的监控能够得到时时刻刻的currenttime,再比上duration总时长,就能得到时时刻刻的播放效果偏移量;

先说说timeupdate:

该事件是在播放中时时发生的,大约每秒输出一次,可以输出currenttime得到播放中的当前时间点;

比较绕脑的是progress,缓冲:

对于缓冲这个概念有多个角度可以去描述:

1、属性:buffered、seekable

2、事件:seeking、seeked

先说说事件:

当加载媒体文件的时候,一开始加载就会是seeking状态,如果这其中没有打断的情况,比如网络断开、手动点击播放到指定位置等,那么seeking会持续到文件加载结束,结束后触发seeked,而seeked则是seeking触发的false事件结束后的;

但是如果,在加载过程中,手动跳转到了任意一个位置,那么seeking就会被false掉,从而触发seeked;这个概念很重要,他和属性关联性强;

而我们的缓冲的时间数据来源就是buffered属性;

buffered属性有三个参数:

1、length、2、start() 3、end()

buffered.length表示加载的数据的时间范围数;这个时间范围数怎么理解?

举例我有一首3分钟的歌曲

如果数据加载没有任何打断,直接从0加载到了3分钟,那么整个数据的加载时间范围数就是1,可以看成index=0;

如果数据被在50秒处因为网络原因或其他原因打断了一次,表现形式为0-50秒加载完成后就暂时没加载了,那么0-50秒这个片段的时间范围数就是1,index=0,而后自动请求又开始加载从50秒开始加载到一份半产生一个新片段,那么这50-一分半的数据加载就是第二个时间范围数2,index=1;同样的之后又加载一次产生一个新片段3,index=2;

所以总结下来:

buffered的length,通俗的来讲可以说是描述了音频数据加载是否产生的打断事件,记录了有多少的缓冲片段,如果没有被打断过,一个完整的加载,默认的buffered.length = 1,index=0,如果有一次打断,缓冲两次产生2个片段,那么buffered.length=2, 包含index索引[0,1]的片段,三个片段就会有buffered.length = 3 包含index=2的 [0,1,2]片段,所以可以看出,length是加载片段个数,如果没有中断加载,默认是一次完整的加载,所以只会有1个缓冲片段,片段数量判断可位置查询可以通过buffer.length来判断和查询,如果是一次完整的加载,buffered.length = 1,那么加载的数据开始时间和结束时间就可以用start和end来得到;

buffered.start(0)代表第一个缓冲片段的已加载的起始时间,一般来说start(0)就是歌曲开始时间,

buffered.end(0)代表第一个缓冲片段的已加载的结束时间,表示该片段的结束时间,这里的0是个数索引index,和循环很相似;

如果是一次加载类型:start(0)就可以表示歌曲开始时间,end(0)就可以表示歌曲结束时间,注意如果没有打断,end()是持续缓冲变化的,因为缓冲是按时间进行的,不是一次完成,所以只要没有中断,后10秒的end()得到的缓冲结束时间是大于前10秒的end()借宿时间的,同样,因为是根据时间变化,监控buffered.end()需要放在timeupdate事件中,timeupdate监控是时时执行的,只要处于播放状态,大约每秒都会执行一次,所以在timeupdate事件中时时监控buffered.end()能时时得到最新的end()时间;

如果是两次加载类型,这会有两个片段[0,1],那么start(0),表示片段1的开始时间,end(0)表示片段1 的结束时间,同样的就可以获取buffered.start(1)和buffered.end(1),则表示第二个片段的起始时间和第二个片段的结束时间。

为什么会有多个片段?

对于视频文件很好理解,因为视频文件一般来说很大,一次是无法加载完成的,所以加载多次就被分成多个片段;

其实对于mp3这个小文件类型,同样有时候会因为网络波动问题一次网络加载缓冲一段,一般只到50秒左右的样子,之后会断开触发seeked事件,之后会再次触发seeking请求数据事件再加载几十秒的数据,所以如果用本地音频文件作为测试,会直接一次加载全部,所以网络文件可能audio.buffered.length有1/2/3/4/5.....多个buffered.length,而本地文件只有0,这就描述了网络加载产生了多个buffered.length数据时间段,而本地缓冲一次完成,就只有一个时间段;而且用户如果手动点击指定播放位置,肯定会中断;


到了这里,就可以理解为什么在MDN会有这样的代码描述:

  window.onload = function(){var myAudio = document.getElementById('my-audio');var myCanvas = document.getElementById('my-canvas');var context = myCanvas.getContext('2d');context.fillStyle = 'lightgray';context.fillRect(0, 0, myCanvas.width, myCanvas.height);context.fillStyle = 'red';context.strokeStyle = 'white';var inc = myCanvas.width / myAudio.duration;// display TimeRangesmyAudio.addEventListener('seeked', function() {for (i = 0; i < myAudio.buffered.length; i++) {var startX = myAudio.buffered.start(i) * inc;var endX = myAudio.buffered.end(i) * inc;var width = endX - startX;context.fillRect(startX, 0, width, myCanvas.height);context.rect(startX, 0, width, myCanvas.height);context.stroke();}});}

这里监控seeked就表示监控是否产生打断事件,如果没有产生,就是一次加载,那么在加载完成后直接把整个进度条全部更新颜色,如果产生了打断,那么表示只加载了部分,那么就去遍历获取buffered.length,从第一个片段开始,获取到最新的一个片段,而start()和end()遍历buffered.length 的index;得到每个片段的时间点,在和总时间对比得到进度条需要改变的比例,再更新缓冲颜色实现部分缓冲的更新;由于网络加载一般来说都不会是一次加载完成的,所以一般都会有多次seeked;

如果buffered.length = 0 ,则无法输出start和end,所以可以加入一个if判断buffered.length


上面的seeked事件监控已经可以得到数据从而写出缓冲的进度条了,但是个人建议通过progress缓冲事件再监控seeked事件,再定义默认页面不触发媒体加载,通过按钮触发媒体加载,可以更好的得到用户点击按钮再缓冲播放歌曲的效果;


本人测试结果:

输出结果 :

分析结果:

对照输出顺序和代码顺序,可以看出,当我点击播放的时候会先触发progress缓冲,然而触发progress缓冲并不是立即的到audio的buffered.length,需要等待到 durationchange事件,即得到时长数据后才会得到buffered.length,所以一开始progress事件中buffered.length = 0,这时候如果直接输出berffered.start(0)和buffered.end(0)会报错,因为都没有得到数据,避免这种报错只需要判断下buffered.length != 0即可;

html audio缓冲效果实现相关推荐

  1. 《javaScript100例|04》自动播放——Js幻灯片缓冲效果

    目录 效果图 示例 源码地址: 效果图 示例 <html> <head> <title>自动播放--幻灯片缓冲效果</title> <style& ...

  2. php 漂浮广告代码,JavaScript实现带缓冲效果的随屏滚动漂浮广告代码

    本文实例讲述了JavaScript实现带缓冲效果的随屏滚动漂浮广告代码.分享给大家供大家参考,具体如下: 这里演示了始终随屏滚动的JavaScript代码,在国内的应用泛滥成灾了,特别是一些喜欢漂浮广 ...

  3. HTML滚动条平滑移动,孟欣 - JS缓冲效果,平滑移动(滚动条平滑滚动)

    JS缓冲效果,平滑移动(滚动条平滑滚动) 举个栗子: 点击导航栏的锚点,改变scroll的位置.(页面不是瞬间闪到,有个缓冲的效果) 点击button,页面瞬间闪到目标位置,这个功能很简单,不再啰嗦 ...

  4. css easeoutbounce,缓冲效果插件easing用法

    本站的导航条二级菜单展开缓冲效果就是使用插件easing实现的,类似弹簧的缓冲效果... 在实际应用中偶尔会使用到这个插件以实现缓冲效果,现在这里记录下插件easing的用法.此插件依赖jquery库 ...

  5. ios开发学习--音频声效(Audio)效果源码分享--系列教程

    1.教程 1)iOS 音频开发之CoreAudio http://blog.csdn.net/xinruiios/article/details/8946251 2) iPhone/iPad 2012 ...

  6. 层展开/关闭 - 运动缓冲效果

    http://bbs.blueidea.com/thread-2843406-1-1.html 效果一:http://www.chenbincb.com.cn/cnblogs/demo3/1.html ...

  7. 【持续加精】几种强哥墙裂推荐的缓冲效果,各有千秋、各取所需

    transition: .618s ease;//中庸(符合大部分年龄层次的人对动效的审美)transition: .2s ease-out;//城乡结合部动效(虽然low逼,但是实用)transit ...

  8. DIV遮罩层--数据缓冲效果的实现

    这个非本人所写,拿的网上的自己改了下 JS代码: View Code function sAlert(str) {var msgw, msgh, bordercolor;msgw = 300;//提示 ...

  9. Java 缓冲流简介及简单用法

    在java编程中, 我们有时会听到缓冲流和原始流等字眼. 其实在之前的博文中, 提到过流可以分为原始流和处理流. http://blog.csdn.net/nvd11/article/details/ ...

  10. 使用Skrollr创建视差滚动效果页面

    视差滚动(Parallax Scrolling)是指多层背景以不同的速度移动,形成立体的运动效果,带来非常出色的视觉体验.随着用户对视觉体验的要求不断提高,WEB开发者开始 在网页中加入各种特效元素以 ...

最新文章

  1. 【Live555】live555源码详解系列笔记
  2. unity, TRANSFORM_TEX
  3. Vuforia 6.1提供4个版本下载
  4. python对象复制_Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
  5. python recv
  6. php 正规标题,一些PHP面试标题
  7. 怎么让前端项目运行起来_如何立即使您的前端项目看起来更好
  8. BRI OS 高级ping
  9. bin文件如何编辑_每日学习:Linux文件与目录管理常用命令解析
  10. oracle 19602,Oracle CPU Costing
  11. Flash Professional CS6 安装zxp插件
  12. 北邮计算机 六级,【北邮晚安】大学宿舍关系分六级,你在哪一层?
  13. JAVA+selenium+testNG QQ邮箱登录及邮箱发送
  14. 在线装机测试软件,完美装机大师工具V3.0专业版
  15. pandas 合并表格时出现unnamed列,和顺序被打乱的问题
  16. 混音师的混音之道|公开我学习混音的方法,真正的捷径|MZD Studios
  17. 模拟Android内存不足 activity回收 值保存 状态恢复
  18. t420i升级固态硬盘提升_固态硬盘能提升游戏性能吗
  19. go并发之道学习总结
  20. 搭建局域网,通过DHCP实现电脑自动获取IP地址

热门文章

  1. 个人笔记:kali firefox安装hackbar插件
  2. 球球大作战服务器维护时间,2018球球大作战每日解除限制时间是几点 | 手游网游页游攻略大全...
  3. 把脉大连接:“多端协同”的大动脉与“多人协作”的主动脉
  4. 验证苹果商店服务器通知 responseBodyV2
  5. 吴晓波罗振宇2019跨年演讲感想
  6. Alt键一直处于按下状态 解决办法
  7. 班得瑞[Bandari]音乐介绍
  8. docker容器中安装jdk8,压缩包下载
  9. 论文笔记:多标签学习——ACkEL算法
  10. idea显示Multiple Spring Boot run configurations were detected. Services allows to manage multiple run