那些年,我们一起被坑的H5音频

原文地址:http://weibo.com/p/23041874d6cedd0102vkbr

不要被这么文艺的标题吓到,这里不会跟你讲述中学时期泡妞史,也不会有其它什么现实不该有而小说噼里啪啦不能没有的坑爹情节,请注意,这是一篇技术类文章,主要讲的是:音频在移动端的兼容问题,至于为什么标题要起的这么文艺,这只是为了迎合下这条微博而已:

神马?你还没关注我新浪微博 - 桑尼真?果断走起吧,我不会晒自拍刷屏不会买面膜,有的只是吐槽跟技术类的分享,欢迎关注…

好了,前面按惯例废话了不少,下面我们来说下,音频在移动端的那些坑,坑的具体表现与填坑方式…

我私自把 音频分两种,背景音乐与音效音乐;

一、背景音乐

背景音乐,就是贯穿整个页面的音乐,一般挑选节奏与曲风页面表达主题搭配,比如旅行类的页面,我可能会挑选《TravelingLight》这样的轻快节奏的,清新乡村一点,让用户听了,感觉就真的要放下包袱去旅行的感觉;而游戏类体验类的页面,可能会挑选《TheTime HasCome》这样快节奏,rap&rock系的,感觉就是在游戏里面打击的那种节奏感;而对于那种少女系萌萌哒的页面,可能会挑选《Downby the sallygarden》这种轻淡旋律,符合思春少女的心境的风格…不过背景音乐类型一般以轻音乐类型为主,作为衬托主题辅助作用,节奏太重不宜长听…

选曲风格大概就如上面所述,在页面播放背景音乐的话,一般就是进入页面,背景音乐自动响起,音量由小到大渐入,到收尾的时候,音量由大到小渐出,然后再循环这样的过程,那把上面的过程用HTML5代码转化的话,就是这样代码流程的:

首先new audio,创建一个audio音频对象,赋值音频src地址,设置loop循环,检测它的readystatey音频当前就绪状态,等于4 HAVE_ENOUGH_DATA的时候,表示可用数据足以开始播放,或者监听canplaythrough事件/canplay事件,canplaythrough表示歌曲已经载入完全完成,而canplay表示缓冲至目前可播放状态,前者是完全加载好了才播,后者是加载到当前网络状态能播就播,不一定完全加载,边播边载,可能会快一点,不过如果播一部分后网速变慢,或者断网,音乐可能就会卡顿…当加载完成后,就play播放音频,大概就是这样的流程,具体代码:

function musicPlay(){
       var audio =document_createElement_x_x("audio");
       audio.src ="media/thunder.mp3";
       audio.loop =true;
      audio.load();
      audio.addEventListener("canplaythrough", function(){
         audio.play();
      },false);
}
   
musicPlay();

测试地址: Demo
二维码:

上面代码看起来正常,网上找的代码也是这样的,在电脑上面播也是ok的,然后当你欢心喜地在手机上面播的时候,TNND,坑爹啊…有砸手机的冲动…就上面的流程,会发现在IOS手机上面压根就没声音好吗!玩笑不能这样开的好吗!这是想闹哪样(PS:安卓4.1以上都是可以的)…用无线网卡+fiddler抓包调试,手机配代理后,居然可以正常播放,相当奇葩…

IOS手机请扫下面二维码:

是否听到了阵阵打雷声?与之前的代码比较,其实将 audio添加到html页面节点而已,然后IOS就能正常识别了,这个安卓相对而言要好些…

对于背景音乐播放的,我上面提到,可以做一个“音量由小到大渐入,到收尾的时候,音量由大到小渐出”这样的效果,这样不会让用户一进页面,就马上最大音量轰炸,有多少人开会或者在图书馆被这样的突入起来的背景音乐吓到,麻烦举下手,诚实点我们还可以做朋友的…

音量的话,audio也有相应的控制属性volume,设置范围为0-1,0的时候为静音,也有一个专有静音属性muted与之对应,1的时候是音频原有音量,然后我在PC上,就写了这样一个定时器:

