diff --git a/source/client/components/CVAudioManager.ts b/source/client/components/CVAudioManager.ts index cba5096d..476943dc 100644 --- a/source/client/components/CVAudioManager.ts +++ b/source/client/components/CVAudioManager.ts @@ -75,9 +75,6 @@ export default class CVAudioManager extends Component { super.create(); this.graph.components.on(CVMeta, this.onMetaComponent, this); - - this.audioPlayer = document.createElement('audio'); - this.audioPlayer.onended = this.onEnd; } dispose() @@ -91,11 +88,13 @@ export default class CVAudioManager extends Component const { ins, outs } = this; if (ins.playNarration.changed) { - if(!this.isPlaying) { - this.play(this._narrationId); - } - else { - this.stop(); + if(this.audioPlayer) { + if(!this.isPlaying) { + this.play(this._narrationId); + } + else { + this.stop(); + } } } @@ -171,12 +170,13 @@ export default class CVAudioManager extends Component this.isPlaying = true; outs.narrationPlaying.setValue(id === this._narrationId); }) - .catch(error => Notification.show(`Failed to play audio at '${uri}'`, "warning")); + .catch(error => Notification.show(`Failed to play audio at '${this.audioPlayer.getAttribute("src")}':${error}`, "warning")); } stop() { this.audioPlayer.pause(); + this.audioPlayer.currentTime = 0; this.onEnd(); } @@ -186,4 +186,16 @@ export default class CVAudioManager extends Component this.isPlaying = false; outs.narrationPlaying.setValue(false); } + + // setup function required for Safari compatibility so audio element is setup immediately on user interaction. + setupAudio() + { + if(this.audioPlayer === null) { + this.audioPlayer = document.createElement('audio'); + this.audioPlayer.onended = this.onEnd; + //this.audioPlayer.src = "data:audio/mpeg;base64,SUQzBAAAAAABEVRYWFgAAAAtAAADY29tbWVudABCaWdTb3VuZEJhbmsuY29tIC8gTGFTb25vdGhlcXVlLm9yZwBURU5DAAAAHQAAA1N3aXRjaCBQbHVzIMKpIE5DSCBTb2Z0d2FyZQBUSVQyAAAABgAAAzIyMzUAVFNTRQAAAA8AAANMYXZmNTcuODMuMTAwAAAAAAAAAAAAAAD/80DEAAAAA0gAAAAATEFNRTMuMTAwVVVVVVVVVVVVVUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQsRbAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQMSkAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"; + + this.ins.playNarration.set(); + } + } } \ No newline at end of file diff --git a/source/client/ui/explorer/ARMenu.ts b/source/client/ui/explorer/ARMenu.ts index 4292fe57..615c9446 100644 --- a/source/client/ui/explorer/ARMenu.ts +++ b/source/client/ui/explorer/ARMenu.ts @@ -90,8 +90,9 @@ export default class ARMenu extends DocumentView protected onToggleNarration() { - const audioIns = this.activeDocument.setup.audio.ins; - audioIns.playNarration.set(); + const audio = this.activeDocument.setup.audio; + audio.setupAudio(); // required for Safari compatibility + audio.ins.playNarration.set(); } protected onToggleAnnotations() diff --git a/source/client/ui/explorer/MainMenu.ts b/source/client/ui/explorer/MainMenu.ts index 38194f34..17091a3d 100644 --- a/source/client/ui/explorer/MainMenu.ts +++ b/source/client/ui/explorer/MainMenu.ts @@ -226,8 +226,9 @@ export default class MainMenu extends DocumentView protected onToggleNarration() { - const audioIns = this.activeDocument.setup.audio.ins; - audioIns.playNarration.set(); + const audio = this.activeDocument.setup.audio; + audio.setupAudio(); // required for Safari compatibility + audio.ins.playNarration.set(); } // TODO: More elegant way to handle focus diff --git a/source/client/ui/explorer/TourNavigator.ts b/source/client/ui/explorer/TourNavigator.ts index bd9cc3d5..56b5fec5 100644 --- a/source/client/ui/explorer/TourNavigator.ts +++ b/source/client/ui/explorer/TourNavigator.ts @@ -34,6 +34,7 @@ export default class TourNavigator extends DocumentView protected needsFocus: boolean = false; protected firstRender: boolean = true; + protected stepTitle: string = ""; protected firstConnected() { @@ -62,6 +63,7 @@ export default class TourNavigator extends DocumentView title = language.getLocalizedString("No tour selected"); info = "---"; } + this.stepTitle = title; return html`