Support compatibility points for Safari

Tested on MacOS Big Sur, Safari 14.0.3
This commit is contained in:
Travis Ralston 2021-05-06 21:38:48 -06:00
parent b61fe2f8e6
commit b08e47bfe1
4 changed files with 155 additions and 25 deletions

View file

@ -21,6 +21,7 @@ import {SimpleObservable} from "matrix-widget-api";
import {IDestroyable} from "../utils/IDestroyable";
import {PlaybackClock} from "./PlaybackClock";
import {clamp} from "../utils/numbers";
import {createAudioContext, decodeOgg} from "./compat";
export enum PlaybackState {
Decoding = "decoding",
@ -49,7 +50,7 @@ export class Playback extends EventEmitter implements IDestroyable {
*/
constructor(private buf: ArrayBuffer, seedWaveform = DEFAULT_WAVEFORM) {
super();
this.context = new AudioContext();
this.context = createAudioContext();
this.resampledWaveform = arrayFastResample(seedWaveform ?? DEFAULT_WAVEFORM, PLAYBACK_WAVEFORM_SAMPLES);
this.waveformObservable.update(this.resampledWaveform);
this.clock = new PlaybackClock(this.context);
@ -91,7 +92,23 @@ export class Playback extends EventEmitter implements IDestroyable {
}
public async prepare() {
this.audioBuf = await this.context.decodeAudioData(this.buf);
// Safari compat: promise API not supported on this function
this.audioBuf = await new Promise((resolve, reject) => {
this.context.decodeAudioData(this.buf, b => resolve(b), async e => {
// This error handler is largely for Safari as well, which doesn't support Opus/Ogg
// very well.
console.error("Error decoding recording: ", e);
console.warn("Trying to re-encode to WAV instead...");
const wav = await decodeOgg(this.buf);
// noinspection ES6MissingAwait - not needed when using callbacks
this.context.decodeAudioData(wav, b => resolve(b), e => {
console.error("Still failed to decode recording: ", e);
reject(e);
});
});
});
// Update the waveform to the real waveform once we have channel data to use. We don't
// exactly trust the user-provided waveform to be accurate...