2 * Plays audio files (alerts, generally) by key name. Each sound uses a
3 * dot-path to indicate the sound.
7 * this.audio.play('warning.checkout.no_item');
9 * URLs are tested in the following order until an audio file is found
10 * or no other paths are left to check.
12 * /audio/notifications/warning/checkout/not_found.wav
13 * /audio/notifications/warning/checkout.wav
14 * /audio/notifications/warning.wav
16 * Files are only played when sounds are configured to play via
17 * workstation settings.
19 import {Injectable, EventEmitter} from '@angular/core';
20 import {ServerStoreService} from '@eg/core/server-store.service';
21 const AUDIO_BASE_URL = '/audio/notifications/';
24 export class AudioService {
26 // map of requested audio path to resolved path
27 private urlCache: {[path: string]: string} = {};
29 constructor(private store: ServerStoreService) {}
31 play(path: string): void {
33 this.playUrl(path, path);
37 playUrl(path: string, origPath: string): void {
38 // console.debug(`audio: playUrl(${path}, ${origPath})`);
40 this.store.getItem('eg.audio.disable').then(audioDisabled => {
41 if (audioDisabled) { return; }
43 const url = this.urlCache[path] ||
44 AUDIO_BASE_URL + path.replace(/\./g, '/') + '.wav';
46 const player = new Audio(url);
48 player.onloadeddata = () => {
49 this.urlCache[origPath] = url;
51 console.debug(`audio: ${url}`);
54 if (this.urlCache[path]) {
55 // when serving from the cache, avoid secondary URL lookups.
59 player.onerror = () => {
60 // Unable to play path at the requested URL.
62 if (!path.match(/\./)) {
63 // all fall-through options have been exhausted.
66 `No suitable URL found for path "${origPath}"`);
70 // Fall through to the next (more generic) option
71 path = path.replace(/\.[^\.]+$/, '');
72 this.playUrl(path, origPath);