audio和video标签兼容IE8的方法
audio/video 是 HTML5 标签,IE8 不支持。兼容方案:1. 用 IE 条件注释给老浏览器加 embed 标签;2. JS 判断浏览器类型动态插入;3. 引入 html5media.js 库自动降级到 Flash 播放器。推荐方案3最省事,一行 script 搞定。
HTML5 给了我们 <audio> 和 <video>,想在页面上放个音频视频,跟写个 <input> 一样简单。
但只要项目还得照顾老 IE,麻烦就来了:IE8 这些老家伙压根不认这俩标签。
这篇把当年处理音视频兼容的几种办法捋一遍。虽然现在 IE 基本进博物馆了,但这套"新特性 + 降级兜底"的思路,到今天写兼容照样用得上。
先认识这几个标签
能往页面塞音视频的标签不止一个:object、embed、audio、video。
它们效果大体一样,但脾气不太一样:
object/embed:老牌选手,页面一打开默认就自动播,控制条是插件自带的,固定杵在那。调大小也比较生硬,改 width、height 不会联动。audio/video:HTML5 新标签,长得更顺眼,改 width 时 height 会等比缩放,控制条样式也更现代。
简单说,功能上差不多,新标签胜在美观和可控。但新标签有个硬伤——老浏览器不认。
兼容的死结在哪
HTML5 这些新标签,在老 IE 里直接当空气,啥也不显示。
而老浏览器时代,网上的音视频播放基本是靠插件撑着,最典型的就是 Flash。
比如当年优酷的 flash 播放器,就是一坨 embed:
<!-- 老式 Flash 播放器,靠 embed 加载一个 swf -->
<embed src="http://player.youku.com/player.php/sid/XXX/v.swf"
type="application/x-shockwave-flash"
width="480" height="400"
allowFullScreen="true" allowScriptAccess="always"></embed>
所以兼容的核心矛盾就一句话:新浏览器想用好看的 HTML5 标签,老浏览器只能退回去用 embed/插件。
怎么让同一个页面在两边都能放出声音,就是下面几个方案要解决的。
两个标签的基本写法
先把 audio 和 embed 各自怎么写摆出来,后面方案都是在这俩基础上组合。
audio 标签,属性都在注释里:
<!-- controls:显示播放控制条 -->
<!-- autoplay:就绪后自动播放 -->
<!-- loop:循环播放 -->
<!-- preload:页面加载时预加载音频(有 autoplay 时此项无效) -->
<audio controls="true" autoplay="true" loop="loop" preload="auto">
<source src="mebugs.mp3"></source>
</audio>
<!-- 从兼容角度,也可以把 src 直接写标签上 -->
<!-- 标签内的文字会在浏览器不支持时显示出来,当兜底提示 -->
<audio src="mebugs.mp3">
您的浏览器不支持 audio 标签
</audio>
embed 标签给老浏览器用:
<!-- embed 必须有 src;autostart 控制是否自动播放 -->
<embed src="mebugs.mp3" autostart="false" />
方案一:条件注释直接双写
最直白的办法:两个标签都写上,用 IE 条件注释让老 IE 只认 embed 那份。
<!-- 现代浏览器走这个 -->
<audio id="play_new" src="mebugs.mp3" autoplay="true">
您的浏览器不支持 audio 标签
</audio>
<!-- IE8 及更老的版本,才会执行注释里的 embed -->
<!--[if lte IE 8]>
<embed id="play_old" type="audio/mpeg" src="mebugs.mp3" autostart="false"></embed>
<![endif]-->
<!--[if lte IE 8]> 是 IE 专属的条件注释,意思是"IE8 及以下才生效",其他浏览器把它当普通注释忽略掉。
好处是简单粗暴,缺点是页面上会多塞一个元素,不太干净。
方案二:JS 判断浏览器动态插
嫌双写脏,可以用 JS 先认一下浏览器,再决定插哪个标签。
// 粗略判断浏览器类型
function browserType() {
var nv = navigator.userAgent.toLowerCase();
// trident 是 IE 的内核标识,新版 IE 不一定有 msie 字样
if (nv.indexOf("msie") > 0 || nv.indexOf("trident") > 0) { return "IE"; }
else if (nv.indexOf("chrome") > 0) { return "Chrome"; }
else if (nv.indexOf("firefox") > 0) { return "Firefox"; }
else if (nv.indexOf("safari") > 0) { return "Safari"; }
else { return "Unknown"; }
}
var bt = browserType();
var box = document.getElementById("player_div");
if (bt === "Chrome" || bt === "Firefox") {
// 现代浏览器用 audio
box.innerHTML = "<audio autoplay='true'><source src='mebugs.mp3'></source></audio>";
} else {
// 其余(含老 IE)退回 embed
box.innerHTML = "<embed src='mebugs.mp3' autostart='false' />";
}
这样页面干净些,但靠 UA 字符串猜浏览器本就不太靠谱,判断逻辑还得自己维护。
PS:真要做特性检测,更稳的是看 document.createElement('audio').canPlayType 存不存在,而不是认 UA。不过当年图快,就先这么用了。
方案三:html5media 一把梭
前面两个都得自己操心兼容逻辑,有没有更省事的?有,html5media 这个库。
它是个不依赖任何框架的纯 JS 类库,专门让 audio / video 在老 IE 里也能用。
原理是:浏览器支持 HTML5 就正常走原生标签;不支持就自动切成 Flash 版的 Flowplayer 播放器顶上。
引入很简单,塞 head 里一行:
<!-- 建议下到本地引,别依赖外链 -->
<script src="http://api.html5media.info/1.1.6/html5media.min.js"></script>
<!-- 想省流量,也可以只让老 IE 加载它 -->
<!--[if lte IE 8]>
<script src="http://api.html5media.info/1.1.6/html5media.min.js"></script>
<![endif]-->
引完之后,页面里就只管正常写 HTML5 标签,剩下的降级它全包了:
<!-- 直接写,不用自己判断浏览器 -->
<video src="mebugs.mp4" width="800" height="600" controls="true" preload="auto"></video>
<audio src="mebugs.mp3" controls="true" autoplay="true"></audio>
<!-- 哪怕在 IE8 甚至 IE6 里,这俩标签也能放出来 -->
对懒人来说这是最香的——一行 script,不用自己写一堆分支判断。
现在还需要这么做吗
说句实在话,今天写新项目基本不用操这份心了。
IE 已经被微软自己停掉,主流浏览器全面支持 audio / video,Flash 更是早就凉透。
直接写原生标签,顶多用 <source> 挂多个格式(mp4、webm)照顾不同浏览器的编码支持,就够了:
<video controls width="800">
<source src="mebugs.webm" type="video/webm">
<source src="mebugs.mp4" type="video/mp4">
您的浏览器不支持 video 标签
</video>
所以这篇的三个老方案,更多是留个记录。真正能带走的,是那个思路:用新特性,但给不支持的环境留一条降级的后路。这套路放在今天做任何浏览器兼容都成立。
小结
音视频兼容的老问题,本质是 HTML5 新标签遇上不认它的老 IE。
三条路:条件注释双写最直接、JS 判断浏览器动态插更干净、html5media 库自动降级最省事。
现在 IE 退场,原生标签 + 多 <source> 就够用了,前面那些兜底可以收进历史。
但"新特性配降级兜底"的思路留着,哪天再碰上某个新 API 老环境不支持,照这个套路来就行。
