HTML5 Audio 在 iOS Safari 上的问题

最近接触一个移动短项目,做摇一摇的功能,然后摇的时候要有声音,摇中奖的时候也有声音,问题来了,iOS 5 不能用代码去触发播放声音,其实 Android 4.0+ 也有一样的问题,因为目前只折腾了 iOS,所以这里就以 iOS Safari 的情况为例,其他应该是类似的,大家可以自己验证。以下的 Safari 都是指 iOS 下的。

iOS Safari 中的 HTML5 媒体元素都是单例的,所以一次只能播放一个 HTML5 音频(和 HTML5 视频)流(估计是为了减少数据费用)。音频文件只能从用户触发的触摸(单击)事件加载,如果在 HTML 标记中使用了 autoplay 属性,那么 Safari 将会忽略这个属性,并且不会在加载页面时播放此文件,对于 preload 属性,Safari 同样会忽略。唯一能解决的就是用户进入页面是,让用户触发 touch 事件:

var shakeAudio = $(‘#shakeAudio‘)[0],
    winAudio = $(‘#winAudio‘)[0]

$(document).on(‘touchstart‘, function() {
    shakeAudio.load()
})

触发 load 事件后,当用户再摇一摇的时候边可以用 ShakeAudio.play() 播放声音。

咦,摇中奖的声音呢?如果在上面 ontouchstart 事件中加多个 winAudio.load(),那么 shakeAudio 播放不能,上面说了,他是一个单例,后面的会覆盖前面的。怎么办?最好的方法是使用 audio
sprite,将所有的音频综合到一个单音频流中,然后播放此流的各个部分。

当然,同样需要让用户先有一次 touch 事件触发,以加载该 audioSprite 音频:

var audioSprite = $(‘#audioSprite‘)[0],
    audioData = {
        shake: {
            start: 0,
            length: 1
        },
        win: {
            start: 1.3,
            length: 1.5
        }
    }

当播放 shake 的声音时:

audioSprite.currentTime = audioData.shake.start;
audioSprite.play();

// 添加当到达 sprite 的结尾时停止音频流的逻辑
var handler = function() {
    if (this.currentTime >= audioData.shake.start + audioData.shake.length) {
        this.pause()
    }
}

audioSprite.addEventListener(‘timeupdate‘, handler, false);

播放 winAudio 同理。需要注意的是,更改 currentTime 并不是百分百正确的。假设 currentTime 设为 6.5,而实际得到的却是 6.7。每个 audio sprite 之间需要少量的空间,以避免寻找到另一个 sprite 的头部。

在访问任何 audio sprite 之前,务必确保整个音频流已加载,因为如果音频流没有完全加载,那么在想要访问已加载的流的任何一个部分时,那么这个流需要进行缓冲,而且还会在流加载过程中发生延时。

FYI: HTML5 Audio Behaviour and Support in iOS and Android

时间: 2024-09-28 20:03:30

HTML5 Audio 在 iOS Safari 上的问题的相关文章

iOS Safari 上加载的最大的图片尺寸

做WAP端项目时发现, 写css代码显示图片, 却显示不出.或用canvas 来加载图片的某一部分的时候显示不出, 代码如下: background: url() no-repeat -1000px -2000px; width: 3000px; height: 4000px; 经过网上google 搜索( sprite sheet max size )发现如下, 所以对于一般的图片的总面积不要超过: 2048 x 2048 = 4194304 的值, 单个长或者宽可以超过 2048. iPho

关于html5 audio 标签在ios系统上不能正常自动播放的解决办法

由于 iOS Safari 限制不允许 audio autoplay, 必须用户主动交互(例如 click)后才能播放 audio, 因此我们通过一个用户交互事件来主动 play 一下 audio. 这个坑相信大家都已经踩过了, 在 iOS 9 没出现以前, 这样的 hack 方案还是妥妥的.但 iOS 9 出现后, 发现这个方案"失效"了. 没有办法, 看来是时候升级一下 hack 方案了, 于是仔细看了下 audio 的事件. 对于能够自动播放时事件的顺序如下loadstart -

在iOS微信浏览器中自动播放HTML5 audio(音乐)的2种正确方式

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"

[jPlayer] HTML5 Audio &amp; Video for jQuery

----------------------------------------------------------------------------------------------------- The jQuery HTML5 Audio / Video Library jPlayer is the completely free and open source (MIT) media library written in JavaScript. A jQueryplugin, (an

html5 audio总结

前言 html5中对音频,视频播放原生支持.最近做了一个音乐播放器,得益于快过年了,才能抽出一点时间来总结一下.总的来说,html5对audio的支持非常强大, 难怪flash要死.浏览器上装播放插件的时代已经接近尾声了.目前大多数浏览器都支持了大部分常用的api,ie8及其以前除外(万恶的ie啊). HTML5 音频虽然很健壮,但有其局限性,这主要取决于它的实现.对于音乐播放器(点唱机播放器)或简单的声音效果,它很有效,但是对于声音密集的应用程序如游戏,它的表现不是很理想.所以有了Web Au

The jQuery HTML5 Audio / Video Library (jQuery jPlayer插件给你的站点增加视频和音频功能)

http://jplayer.org/ The jQuery HTML5 Audio / Video Library jPlayer is the completely free and open source (MIT) media library written in JavaScript. A jQueryplugin, (and now a Zepto plugin,) jPlayer allows you to rapidly weave cross platform audio an

HTML5 audio API的研究与学习1

HTML5 audio 1.audio sprite 音频精灵的主要思想其实跟css精灵差不多,将一个音频合成到一个音频,然后通过currentTime获取当前播放时间进行区分,不过在这里执行以下代码之前需将audio 先加载到页面当中.当时怎么判断页面已经加载完声音呢,在移动端audio的很多属性支持的都不是很好,在尝试了很多也在网上找了很多资料之后,暂且发现可以使用AudioContext对象去管理与播放声音 <input type="button" value="

5款帮助简化的HTML5 Audio开发的Javascript类库

HTML5的audio标签提供了我们方便控制声音的功能,但是使用原生的HTML5来开发声音或者音乐相关的项目仍旧非常的麻烦,在今天这篇文章中,我们将介绍5款帮助你简化开发的javascript audio类库,相信合理的使用能够帮助你高效的开发基于html5 audio的应用和项目,希望大家觉得有帮助! SoundManager 2 soundmanager2绝对是一个产品级别的javascript audio解决方案,支持HTML5并且兼容老的flash.帮助大家使用一套统一API来实现跨平台

使IFRAME在iOS设备上支持滚动

原文链接: Scroll IFRAMEs on iOS原文日期: 2014年07月02日 翻译日期: 2014年07月10日翻译人员: 铁锚 很长时间以来, iOS设备上Safari中超出边界的元素将不能滚动,处理这种问题对开发人员来说一直是种折磨. 对原文作者的博客来说,这特别让人无奈,因为demo程序都是在沙箱IFRAMEs中运行的,这是为了不影响博客网站的AJAX页面加载策略.  通过一些研究发现,只要设置两个CSS属性,以及加上一个元素,这个问题就解决了. Here we go!(译者注