SoundJs | Web-Audio-API实现多音频播放

因为HTML5 Audio不支持同时播放多首歌,今天我们主要介绍一下soundjs和Web-Audio-API实现多音频播放的方法,文末还总结了两种实现方式的demo,大家可以依据实际项目情况添加接口。

| 导语 再回首-“凤凰传奇邀你唱H5”

前言

需求背景:用户选择玲花或曾毅,参与合唱,合唱成功后上传用户录音数据,封装待播放的音频信息(这些部分都是由林雨哥[lennylin]完成的),到落版页请求歌曲进行播放。其中ios微信侧录制音频会屏蔽掉媒体本身的声音,所以ios播放用户合唱歌曲需要同时播放用户录制音频和背景音乐。

  (凤凰传奇邀你唱H5)  

因为HTML5 Audio不支持同时播放多首歌,今天我们主要介绍一下soundjs和Web-Audio-API实现多音频播放的方法,文末还总结了两种实现方式的demo,大家可以依据实际项目情况添加接口。

目录

1. soundjs多音频播放

常用属性:

duration

 音频时长

volume

 音量

playState

 音频播放状态:playFinished | playSucceeded

paused

 s.paused = true 设置音频暂停

startTime

 音频开始播放时间点

loop

 音频循环次数

常用方法:

play()  音频播放
stop()  音频暂停播放,重置播放位置为0,如果想保留播放位,可以使用sound.paused = true

常用事件:

complete  音频播放完成
succeeded  回放成功时触发

首先我们看下单个音频播放:

createjs.Sound.alternateExtensions //设置声音后缀名

createjs.Sound.registerSound //注册音频,sound播放音乐之前需先注册

createjs.Sound.on("fileload", this.loadHandler, this); //针对每个注册音频加载完后的处理事件

多音频播放:

值得注意的是,当sound.src是一个会重定向的音频地址,需要先获得重定向后的真实地址,再注册音频。回顾我们的需求,落版页听录制歌曲的时候,我们需要拿用户openid去请求服务器端的php文件,服务器会重定向到一个具体的mp3地址,代码片段如下:

先看一下readyState几种状态

0

UNSENT (未打开)

open()方法还未被调用.

1

OPENED  (未发送)

open()方法已被调用.

2

HEADERS_RECEIVED (已获取响应头)

send()方法已经被调用, 响应头和响应状态已经返回.

3

LOADING (正在下载响应体)

响应体下载中

4

DONE (请求完成)

整个请求过程已经完毕.

当状态为HEADERS_RECEIVED时可以拿到多次重定向后的最终 URL 并终止请求

注意:如果在初始化音频的时候再去发request请求,会导致微信侧播放异常,所以提前获取音频真实地址,在回调里面再执行音频初始化。

当点击恢复音频播放时需要考虑是否所有音频都已经播放完成,如果是则调用play(),否则仅仅设置paused的状态为false。因为这个时候短音频可能已经播放完成,长音频未播放完成并处于暂停状态,如果不判断直接调用play(),短音频会重新开始播放。

2. Web-Audio-API多音频播放

仔细分析soundjs源码,你会发现它对音频的操作其实是基于强大的Web-Audio-API,而且大多数浏览器都支持Web-Audio-API,我们完全可以用它实现一个简单的音频播放器,不再依赖任何接口文件。
2.1 常用的接口:
AudioContext

 音频上下文

控制其包含节点的创建、处理和解码,使用其他接口之前需创建一个音频上下文

AudioNode  音频节点
AudioBuffer

音频数据对象

可以通过AudioContext.createBuffer 来创建或者

通过 AudioContext.decodeAudioData成功解码音轨后获取.

AudioBufferSourceNode

含有音频源的音频节点,它是用AudioBuffer对象来播放音频数据

可以通过createBufferSource() 方法创建

方法:AudioBufferSourceNode.start()   AudioBufferSourceNode.stop()

事件:ended

ended

音频播放停止时触发

2.2 创建单音频播放

定义音频上下文需注意:webkit内核的浏览器需要带webkit前缀(webkitAudioContext)

2.3 多音频播

 一个 AudioBufferSourceNode 只能被播放一次,每次调用 start() 之后,如果还想再播放一遍同样的声音,那么就需要再创建一个 AudioBufferSourceNode,如果想要多次播放声音,需要保留音频播放上下文和音频数据,这里可以定义一个class,初始化每个音频的id,url地址,buffer数据以及音频上下文等等。

 2.4 音频暂停、播放

 2.5 音频播放结束

绑定音频播放结束事件

综上所述,当对音频点击操作时,需要先判断音频播放状态,如果正在播放则直接暂停;如果已经暂停并且没有播放结束,那么执行恢复操作resume();如果音频已经播放完成,则需要再创建一个 AudioBufferSourceNode,重新绑定context、buffer等信息

 3. 音频播放进度条实现

svg的stroke-dasharray属性:stroke-dasharray=”0,10000″,其中第一个属性是虚线宽度,第二个是虚线之间间隔,保证第二个属性大于圆形周长即可,然后动态改变第一个属性值,即可实现音乐播放进度条,其中第一个属性值是圆周长*idx / 100

值得注意的是,如果是多首歌曲同时播放,需要考虑歌曲的最大时长来设置进度条速度,代码片段如下:

总结

1. soundjs实现的音频播放

调用方法:

2.  Web-Audio-API实现的音频播放

http://hx.qq.com/act/a20180305song/test.html

       (AudioContext)

Web-Audio-API调用方法:

技术研究
原文地址:https://tgideas.qq.com/gicp/news/475/6594222.html?from=list