Currently, I am developing a website that utilizes the Web Audio API to play audio files. My tech stack includes TypeScript and Angular 2 within Visual Studio Code. Everything is functioning smoothly on various platforms except for ios; specifically, when testing on an iPad, perplexing errors arise.
The initial hurdle is acquiring an AudioContext that functions seamlessly across both ios and non-ios platforms. Several solutions in plain JavaScript exist, such as . Although implementing a button press workaround may be cumbersome, it's tolerable. The issue appears to relate to TypeScript. (As someone new to TypeScript, my grasp of fundamental concepts might be lacking.)
In ios environments, the runtime provides a webkitAudioContext rather than an AudioContext. It seems like the TypeScript definitions I'm employing struggle to handle this distinction. Alternatively, it's plausible that I have not specified the necessary information. Initially, I declared a member variable with type AudioContext, which functioned correctly on non-ios devices. To cater to ios compatibility, I attempted to modify the variable type to any, allowing the inclusion of a webkitAudioContext if AudioContext is unavailable. The corresponding code snippet looks like this (note: this is just prototype code and error handling is provisional):
export class PlayerService {
private static _audioContext: any = null;
//......
public static getAudioContext(): any {
if (!PlayerService._audioContext) {
try {
if (typeof AudioContext !== "undefined") {
PlayerService._audioContext = new AudioContext();
} else if (window['webkitAudioContext'] !== "undefined") {
PlayerService._audioContext = Object.create(window['webkitAudioContext'].prototype);
} else {
throw new Error('AudioContext not supported. :(');
}
} catch (err) {
console.log(err.message);
alert('Cannot create audio context.');
throw err;
}
}
return PlayerService._audioContext;
}
This implementation continues to operate effectively on non-ios platforms; however, on ios, it successfully returns a webkitAudioContext with the expected methods and properties. (Utilizing Object.create(...) was essential for achieving this functionality.) Nonetheless, upon invoking decodeAudioData on this object, an error emerges citing:
TypeError: Can only call AudioContext.decodeAudioData on instance of AudioContext.
Due to the 'any' typing of the variable where the decodeAudioData method is called, I'm uncertain why it necessitates an AudioContext specifically. Regardless, this likely isn't the optimal approach to resolve the issue. Currently, I lack type details regarding webkitAudioContext and possess information solely about AudioContext. Is there existing type data available, possibly undiscovered? If absent, would generating it prove troublesome? Alternatively, is bypassing type checking for this class set feasible (though not my preferred choice)? Or perhaps, an entirely different methodology exists that eludes me?