audio.volume=0.01;
timer_volume_up=setInterval(function(){
         if(audio.volume<0.15){
            audio.volume+=0.01;
          }
          else{
            audio.volume=0.15;
            clearInterval(timer_volume_up);
          }
},1000);

刚播放的时候,声音音量为0.01,然后1s加0.01,直到0.15的时候,就停止,清除计数器,做一个声音渐入的效果,调节时长15s;

timer_count=setTimeout(function(){
            timer_volume_down=setInterval(function(){
               if(audio.volume>0.01){
                  audio.volume-=0.01;
                }
                else{
                  audio.volume=0.01;
                  clearInterval(timer_volume_down);
                }
              
            },1000);
},parseInt(audio.duration*1000-15000));

音频的时长可以用duration是音频长度,单位为秒,获取audio.duration乘以1000,化作毫秒,减去15000,就是音频离结束前15秒,检测音频音量是不是大于0.01,如果是,就1s减0.01,直到0.01为止,15秒,刚好音频结束,做为淡出

演示地址:Demo
二维码:

PC上面听起来是不是很正,首次打开的时候,因为音量很低,所以不会给用户突入起来的感觉,如果用户所在场合不适合有声音,可以有足够的时间将手机设置为静音,然后继续浏览页面;而且音乐循环起来没那么硬,感觉就被无缝连接一样,很舒适的就循环起来了,有木有…

然后用IOS扫二维码,瞬间崩溃,又来坑爹了…
在IOS手机上面就算直接设置了volume 0.01,他还是最大音量 1,这里的话,是苹果的设定,具体可以见《Safari HTML5 Audio and Video Guide》一文:

On iOS devices, the audio level is always under the user‘s physicalcontrol. The volume property is not settable in JavaScript. Readingthe volume property always returns 1.

意思就是说,屌丝程序猿你吖别瞎操心,老子这里只能最大声…
对于安卓,没有什么详细的资料说不支持,不过我拿安卓4.4测试,好像也是无效…
如果想在手机上实现跟PC一样的效果,目前别太指望代码,老老实实调整音频源文件吧…

那对于背景音乐,单放一首,会不会太单调啦?那就来个多音频顺序播放呗,可以这样,监听单曲的onended事件,然后当音频ended播放完毕后,就play播放下一首,我们来看下实例:

演示地址: Demo
二维码:

PC上正常,会听到两声雷声的音频,然后就哔哔哔的车笛声,循环播放;
在IOS上,也可以正常播放,但是安卓4.4它获取不到onended事件,不支持,所以雷声过后,就没有哔哔哔…
这里可以用setInterval计算好每个音频的时间,手动循环播放,不过这样时间点会由于loading时加载延迟,对的不准,可能播一半就又重新播了…

对于背景音乐自动播放问题,就IOS而言,在微信里面,页面加载后调用play是可以正常播放音乐的,但是在同个手机safari上,它是不能自动播放的,因为IOS系统为了防止网页浪费用户流量,需要用户在该页面进行操作(比如划屏,点击)后,,才能播放音频,视频同理,所以在safari打开后,一切都是那么安静…这里解决方法,可以做一个音频按钮,引导用户选择需不需要背景音乐,然后就有了用户操作,人性化的伪装,啊哈哈…

背景音乐的问题,目前我碰到的基本都罗列出来了,那么我们进入下一个话题:音效音乐

二、音效音乐

音效音乐,就是在页面中,点击按钮的啪嗒声,物品掉落的嘎达声,成龙头发特技的duangduang声,这些用于辅助页面,让动态交互效果更加真实,贴近实际的音频;一般为点击触发型,播放次数为一次,再次点击,再触发,与用户动作配合,比如你在玩一个捡金币的游戏,点一个金币,就叮 的一声,那点两个金币,就 叮叮 两声,那点一万个金币,就……你以为我会打一万个 叮 充字数么,我像是那种靠打叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮叮 的人么…我很正直的好吧…

至于音效音频,它也是一个音频,跟背景音频一样的用audio,所以,跟上面背景音频同样的问题我就不累赘了,我们来看一个致命的问题:

演示地址:Demo
二维码:

