API的魅力:H5让Web页面轻松控制多媒体音视频

   日期:2020-07-02     浏览:107    评论:0    
核心提示:猛的发现最近做了超多关于音乐的东西:Web-app、微信小程序、Electron、TS...emmmmmmm还缺一个最重要的:我们不妨再来看看原生JS中是如何帮助浏览器解决音乐和视频的困惑的!

常见的音频/视频文件格式:

文件格式 所用【容器】 说明
*.oga/ *.ogv OGG 一个自由开放标准的容器格式。Ogg格式并不受软件专利的限制,能够设计用于高效处理流媒体和高质量数字媒体。可以纳入各种自由开放源代码的编解码器,包含音效、视频、文字与元数据的处理,是HTML5视频常用的一种格式
*.avi AVI 即把视频和音频编码混合在一起储存,应该是最常见的音频视频容器了。支持的音视频编码也是最多的
*.mp4 MP4 MPEG-4编码,是HTML5视频常用的格式
*.wmv/ *.asf ASF 能够用于流传送。还能包容脚本。ASF封装的WMV视频还具有“数位版权保护”功能
*.mov MOV 具有较高的压缩比率和较完美的视频清晰度,而且还可跨平台
*.wav WAV 一种音频容器,常说的WAV就是指没有压缩的PCM编码,其实WAV里还包含MP3等其它ACM压缩编码
*.webm WebM Google基于MKV容器开发的一个免费的媒体容器格式,据说其极具效率,可以在netbook、tablet、手持装置上顺畅使用

HTML5 Video&Audio API

以前包括现在,网页中播放视频或音频的主要方式还是Object调用Flash插件、QuickTime插件或Windows Media插件向HTML标签中插入视频,相对于这种传统方式,使用HTML5的媒体标签的好处可是太多了

  1. 作为浏览器原生支持的功能,新的audio元素和video元素无需安装任何东西 —— 尽管有些插件安装率很高。
  2. 可以避免插件带来的安全问题,比如信息泄露、弹窗广告
  3. 有些插件很难和页面其他内容相集成
  4. 媒体元素向页面提供了通用、集成、可脚本化控制的API。对于开发人员来说,使用新的媒体元素后,可以轻易地使用脚本来控制和播放内容。

浏览器支持性检测

我们当然可以通过 html5test.com 或者一些其他工具来检测出浏览器是否支持 <video><audio> 标签。
事实上,目前应该几乎所有浏览器都已经“完美”支持HTML5了 —— 就连IE9也是这样。真是件令人高兴的事情。

但浏览器品种良多,且依赖第三方检测并不是妥善之举。所以检测浏览器是否支持video和audio标签最简单的方式就是:用脚本创建,然后检测其属性是否存在:

var canPlay=!!(document.createElement('video').canPlayType);

这会在内存里动态创建一个video元素(不显示在页面上!),然后去检查其独有的canPlayType()方法是否存在,其它独有的方法/属性也可以检测出来。
通过 !! 运算符将结果转为布尔值,这样就可以知道视频对象是否创建成功,也就是说明浏览器是否支持视频。
这段代码你完全可以放在onload中给用户以“恰当的”提示,但如果不是用JS渲染页面元素(js动态渲染HTML)的话,其实我们有更好的方法:

如何使用video/audio元素

接着上面的说:如果你实在浏览器太垃圾,检测结果不支持,但是项目中又需要用到,可以触发另一部分代码去向页面中插入传统的媒体播放代码。除此之外,还可以在video和audio元素中放入备选内容 —— 以防不测:比如把Flash插件播放同样内容的代码作为备选内容

//如果无需兼容,给用户简单提示即可
<video src="xxx.mp4">
	你的浏览器不支持video标签,请尝试支持html5!
</video>
//如果要兼容插件
<video src="xxx.mp4" controls>
	<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
		<param name="movie" value="xxx.swf" />
		<embed type="application/x-shockwave-flash" src="xxx.swf"></embed>
	</object>
</video>

(controls属性:是否显示自带视频控制控件)
浏览器执行这段代码时,如果支持HTML5,那么 <object> 标签里的代码就会被忽略,反之则用object设置的classid插件编号去调用系统里的插件 —— 这段代码中就是Flash Player的ID,然后播放对应文件。

这里的 <embed> 标签是在非IE或非Window环境下被使用,这种object(-?)embed的混合写法正是Macromedia公司所提倡的兼容写法

另一种兼容:浏览器兼容

上面说的是浏览器不支持video/audio元素时的插件兼容,但是不同浏览器之间也会有差异:这时就需要用到 <source> 标签进行浏览器(文件格式)兼容了:

