Share via


HTML5中为一个简单的MP3播放器做音频 fallback标签比你想象的要难

[原文发表地址] Fallback HTML5 audio tags for a simple MP3 podcast are harder than you'd think

[原文发表时间] 2013-03-26

我最近花了好几个晚上和周末来重新设计博客和Hanselminutes播客站点。之前我没意识到这个播客站点有多糟糕。我想以后能扩宽受众群体,因为目前的受众面有些窄。现在我在给这个站点六年来360多人添加头像

同时,非常感谢来自Portland Girl Geek Dinners的Lynsey Smith,因为她很努力的为我寻找图片!

我仍旧希望有更好的浏览器内置音频体验,所以假定我只是减少了音频标签并且完成了,对吧?

这个HTML5的音频标签不错吧?这样就行了,梦寐以求啊:

 <audio id="audioplayer" preload="metadata" type="audio/mp3" >
     <source src="https://s3.amazonaws.com/hanselminutes/hanselminutes_0363.mp3" type="audio/mp3"/>
 Your browser doesn't support the HTML audio tag. Be sad.
 </audio>

如果你喜欢,可以到https://jsfiddle.net/CdxbX/来试一下。

没有比这更容易的了。

这是在IE9+中看到的:

clip_image002

Chrome中:

clip_image004

Firefox,version19:

firefoxaudiotag

呃,这个版本的Firefox现在还不支持MP3音频,所以它只是闪了一下就消失了。Firefox很快就会支持MP3音频,虽然是用底层的操作系统来播放流文件而不是自己的内置代码。

在windows7及以上版本的Firefox20(beta版)上,你可以通过在about:config中打开media.windows-media-foundation.enabled来测试MP3音频的支持情况

让我失望的是HTML5有很多规范问题,你可以注意到尽管我有些fallback文本,但在Firefox中看不到。这是因为fallback元素只有在你的浏览器完全不支持音频标签的时候才会用到

这根本不是我想要的。我想要的是“可以支持这些音频资源吗?不行?那就显示fallback中的内容”。对我来说这样比较直观。

我通过在Mozilla工作的Christian Heilmann联系到了Chris Double并和他谈了这个问题,他说,“你需要使用WHATWG/W3C来解决这个问题。之前已经有过争论。”以前确实有过,从2009年10月开始,更多的人说用这种方式fall back不够直观:

我期望的(在这种情况并不正确)是如果我只放了一个源元素(比如一个MP4),Firefox将使用fallback内容,如果我包含一个不支持格式的对象元素(比如,如果我使用一个QuickTime的对象,但是我没有安装QT,这时用户会看到fallback内容),它确实是这样。在我看来,这种情况下唯一的选择是依靠Javascript和视频元素的canPlayType()函数。——Kit Grose

缺少直观的后备内容意味着我无法仅仅用HTML来制作普遍适用的音频播放器。因此我不得不选择使用JavaScript来处理这种基础的需求,这样太失败了。

让HTML5的音频在所有浏览器上正确fall back

你只能用JavaScript动态创建一个音频标签,然后审查这个标签。这不仅适用于音频标签,也适用于视频标签。最后我贴上从我朋友Matt Coneybeare那弄来的代码。

 <audio id="audioplayer" preload controls loop>
     <source src="audio.mp3">
 </audio>
 <script type="text/javascript">   1:     2:     var audioTag = document.createElement('audio');   3:     if (!(!!(audioTag.canPlayType) && ("no" != audioTag.canPlayType("audio/mpeg")) && ("" != audioTag.canPlayType("audio/mpeg")))) {   4:         AudioPlayer.embed("audioplayer", {soundFile: "audio.mp3"});   5:     }</script>

AudioPlayer.embed方法在最后嵌入了一个独立格式的WordPress音频播放器,这样在Firefox中当canPlayType函数返回false的时候,就有个flash播放器了。

clip_image006

HTML5中一个反应迅速并且触摸操作友好的音频播放器

不管怎么说,<audio>标签制作出来的默认音频播放器实在是有点挫,而我希望它能更好的支持触摸,在平板上看起来更棒等等。为此,我转向Osvaldas Valutis的音频播放器。这是个很好的 jQuery小插件,它把<dudio>标签元素替换成一堆可爱的HTML代码块。其实你无法真正改变HTML5的<audio>标签元素样式,人们只是隐藏它,重建它,然后设法再去调用这些隐藏但还工作的音频元素。

这个插件,配上少许默认色彩的CSS样式,给我带来一个很棒的音频播放器,它看起来都一样,并且在在任何地方都能工作。除了在Firefox19/20,要等到下个版本Firefox对canPlayType函数的返回值为true时,这个插件就能工作了!在此之前,用的是flash的fallback播放器,也是很好用的。

clip_image008

另一个问题是很多Firefox用户都安装QuickTime插件。当渲染Osvaldas的音频播放器时,JavaScript审查会让Firefox浏览器提醒大家没安装它的请安装,而安装后播放器还是无法使用。

最后我对Matt的代码小小的修改了下,让它支持Osvaldas播放器。我发现代码变得更加动态了,所用元素更少,不过这让我阅读起来更容易。

  • 首先,试着用音频标签。有用吗?非常有用,生成播放器;
  • 不支持MP3音频?动态生成一个flash播放器。隐藏音频播放器(好像不需要)

不幸的是,对于代码的可读性,有HTML格式的“.audioPlayer”jQuery插件,还有内嵌的“音频播放器”flash。它们虽然不同,但是名称相同,我没有修改他们,J

 <audio id="audioplayer" preload="auto" controls style="width:100%;" >
     <source src="your.mp3" type="audio/mp3">
         Your browser doesn't support the HTML audio tag. You can still download the show, though!
 </audio>
     <p id="audioplayer_1"></p>
 <script type="text/javascript">   1:     2:     var audioTag = document.createElement('audio');   3:     /* Do we not support MP3 audio? If not, dynamically made a Flash SWF player.  */   4:     if (!(!!(audioTag.canPlayType) && ("no" != audioTag.canPlayType("audio/mpeg")) && ("" != audioTag.canPlayType("audio/mpeg")))) {   5:         AudioPlayer.embed("audioplayer_1", {soundFile: "your.mp3", transparentpagebg: "yes"});   6:         $( '#audioplayer').hide();   7:     }   8:     else /* Ok, we do support MP3 audio, style the audio tag into a touch-friendly player */   9:     {  10:         /* If we didn't do the "if mp3 supported" check above, this call would prompt Firefox install quicktime! */  11:         $( '#audioplayer' ).audioPlayer();  12:      }</script>

总之,目前为止很好用。

奇怪的Bug 当我的站点加载评论的时候,音频播放器被阻止了,Chrome看起来似乎卡住了。有JavaScript专家想说两句的吗?如果加载一个页面—— 就像这个 —— 在页面加载完成之前点击播放器,音频没有放出来。这个问题只发生在Chrome 。有啥想法吗?

看到这,考虑下订阅https://hanselminutes.com吧!这“为开发者注入了新鲜的空气”。