背景音乐是个很欢快的音频,页面加载后自动播放,页面中间两个按钮,点击beep按钮,播放一个车笛声的音频,点击thunder按钮,播放一个雷声的音频,在IOS上,是可以正常播放的;
在安卓…当点击beep按钮时,背景音乐被强制中止,车笛声音频播放正常,车笛声播放完毕后,背景音乐不会继续播放;
当点击thunder按钮,播放途中点击beep按钮,雷声同样被中断;
由此可见,安卓下,同时只能播放一个audio音频,不支持多个audio音频同时播放,所以,安卓下要背景音乐还是音效,就要权衡取舍了…

当页面存在多个页面,页面之间切换后,音频当前时间没有重置,导致来回切换,音频与动作没有匹配,具体效果如:

演示地址:Demo
二维码:

页面左右切换,背景音乐会切换与之对应,切换的时候,会出现沙沙沙的翻页声,但是再来回切换,会发现音频没有重置,会继续上次播放的位置继续播放,这里其实只需要在页面切换的时候,把音频pause暂停,然后currentTime当前时间帧,设置为0,就可以让音频下次播放的时候,从头播放…具体效果按下Reset CurrentTime 按钮后,就可以体验了…

那现在只是添加了1个音效,如果添加多10个音效呢?会出现什么问题?没错啦,http请求数量增加,跟图片一样,请求时间也会相应的增加,如果你觉得10个音频没什么,那如果50个呢…iP6直接就停在loading页面,进不去…好吧,说到loading,当页面文件增加,体积到达到一定程度,loading页面就肯定要加的,下面提供个loading的代码:

演示地址:Demo
二维码:

页面加载10张图片,4个音频,资源加载完毕后,页面上‘loading...’字样,被替换为“PageStart”,表示页面加载完成…

喂喂喂,怎么突然转移话题,刚说到http请求数量增加,怎么就变成加载资源判断了?
那说回减少http请求这个上面,图片的话,我们知道,可以通过csssprite,也就是图片合并,来适当减少图片请求,那音频能不能也做个合并呢?当然是可以的,就网上下载个音频编辑器,把它们合成一段再下载咯…啊哈哈…其实真的有这个代码可以使用JSFIDDLE,通过将小音频合并,然后记录关键点,需要哪段音频,就获取对应的关键点,以及音频长度,赋值对应的currentTime播放时间,然后播放,由于加载问题,可能会有0.几秒的误差,所以音频在合并的时候,需要留适当的空白,以免音频错位,读到下一个音频去,就好像sprite图与图之间,也需要有相应的间隙一样…不过一旦合并,后面修改起来,就比较麻烦了,因为只要中间一个音频加长,后面的音频都必须做相应挪动(剪短可以不用,哈哈),可维护性偏低,建议在最后项目发布时使用(如果有时间的话,哈哈)…

音频参考的话,可以看下这文章,感觉不错:《Making HTML5 audio actually work onmobile》;

以上就是我近一个礼拜做音频项目所遇到的坑坑洼洼,罗列一下,需要的同学们可以看下作为参考,避免以后在同样的坑上浪费时间,期待各系统各浏览器的兼容完善,有音频的页面总体会上了一个档次的说(虽然页面加载速度被拖后腿了,哈哈)…然后,不管你PC上面的demo多牛逼,音频音效切合的多么好,都要老老实实用真机过一遍,IOS7/8(为什么没有IOS6??因为IOS6压根就不支持audio标签,哈哈,详见这里)、安卓4.1-4.4,真机没问题,才是真的没问题…最后感谢 黄坤,基神,岱霖提供的相关资料(下次做完项目记得写总结啊混蛋们,遇到坑也写啊混蛋们,不要让队友走自己走过的坑啊混蛋们)…

时间: 2024-11-03 21:53:55

那些年,我们一起被坑的H5音频的相关文章

移动端H5音频与视频问题及解决方案

最近在研究用视频代替动画,已经初步有成果了,顺便总结下几年开发中遇到的实际问题及给出自己的解决方案 看下最后实际效果:兼容PC,iphone, 安卓5.0 解决了,手动,自动,不全屏的问题 左边视频代替了动画,然后支持背景蒙板效果,能够透出底图 右边是原视频文件 H5 audio音频 每次通过 new Audio 一个音频对象,在IOS上可以看到会产生一个新的线程,这个很恶心 解决方案: new Audio一个对象,通过替换不同的音频地址,达到不多开线程的目的 在安卓上支持不给力 解决方案: 低

