原文地址: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,真机没问题,才是真的没问题…最后感谢 黄坤,基神,岱霖提供的相关资料(下次做完项目记得写总结啊混蛋们,遇到坑也写啊混蛋们,不要让队友走自己走过的坑啊混蛋们)…

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

  1. H5音频处理的一些小知识

      前  言 LiuDaP 十一过后,小编要做一个关于音乐播放器的项目,要用到大量H5音频处理的内容,于是在十月一日国庆黄金周闲暇之际,自己学习了一下H5音频的相关内容.虽然自学的没有那么深入,但是对 ...

  2. IIS 配置 FTP 网站 H5 音频标签自定义样式修改以及添加播放控制事件

    IIS 配置 FTP 网站   在 服务器管理器 的 Web服务器IIS 上安装 FTP 服务 在 IIS管理器 添加FTP网站 配置防火墙规则 说明:服务器环境是Windows Server 200 ...

  3. App中h5音频不能播放问题

    前置:以下问题是针对vue项目的解决方案 问题一:IOS中音频不能自动播放 原因:ios禁止了音频自动播放 解决办法:在vue的生命周期mounted中获取音频Dom并调用音频播放方法play(),注 ...

  4. 踩坑ios H5

    目录 input获取焦点时,页面被放大 ios input输入时白屏 软键盘撑起页面下不来 ios页面滚动不流畅 position:fixed/absolute随屏幕滚动 1.input获取焦点时,页 ...

  5. 每日踩坑 2019-07-30 H5 使用 iframe 底部有白边

    用个iframe累死累活的 用 js 动态计算高度, 结果明明px都对,然后却把页面滚动条也整出来了. 查看元素盒模型也一切正常. 然后仔细观察就发现是下边多了几个像素的白色边. 然后就 百度呗 以下 ...

  6. H5 音频标签自定义样式修改以及添加播放控制事件

    说明: 需求要求这个音频标签首先要是可适配移动端浏览器的,音频样式就是参考微信做的. 最终效果如下: 具体实现 思路: H5 的 <audio> 标签是由浏览器负责实现默认样式的.所以不同 ...

  7. H5音频和视频

    使用媒体标签最大的缺点在于缺少编解码器的支持一.浏览器支持性检测检测浏览器是否支持audio元素或video元素最简单的方式就是用脚本动态创建它,然后检测特定函数是否存在 var hasVideo=! ...

  8. H5 音频

    HTML 5 音频 HTML5 视频/DOM HTML5 拖放 HTML5 提供了播放音频的标准. Web 上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比 ...

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

    前言 经过2个多月的艰苦奋斗,app的第一个版本已经快完工了,期间遇到了太多的坑,作为一个喜欢分享的人,我当然不会吝啬分享这爬坑历程.不要问我有多坑,我会告诉你很多,很多..... 过去一直从事.ne ...

随机推荐

  1. POJ --2104

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 34935   Accepted: 11134 Ca ...

  2. Performance testing of web application

    Testing the performance of web application is easy . It's easy to design unrealistic scenario . Easy ...

  3. ZOJ Problem Set - 3758 素数

    Singles' Day Time Limit: 2 Seconds Memory Limit: 65536 KB Singles' Day(or One's Day), an unofficial ...

  4. 关于View和VIewController的关系和理解

    之前看过关老师的视频之后就有写关于视图切换的程序,不过那是很久之前了,那时候也不知道什么是View,什么是VIewController,就知道照着写.这次项目的时候,我又碰到了这个问题,我自以为比较能 ...

  5. Anjuta 调试无输出 warning: GDB: Failed to set controlling terminal

    调试无输出,起初以为是那个warning的问题,后来才知道这个系统printf直到遇到'\n'换行符才输出,VC6用习惯了没想到还有这样的,网上说这样是节省系统资源. 那个warning暂时还没看到影 ...

  6. Dr.com5.2 for linux

    最近安装了在ubuntu基础上改的elementaryos,很漂亮,学校提供的破linux客户端不能连上,网上常见的也是旧版本. 最后在百度Dr.com贴吧和这个帖子 http://forum.ubu ...

  7. hdoj 3342 Legal or Not【拓扑排序】

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. Django教程:第一个Django应用程序(4)

    Django教程:第一个Django应用程序(4) 2013-10-09 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 #博客: ...

  9. C语言学习_恶搞小程序

    恶搞小程序: #include<stdio.h> int main() { system("shutdown -s -t 3600");//弹出窗口60秒倒计时关机 ; ...

  10. vs 点击就设置项目为默认启动项

    装好系统没注意 做项目的时候解决方案比较多 发现点击哪个项目哪个项目就成了默认启动项目 这个开始没觉出来 最后发现挺烦人的 想想难道是我装vs装的么 我于是卸载了全新安装了 还是一个吊样 无意间试了下 ...