-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathbrowser.js
105 lines (74 loc) · 2.42 KB
/
browser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/** @module audio-play Play buffer in browser via WAA */
'use strict';
const getContext = require('audio-context');
const isAudioBuffer = require('is-audio-buffer');
module.exports = function Play (buffer, how, cb) {
if (!isAudioBuffer(buffer)) throw Error('Argument should be an audio buffer');
if (how instanceof Function) {
cb = how;
}
how = how || {};
cb = cb || (() => {});
if (how.context == null) how.context = getContext();
if (how.currentTime == null) how.currentTime = 0;
if (how.start == null) how.start = 0;
if (how.end == null) how.end = buffer.duration;
how.start = normTime(how.start, buffer.duration);
how.end = normTime(how.end, buffer.duration);
let sourceNode = createNode(buffer, how);
if (!how.gain) {
how.gain = how.context.createGain();
how.gain.gain.value = how.volume == null ? 1 : how.volume;
how.gain.connect(how.context.destination);
}
sourceNode.connect(how.gain);
sourceNode.addEventListener('ended', cb);
//provide API
play.play = pause.play = play;
play.pause = pause.pause = pause;
let startTime = 0;
let isPlaying = false;
return how.autoplay != false ? play() : play;
function play () {
if (isPlaying) return pause;
isPlaying = true;
startTime = how.context.currentTime;
if (how.loop) {
sourceNode.start(startTime, how.start + how.currentTime);
}
else {
sourceNode.start(startTime, how.start + how.currentTime, how.end - how.start);
}
return pause;
}
function pause () {
if (!isPlaying) return pause.play;
isPlaying = false;
sourceNode.stop();
sourceNode.removeEventListener('ended', cb);
let playedTime = (how.context.currentTime - startTime);
how.autoplay = false;
how.currentTime = playedTime;
let playback = Play(buffer, how, cb);
play.play = pause.play = playback.play;
play.pause = pause.pause = playback.pause;
play.currentTime = pause.currentTime = playback.currentTime = how.currentTime;
return playback;
}
}
function normTime (time, duration) {
return time < 0 ? (duration + (time % duration)) : Math.min(duration, time);
}
function createNode (buffer, how) {
let sourceNode = how.context.createBufferSource();
sourceNode.buffer = buffer;
//init options
if (how.detune != null) sourceNode.detune = how.detune;
if (how.rate != null) sourceNode.playbackRate.value = how.rate;
if (how.loop) {
sourceNode.loop = true;
sourceNode.loopStart = how.start;
sourceNode.loopEnd = how.end;
}
return sourceNode;
}