h5音频和视频解决方案

传统的精灵动画: 磁盘空间大,下载慢,尤其是在线播放,会更慢文件太多,在线播放的时候,太多http请求,会导致响应慢,或者行为失常因此,急需开发了一套技术,用视频代替精灵动画.我们称这种视频叫做交互视频 传统视频的问题: 传统视频,只能在方块形的区域中播放传统的视频,在iPad下是窗口播放,在iPhone下面,只能全屏播放传统的视频,播放的时候,一定会出现在最前端交互视频具有如下特点: 在iPhone下面,不需要全屏播放,可以在一个区域中播放交互视频可以出现在普通图形对象的下面交互视频可以带有蒙

H5 音频

HTML 5 音频 HTML5 视频/DOM HTML5 拖放 HTML5 提供了播放音频的标准. Web 上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比如 Flash)来播放的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了一种通过 audio 元素来包含音频的标准方法. audio 元素能够播放声音文件或者音频流. 音频格式 当前,audio 元素支持三种音频格式:   IE 9 Firefox 3.5 Opera 10.5 Chro

H5音频和视频

使用媒体标签最大的缺点在于缺少编解码器的支持一.浏览器支持性检测检测浏览器是否支持audio元素或video元素最简单的方式就是用脚本动态创建它,然后检测特定函数是否存在 var hasVideo=!!(document.createElement('video').canPlayType); 这段脚本会动态创建一个video元素,然后检查canPlayType()函数是否存在.通过"!!"运算符将结果转换成布尔值,反映出是否创建成功,如果不成功的话就需要出发另一套脚本向页面中引入媒体

那些H5用到的技术(1)——素材加载

编码环境前言什么时候用到素材加载?loading提示,让用户等待图片的加载音频的加载利用神器PreloadJS总结 编码环境 Sublime Text 3 插件包括: Autoprefixer 自动补全CSS ColorPicker 颜色选择器 ConvertToUTF8 转码 GBK Support 支持GBK HTML-CSS-JS Prettify 前端代码格式化 SublimeCodeIntel 最好用的自动补全 Chrome 57.0.2950.5 m 用来预览以及调试 gifcam

H5+混合移动app应用开发——开篇

前言 经过2个多月的艰苦奋斗,app的第一个版本已经快完工了,期间遇到了太多的坑,作为一个喜欢分享的人,我当然不会吝啬分享这爬坑历程.不要问我有多坑,我会告诉你很多,很多..... 过去一直从事.net web开发工作,直到几个月前,公司需要开发一个h5+,于是我这样的全能型选手自然而然就被派去搞web app开发,在开发中遇到了太多的问题,一路过来也解决了太多的问题. 技术选型 html5.html5+.vue.js.mui.js 为什么没有jquery?因为,根本用不着,我们知道jquery

h5播放音乐

h5音频播放,里面參数能够查看http://www.w3school.com.cn/html5/html_5_audio.asp <audio controls="controls"> <source src="song.ogg" type="audio/ogg"> <source src="song.mp3" type="audio/mpeg"> Your browse

移动端高清、多屏适配方案——rem

背景: 开发移动端H5页面 一套设计图 不同尺寸的手机 不同分辨率的手机 方案:使用rem作为单位解决一套设计图适应不同分辨率,不同尺寸的手机. 概念: REM(font size of the root element). 相对于<html>的font-size的计算方式. dpr(device pixel ratio).设备像素比:i5,6 = 2;i6plus=3; <meta content="width=device-width; initial-scale=1.0;

html标签学习

1. 标题 : <h1> - <h6> 2. 分割线 : <hr> 3. 加粗: <strong> 4. 斜体: <em> <i> 5. 段落 : <p> 6. 换行 : <br/> 7. 超链接: <a> href 属性指定链接的地址 target ( 目标 ):_self ( 当前页面打开 ) _blank(新页面打开) 8. 图像: <img> src 资源链接属性 .alt 图片