diff --git a/src/audio/BackgroundAudio.ts b/src/audio/BackgroundAudio.ts index c90016eef9..eda10c0904 100644 --- a/src/audio/BackgroundAudio.ts +++ b/src/audio/BackgroundAudio.ts @@ -48,6 +48,12 @@ export class BackgroundAudio { source.buffer = this.sounds[url]; source.loop = loop; source.connect(this.audioContext.destination); + + await this.audioContext.resume(); + source.onended = () => { + this.audioContext.suspend(); + }; + source.start(); return source; } diff --git a/src/audio/compat.ts b/src/audio/compat.ts index 7af6ef68b2..0c972e9b73 100644 --- a/src/audio/compat.ts +++ b/src/audio/compat.ts @@ -15,16 +15,21 @@ import { logger } from "matrix-js-sdk/src/logger"; import { SAMPLE_RATE } from "./VoiceRecording"; export function createAudioContext(opts?: AudioContextOptions): AudioContext { + let ctx: AudioContext; if (window.AudioContext) { - return new AudioContext(opts); + ctx = new AudioContext(opts); } else if (window.webkitAudioContext) { // While the linter is correct that "a constructor name should not start with // a lowercase letter", it's also wrong to think that we have control over this. // eslint-disable-next-line new-cap - return new window.webkitAudioContext(opts); + ctx = new window.webkitAudioContext(opts); } else { throw new Error("Unsupported browser"); } + // Initialize in suspended state, as Firefox starts using + // CPU/battery right away, even if we don't play any sound yet. + void ctx.suspend(); + return ctx; } export function decodeOgg(audioBuffer: ArrayBuffer): Promise {