jsdk-offical
Version:
JSDK is the most comprehensive TypeScript framework, like JDK.
139 lines (118 loc) • 4.03 kB
text/typescript
/**
* @project JSDK
* @license MIT
* @website https://github.com/fengboyue/jsdk
*
* @version 2.3.0
* @author Frank.Feng
*/
module JS {
export namespace media {
let W = window, A = W.AudioContext || W['msAudioContext'], AC: AudioContext = new A();
export interface AudioProInit {
/** Default volume: 0~1 float */
volume?: number,
/** Default value for cyclic play */
loop?: boolean,
/**
* Create new AudioNode to handle complex effects before playing.
*/
handler?: (this: AudioPro, ac: AudioContext) => AudioNode,
/**
* Be called before an audio play.
*/
playing?: EventHandler<AudioPro>;
/**
* Be called when an audio finished to play.
*/
played?: EventHandler<AudioPro>
}
/**
* Audio Processor.
*/
export class AudioPro {
private _init: AudioProInit;
private _node: AudioBufferSourceNode;
private _gain: GainNode;
static play(id: string, cache: AudioCache){
new AudioPro().play(id, cache)
}
constructor(init?: AudioProInit) {
this._init = Jsons.union({
volume: 1,
loop: false
}, init);
}
loop(): boolean
loop(is: boolean): this
loop(is?: boolean): any {
let m = this;
if (is == void 0) return m._init.loop;
m._init.loop = is;
m._node.loop = is;
return m
}
_play(a: AudioBuffer) {
let m = this;
m.stop();
// Create a gain node.
m._gain = AC.createGain();
m._gain.gain.value = m._init.volume;
m._node = AC.createBufferSource();
m._node.buffer = a;
let c = m._init;
m._node.loop = c.loop;
if (c.played) m._node.onended = e => {
m._dispose();
c.played.call(m)
};
// Connect the source to the gain node.
m._node.connect(m._gain);
if (c.handler) {
let node: AudioNode = c.handler.call(m, AC);
m._gain.connect(node);
node.connect(AC.destination)
} else {
// Connect the gain node to the destination.
m._gain.connect(AC.destination);
}
if (c.playing) c.playing.call(m);
m._node.start();
}
play(a: ArrayBuffer)
play(id: string, cache: AudioCache)
play(a: string|ArrayBuffer, cache?: AudioCache){
if(typeof a == 'string') {
cache.get(a).then(buf => {
this.play(buf)
})
}else{
if (a) AC.decodeAudioData(<ArrayBuffer>a, (buffer: AudioBuffer) => {
this._play(buffer)
}, err => {
JSLogger.error('Decode audio buffer fail!')
})
}
}
stop() {
if (this._node) this._node.stop();
}
/**
* Sets volume of current sound.
* @param n 0~1
*/
volume(n: number) {
let m = this;
m._init.volume = n;
if (m._gain) m._gain.gain.value = n;
}
_dispose() {
let m = this;
m._gain.disconnect();
m._node.disconnect();
}
}
}
}
import AudioProInit = JS.media.AudioProInit;
import AudioPro = JS.media.AudioPro;