2016-06-16 07:36:44 +08:00
|
|
|
import * as Links from 'Common/Links';
|
2022-02-24 18:19:19 +08:00
|
|
|
import { doc, SettingsGet, fireEvent, addEventsListener } from 'Common/Globals';
|
2022-06-08 00:46:06 +08:00
|
|
|
import { addObservablesTo } from 'External/ko';
|
2015-11-15 08:23:16 +08:00
|
|
|
|
2020-11-10 03:14:04 +08:00
|
|
|
let notificator = null,
|
|
|
|
player = null,
|
2022-09-02 17:52:07 +08:00
|
|
|
canPlay = type => !!player?.canPlayType(type).replace('no', ''),
|
2020-11-10 03:14:04 +08:00
|
|
|
|
2020-11-10 17:25:02 +08:00
|
|
|
audioCtx = window.AudioContext || window.webkitAudioContext,
|
2020-11-10 03:14:04 +08:00
|
|
|
|
|
|
|
play = (url, name) => {
|
|
|
|
if (player) {
|
|
|
|
player.src = url;
|
|
|
|
player.play();
|
|
|
|
name = name.trim();
|
2022-02-11 19:21:16 +08:00
|
|
|
fireEvent('audio.start', name.replace(/\.([a-z0-9]{3})$/, '') || 'audio');
|
2020-11-10 03:14:04 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
createNewObject = () => {
|
|
|
|
try {
|
|
|
|
const player = new Audio;
|
|
|
|
if (player.canPlayType && player.pause && player.play) {
|
|
|
|
player.preload = 'none';
|
|
|
|
player.loop = false;
|
|
|
|
player.autoplay = false;
|
|
|
|
player.muted = false;
|
|
|
|
return player;
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
console.error(e);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
|
|
|
// The AudioContext is not allowed to start.
|
|
|
|
// It must be resumed (or created) after a user gesture on the page. https://goo.gl/7K7WLu
|
|
|
|
// Setup listeners to attempt an unlock
|
|
|
|
unlockEvents = [
|
|
|
|
'click','dblclick',
|
|
|
|
'contextmenu',
|
|
|
|
'auxclick',
|
|
|
|
'mousedown','mouseup',
|
|
|
|
'pointerup',
|
|
|
|
'touchstart','touchend',
|
|
|
|
'keydown','keyup'
|
|
|
|
],
|
|
|
|
unlock = () => {
|
2022-07-19 17:50:57 +08:00
|
|
|
unlockEvents.forEach(type => doc.removeEventListener(type, unlock, true));
|
2020-11-10 03:14:04 +08:00
|
|
|
if (audioCtx) {
|
|
|
|
console.log('AudioContext ' + audioCtx.state);
|
|
|
|
audioCtx.resume();
|
|
|
|
}
|
2022-06-08 00:46:06 +08:00
|
|
|
// setTimeout(()=>SMAudio.playNotification(0,1),1);
|
2020-11-10 03:14:04 +08:00
|
|
|
};
|
2016-06-28 04:54:38 +08:00
|
|
|
|
2020-11-10 03:14:04 +08:00
|
|
|
if (audioCtx) {
|
|
|
|
audioCtx = audioCtx ? new audioCtx : null;
|
|
|
|
audioCtx.onstatechange = unlock;
|
|
|
|
}
|
2021-01-27 07:26:31 +08:00
|
|
|
unlockEvents.forEach(type => doc.addEventListener(type, unlock, true));
|
2020-11-10 03:14:04 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Browsers can't play without user interaction
|
|
|
|
*/
|
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
export const SMAudio = new class {
|
2016-09-10 06:38:16 +08:00
|
|
|
constructor() {
|
2020-11-10 03:14:04 +08:00
|
|
|
player || (player = createNewObject());
|
2016-08-30 06:10:24 +08:00
|
|
|
|
2020-11-10 03:14:04 +08:00
|
|
|
this.supported = !!player;
|
2021-01-27 07:26:31 +08:00
|
|
|
this.supportedMp3 = canPlay('audio/mpeg;');
|
|
|
|
this.supportedWav = canPlay('audio/wav; codecs="1"');
|
|
|
|
this.supportedOgg = canPlay('audio/ogg; codecs="vorbis"');
|
2020-11-10 03:14:04 +08:00
|
|
|
if (player) {
|
|
|
|
const stopFn = () => this.pause();
|
2022-02-24 18:19:19 +08:00
|
|
|
addEventsListener(player, ['ended','error'], stopFn);
|
2020-08-15 02:35:39 +08:00
|
|
|
addEventListener('audio.api.stop', stopFn);
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
2022-06-08 00:46:06 +08:00
|
|
|
|
|
|
|
addObservablesTo(this, {
|
|
|
|
notifications: false
|
|
|
|
});
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
paused() {
|
2020-11-10 03:14:04 +08:00
|
|
|
return !player || player.paused;
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
stop() {
|
2020-11-10 03:14:04 +08:00
|
|
|
this.pause();
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
pause() {
|
2022-09-02 17:52:07 +08:00
|
|
|
player?.pause();
|
2022-02-11 19:21:16 +08:00
|
|
|
fireEvent('audio.stop');
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
playMp3(url, name) {
|
2020-11-10 03:14:04 +08:00
|
|
|
this.supportedMp3 && play(url, name);
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
playOgg(url, name) {
|
2020-11-10 03:14:04 +08:00
|
|
|
this.supportedOgg && play(url, name);
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
playWav(url, name) {
|
2020-11-10 03:14:04 +08:00
|
|
|
this.supportedWav && play(url, name);
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
|
2022-06-08 00:46:06 +08:00
|
|
|
/**
|
|
|
|
* Used with SoundNotification setting
|
|
|
|
*/
|
|
|
|
playNotification(force, silent) {
|
|
|
|
if (force || this.notifications()) {
|
|
|
|
if ('running' == audioCtx.state && (this.supportedMp3 || this.supportedOgg)) {
|
|
|
|
notificator = notificator || createNewObject();
|
|
|
|
if (notificator) {
|
2023-12-05 23:18:36 +08:00
|
|
|
// SettingsGet('NotificationSound').startsWith('custom@')
|
2022-06-08 00:46:06 +08:00
|
|
|
notificator.src = Links.staticLink('sounds/'
|
|
|
|
+ SettingsGet('NotificationSound')
|
|
|
|
+ (this.supportedMp3 ? '.mp3' : '.ogg'));
|
|
|
|
notificator.volume = silent ? 0.01 : 1;
|
|
|
|
notificator.play();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
console.log('No audio: ' + audioCtx.state);
|
2015-11-15 08:23:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-10 03:14:04 +08:00
|
|
|
};
|