135 lines
3.1 KiB
TypeScript
Raw Normal View History

2018-03-11 02:00:06 +00:00
import { AnimeNotifier } from "../AnimeNotifier"
2018-03-11 03:45:01 +00:00
var audioContext: AudioContext
var audioNode: AudioBufferSourceNode
2018-03-11 17:17:35 +00:00
var gainNode: GainNode
var volume = 1.0
2018-03-11 16:20:52 +00:00
var playId = 0
2018-03-11 04:10:32 +00:00
var audioPlayer = document.getElementById("audio-player")
var audioPlayerPlay = document.getElementById("audio-player-play")
var audioPlayerPause = document.getElementById("audio-player-pause")
2018-03-11 03:45:01 +00:00
2018-03-11 02:00:06 +00:00
// Play audio file
2018-03-11 14:43:17 +00:00
export function playAudio(arn: AnimeNotifier, element: HTMLElement) {
2018-03-11 03:45:01 +00:00
if(!audioContext) {
audioContext = new AudioContext()
2018-03-11 17:17:35 +00:00
gainNode = audioContext.createGain()
gainNode.gain.value = volume
2018-03-11 03:45:01 +00:00
}
2018-03-11 16:20:52 +00:00
playId++
let currentPlayId = playId
2018-03-11 04:10:32 +00:00
2018-03-11 14:43:17 +00:00
// Stop current track
stopAudio(arn)
arn.currentSoundTrackId = element.dataset.soundtrackId
element.classList.add("playing")
2018-03-11 02:00:06 +00:00
2018-03-11 04:10:32 +00:00
// Request
2018-03-11 03:45:01 +00:00
let request = new XMLHttpRequest()
2018-03-11 14:43:17 +00:00
request.open("GET", element.dataset.audioSrc, true)
2018-03-11 03:45:01 +00:00
request.responseType = "arraybuffer"
2018-03-11 04:10:32 +00:00
2018-03-11 03:45:01 +00:00
request.onload = () => {
2018-03-11 16:20:52 +00:00
if(currentPlayId !== playId) {
return
}
2018-03-11 03:45:01 +00:00
audioContext.decodeAudioData(request.response, buffer => {
2018-03-11 16:20:52 +00:00
if(currentPlayId !== playId) {
return
}
2018-03-11 03:45:01 +00:00
audioNode = audioContext.createBufferSource()
audioNode.buffer = buffer
2018-03-11 17:17:35 +00:00
audioNode.connect(gainNode)
gainNode.connect(audioContext.destination)
2018-03-11 03:45:01 +00:00
audioNode.start(0)
2018-03-11 04:10:32 +00:00
audioNode.onended = (event: MediaStreamErrorEvent) => {
2018-03-11 16:20:52 +00:00
if(currentPlayId !== playId) {
return
2018-03-11 04:10:32 +00:00
}
2018-03-11 16:20:52 +00:00
stopAudio(arn)
2018-03-11 03:51:10 +00:00
}
2018-03-11 03:45:01 +00:00
}, console.error)
}
2018-03-11 04:10:32 +00:00
2018-03-11 03:45:01 +00:00
request.send()
// Show audio player
2018-03-11 04:10:32 +00:00
audioPlayer.classList.remove("fade-out")
audioPlayerPlay.classList.add("fade-out")
audioPlayerPause.classList.remove("fade-out")
2018-03-11 03:45:01 +00:00
}
2018-03-11 14:43:17 +00:00
// Stop audio
export function stopAudio(arn: AnimeNotifier) {
arn.currentSoundTrackId = undefined
// Remove CSS class "playing"
let playingElements = document.getElementsByClassName("playing")
for(let playing of playingElements) {
playing.classList.remove("playing")
}
// Fade out sidebar player
audioPlayer.classList.add("fade-out")
2018-03-11 16:20:52 +00:00
2018-03-11 17:17:35 +00:00
if(gainNode) {
gainNode.disconnect()
2018-03-11 16:20:52 +00:00
}
2018-03-11 17:17:35 +00:00
if(audioNode) {
audioNode.stop()
audioNode.disconnect()
audioNode = null
}
2018-03-11 14:43:17 +00:00
}
// Toggle audio
export function toggleAudio(arn: AnimeNotifier, element: HTMLElement) {
2018-03-11 15:42:49 +00:00
// If we're clicking on the same track again, stop playing.
// Otherwise, start the track we clicked on.
if(arn.currentSoundTrackId && element.dataset.soundtrackId === arn.currentSoundTrackId) {
2018-03-11 14:43:17 +00:00
stopAudio(arn)
2018-03-11 15:42:49 +00:00
} else {
playAudio(arn, element)
2018-03-11 14:43:17 +00:00
}
}
2018-03-11 16:20:52 +00:00
// Set volume
2018-03-11 17:17:35 +00:00
export function setVolume(arn: AnimeNotifier, element: HTMLInputElement) {
volume = parseFloat(element.value) / 100.0
2018-03-11 16:20:52 +00:00
2018-03-11 17:17:35 +00:00
if(gainNode) {
gainNode.gain.value = volume
}
2018-03-11 16:20:52 +00:00
}
2018-03-11 03:45:01 +00:00
// Pause audio
export function pauseAudio(arn: AnimeNotifier, button: HTMLButtonElement) {
if(!audioNode) {
return
}
audioNode.playbackRate.setValueAtTime(0.0, 0)
2018-03-11 04:10:32 +00:00
audioPlayerPlay.classList.remove("fade-out")
audioPlayerPause.classList.add("fade-out")
2018-03-11 03:45:01 +00:00
}
// Resume audio
export function resumeAudio(arn: AnimeNotifier, button: HTMLButtonElement) {
if(!audioNode) {
return
}
audioNode.playbackRate.setValueAtTime(1.0, 0)
2018-03-11 04:10:32 +00:00
audioPlayerPlay.classList.add("fade-out")
audioPlayerPause.classList.remove("fade-out")
2018-03-11 02:00:06 +00:00
}