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
|
export default class AudioPlayer {
files = {}
players = {}
current_background_id = 0
constructor() {
this.done = this.done.bind(this)
}
load(graph) {
this.files = graph.uploads
.filter(upload => upload.tag === 'audio')
.reduce((accumulator, item) => {
accumulator[item.id] = item
return accumulator
}, {})
}
done(id) {
console.log('remove', id)
delete this.players[id]
}
playPage(page) {
const { background_audio_id, restart_audio } = page.settings
console.log('playPage', background_audio_id)
if (
this.current_background_id
&& this.current_background_id !== background_audio_id
&& this.current_background_id in this.players
) {
this.players[this.current_background_id].stop()
}
if (background_audio_id in this.files) {
this.current_background_id = background_audio_id
this.playFile({
item: this.files[background_audio_id],
restart: !!restart_audio,
})
}
}
playFile({ item, restart, loop }) {
const { id } = item
if (id in this.players) {
if (restart) {
this.players[id].restart()
}
return this.players[id]
} else {
this.players[id] = new Player(item, this.done)
this.players[id].play()
return this.players[id]
}
}
}
class Player {
constructor(item, done) {
this.item = item
this.done = done
this.audio = document.createElement('audio')
this.handleEnded = this.handleEnded.bind(this)
this.handleError = this.handleError.bind(this)
this.release = this.release.bind(this)
this.audio.addEventListener('ended', this.handleEnded)
this.audio.addEventListener('error', this.handleError)
this.audio.src = item.url
}
release() {
this.audio.removeEventListener('ended', this.handleEnded)
this.audio.removeEventListener('error', this.handleError)
this.done(this.item.id)
this.item = null
this.done = null
this.audio = null
}
handleError(error) {
console.error(error)
this.release()
}
handleEnded() {
this.release()
}
play() {
console.log('play', this.item.id)
this.audio.play()
}
restart() {
console.log('replay', this.item.id)
this.audio.currentTime = 0
this.audio.play()
}
stop() {
console.log('stop', this.item.id)
this.audio.pause()
this.release()
}
}
|