事实上,我们可用下面的js代码来检测浏览器最真实的对文件格式的支持情况

document.createElement('video').canPlayType("video/ogg");
document.createElement('video').canPlayType("video/mp4");
document.createElement('video').canPlayType("video/webm");
document.createElement('video').canPlayType("video/webm; codecs='vp8.0,vorbis'");

如果返回probably,表示最有可能支持;如果返回maybe,表示也许支持;如果返回空字符串,则表示不支持。
用脚本方式兼容不同格式只是其中一种方法,而source标签的方式及其为大众所接受:

<video controls>
	<source src="xxx.mp4" />
	<source src="xxx.ogv" />
	<source src="xxx.webm" />
</video>

这样浏览器会自行去检测支持的格式,并读取播放,不支持的则自动忽略。

用的时候,可以把上面几段HTML-video代码合并一下即可。(若是“音频”,将video换成audio,src里面的路径也换成mp3之类的格式就行啦)

JavaScript对属性的控制

其实video/audio中HTML5控制的属性中常用的就那么几个:src、controls、loop(循环播放)、preload(预加载,和autoplay冲突)、height、width、poster(封面)、muted(是否输出视频声音)。
我们还是来说下视频中JavaScript的作用:
比如音量值volumn、播放总时长duration、是否结束播放ended、暂停paused、当前播放时间currentTime等,这些都是可以在对应事件中获取并赋值的!

这里就要说说video/audio元素的主要事件:

  • onloadstart:浏览器开始查找音视频
  • ondurationchange:音视频时长已修改
  • onloadedmetadate:已加载音视频元数据时;比如设置当前播放时间点为15s处:dom.onloadedmetadata=function(){dom.currentTime=15;}
  • onloadeddata:浏览器已加载当前帧时
  • onprogress:浏览器正在下载音视频
  • oncanplay:浏览器正在播放音视频
  • onpause:音视频已暂停
  • onplay:音视频已开始或不再暂停
  • ontimeupdate:当前播放位置已更改
  • onvolumechange:音量已修改

在实际项目中我们一般采用addEventListener监听的方式触发:

比如笔者最近做的仿小米官网视频播放列表中,就对这些事件有使用:

//videoContent: 视频元素
//videoTimes: 当前/总时间(通过selectAll获取的数组)
//videoProgress: 进度条元素(通过selectAll获取的数组)

//监听视频加载完毕执行事件
videoContent.addEventListener('canplay',()=>{
	videoTimes[1].innerHTML=formatTime(videoContent.duration);   //formatTime:自定义时间处理函数
})
//监听视频播放事件执行事件
videoContent.addEventListener('play',()=>{
	videoPlay.className="...";
	timer-setInterval(playing(),1000);
})
//监听视频暂停事件执行事件
videoContent.addEventListener('pause',()=>{
	videoPlay.className="...";
	clearInterval(timer);
})
function playing(){   //正在播放中
	let scale=videoContent.currentTime / videoContent.duration;
	let scaleSuc=videoContent.buffered.end(0) / videoContent.duration;
	videoTimes[0].innerHTML=formatTime(videoContent.currentTime);
	//进度条All获取的三个元素要分别设置当前位置、加载位置、进度条上小球位置
	videoProgress[0].style.width=scale*100+'%';
	videoProgress[1].style.width=scaleSuc*100+'%';
	videoProgress[2].style.left=scale*100+'%';
}

如何通过按钮对视频进行控制呢:

//videoPlay: 播放/暂停按钮元素
videoPlay.addEventListener('click',()=>{
	if(videoContent.paused){
		videoContent.play();
	}else{
		videoContent.pause();
	}
})
`videoContent.buffered.end(0)` 为【缓存节点时间】,是video控件自带,实时监听,其值永远大于等于【当前时间currentTime】。常用来渲染“加载进度”

常见的小应用

相信还在刷网课的各位已经对学校网站及其不耐烦了吧。和一些国外视频网站一样,通常在列表中采用了鼠标悬停播放视频的效果,让当前用户能够“一直停留在此网页上”。
其实这就是利用了在通用事件onmouseover和onmouseout中控制视频的播放和暂停:

<video id="xxx" onmouseover="this.play()" onmouseout="this.pause()">
	<source src="xxx.mp4" />
	<source src="xxx.ogv" />
</video>

其实,若是“无限视频列表”,我们完全可以用【事件代理】来提高性能。

相关参考:

  • https://developer.mozilla.org/zh-CN/HTML/Element/video
  • https://blog.csdn.net/ffffffff8/article/details/78030610
  • https://blog.csdn.net/qq_43624878/article/details/102694623
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服