Skip to content

Commit

Permalink
fix: remove workaround to prevent creating realtime nodes
Browse files Browse the repository at this point in the history
Safari up to version 13.1 allowed to create a MediaElementAudioSourceNode, a
MediaStreamAudioSourceNode, and a MediaStreamAudioDestinationNode with an OfflineAudioContext.

BREAKING CHANGE: This will drop support for Safari v13.1.
  • Loading branch information
chrisguttandin committed Sep 30, 2024
1 parent 8a81581 commit 73e0b67
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 78 deletions.
14 changes: 5 additions & 9 deletions src/factories/media-element-audio-source-node-constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ import { TAudioNodeRenderer, TMediaElementAudioSourceNodeConstructorFactory, TNa
export const createMediaElementAudioSourceNodeConstructor: TMediaElementAudioSourceNodeConstructorFactory = (
audioNodeConstructor,
createNativeMediaElementAudioSourceNode,
getNativeContext,
isNativeOfflineAudioContext
getNativeContext
) => {
return class MediaElementAudioSourceNode<T extends IAudioContext | IMinimalAudioContext> extends audioNodeConstructor<T>
implements IMediaElementAudioSourceNode<T> {
return class MediaElementAudioSourceNode<T extends IAudioContext | IMinimalAudioContext>
extends audioNodeConstructor<T>
implements IMediaElementAudioSourceNode<T>
{
private _nativeMediaElementAudioSourceNode: TNativeMediaElementAudioSourceNode;

constructor(context: T, options: IMediaElementAudioSourceOptions) {
const nativeContext = getNativeContext(context);
const nativeMediaElementAudioSourceNode = createNativeMediaElementAudioSourceNode(nativeContext, options);

// Bug #171: Safari allows to create a MediaElementAudioSourceNode with an OfflineAudioContext.
if (isNativeOfflineAudioContext(nativeContext)) {
throw TypeError();
}

super(context, true, nativeMediaElementAudioSourceNode, <TAudioNodeRenderer<T>>null);

this._nativeMediaElementAudioSourceNode = nativeMediaElementAudioSourceNode;
Expand Down
15 changes: 5 additions & 10 deletions src/factories/media-stream-audio-destination-node-constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,16 @@ const DEFAULT_OPTIONS = {
export const createMediaStreamAudioDestinationNodeConstructor: TMediaStreamAudioDestinationNodeConstructorFactory = (
audioNodeConstructor,
createNativeMediaStreamAudioDestinationNode,
getNativeContext,
isNativeOfflineAudioContext
getNativeContext
) => {
return class MediaStreamAudioDestinationNode<T extends IAudioContext | IMinimalAudioContext> extends audioNodeConstructor<T>
implements IMediaStreamAudioDestinationNode<T> {
return class MediaStreamAudioDestinationNode<T extends IAudioContext | IMinimalAudioContext>
extends audioNodeConstructor<T>
implements IMediaStreamAudioDestinationNode<T>
{
private _nativeMediaStreamAudioDestinationNode: TNativeMediaStreamAudioDestinationNode;

constructor(context: T, options?: Partial<IAudioNodeOptions>) {
const nativeContext = getNativeContext(context);

// Bug #173: Safari allows to create a MediaStreamAudioDestinationNode with an OfflineAudioContext.
if (isNativeOfflineAudioContext(nativeContext)) {
throw new TypeError();
}

const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
const nativeMediaStreamAudioDestinationNode = createNativeMediaStreamAudioDestinationNode(nativeContext, mergedOptions);

Expand Down
14 changes: 5 additions & 9 deletions src/factories/media-stream-audio-source-node-constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ import { TAudioNodeRenderer, TMediaStreamAudioSourceNodeConstructorFactory, TNat
export const createMediaStreamAudioSourceNodeConstructor: TMediaStreamAudioSourceNodeConstructorFactory = (
audioNodeConstructor,
createNativeMediaStreamAudioSourceNode,
getNativeContext,
isNativeOfflineAudioContext
getNativeContext
) => {
return class MediaStreamAudioSourceNode<T extends IAudioContext | IMinimalAudioContext> extends audioNodeConstructor<T>
implements IMediaStreamAudioSourceNode<T> {
return class MediaStreamAudioSourceNode<T extends IAudioContext | IMinimalAudioContext>
extends audioNodeConstructor<T>
implements IMediaStreamAudioSourceNode<T>
{
private _nativeMediaStreamAudioSourceNode: TNativeMediaStreamAudioSourceNode;

constructor(context: T, options: IMediaStreamAudioSourceOptions) {
const nativeContext = getNativeContext(context);
const nativeMediaStreamAudioSourceNode = createNativeMediaStreamAudioSourceNode(nativeContext, options);

// Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.
if (isNativeOfflineAudioContext(nativeContext)) {
throw new TypeError();
}

super(context, true, nativeMediaStreamAudioSourceNode, <TAudioNodeRenderer<T>>null);

this._nativeMediaStreamAudioSourceNode = nativeMediaStreamAudioSourceNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { TNativeMediaStreamTrackAudioSourceNodeFactoryFactory } from '../types';

export const createNativeMediaStreamTrackAudioSourceNodeFactory: TNativeMediaStreamTrackAudioSourceNodeFactoryFactory = (
createInvalidStateError,
isNativeOfflineAudioContext
createInvalidStateError
) => {
return (nativeAudioContext, { mediaStreamTrack }) => {
// Bug #121: Only Firefox does yet support the MediaStreamTrackAudioSourceNode.
Expand All @@ -18,11 +17,6 @@ export const createNativeMediaStreamTrackAudioSourceNodeFactory: TNativeMediaStr
throw createInvalidStateError();
}

// Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.
if (isNativeOfflineAudioContext(nativeAudioContext)) {
throw new TypeError();
}

return nativeMediaStreamAudioSourceNode;
};
};
6 changes: 6 additions & 0 deletions src/factories/test-audio-buffer-constructor-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ import { TTestAudioBufferConstructorSupportFactory } from '../types';
*
* Bug #169: Safari up to version 13.1 threw an error on each attempt to change the channelCount of an AudioDestinationNode.
*
* Bug #171: Safari up to version 13.1 allowed to create a MediaElementAudioSourceNode with an OfflineAudioContext.
*
* Bug #172: Safari up to version 13.1 allowed to create a MediaStreamAudioSourceNode with an OfflineAudioContext.
*
* Bug #173: Safari up to version 13.1 allowed to create a MediaStreamAudioDestinationNode with an OfflineAudioContext.
*
* Bug #180: Safari up to version 13.1 not allowed to use ordinary arrays as parameters of createPeriodicWave().
*/
export const createTestAudioBufferConstructorSupport: TTestAudioBufferConstructorSupportFactory = (nativeAudioBufferConstructor) => {
Expand Down
3 changes: 1 addition & 2 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -805,8 +805,7 @@ const baseAudioContextConstructor = createBaseAudioContextConstructor(
const mediaElementAudioSourceNodeConstructor: TMediaElementAudioSourceNodeConstructor = createMediaElementAudioSourceNodeConstructor(
audioNodeConstructor,
createNativeMediaElementAudioSourceNode,
getNativeContext,
isNativeOfflineAudioContext
getNativeContext
);
const mediaStreamAudioDestinationNodeConstructor: TMediaStreamAudioDestinationNodeConstructor =
createMediaStreamAudioDestinationNodeConstructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { TAudioNodeConstructor } from './audio-node-constructor';
import { TGetNativeContextFunction } from './get-native-context-function';
import { TIsNativeOfflineAudioContextFunction } from './is-native-offline-audio-context-function';
import { TMediaElementAudioSourceNodeConstructor } from './media-element-audio-source-node-constructor';
import { TNativeMediaElementAudioSourceNodeFactory } from './native-media-element-audio-source-node-factory';

export type TMediaElementAudioSourceNodeConstructorFactory = (
audioNodeConstructor: TAudioNodeConstructor,
createNativeMediaElementAudioSourceNode: TNativeMediaElementAudioSourceNodeFactory,
getNativeContext: TGetNativeContextFunction,
isNativeOfflineAudioContext: TIsNativeOfflineAudioContextFunction
getNativeContext: TGetNativeContextFunction
) => TMediaElementAudioSourceNodeConstructor;
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { TAudioNodeConstructor } from './audio-node-constructor';
import { TGetNativeContextFunction } from './get-native-context-function';
import { TIsNativeOfflineAudioContextFunction } from './is-native-offline-audio-context-function';
import { TMediaStreamAudioSourceNodeConstructor } from './media-stream-audio-source-node-constructor';
import { TNativeMediaStreamAudioSourceNodeFactory } from './native-media-stream-audio-source-node-factory';

export type TMediaStreamAudioSourceNodeConstructorFactory = (
audioNodeConstructor: TAudioNodeConstructor,
createNativeMediaStreamAudioSourceNode: TNativeMediaStreamAudioSourceNodeFactory,
getNativeContext: TGetNativeContextFunction,
isNativeOfflineAudioContext: TIsNativeOfflineAudioContextFunction
getNativeContext: TGetNativeContextFunction
) => TMediaStreamAudioSourceNodeConstructor;
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { TInvalidStateErrorFactory } from './invalid-state-error-factory';
import { TIsNativeOfflineAudioContextFunction } from './is-native-offline-audio-context-function';
import { TNativeMediaStreamTrackAudioSourceNodeFactory } from './native-media-stream-track-audio-source-node-factory';

export type TNativeMediaStreamTrackAudioSourceNodeFactoryFactory = (
createInvalidStateError: TInvalidStateErrorFactory,
isNativeOfflineAudioContext: TIsNativeOfflineAudioContextFunction
createInvalidStateError: TInvalidStateErrorFactory
) => TNativeMediaStreamTrackAudioSourceNodeFactory;
Original file line number Diff line number Diff line change
Expand Up @@ -380,38 +380,6 @@ describe('offlineAudioContextConstructor', () => {
});
});

describe('createMediaElementSource()', () => {
// bug #171

it('should not throw an error', () => {
offlineAudioContext.createMediaElementSource(new Audio());
});
});

describe('createMediaStreamDestination()', () => {
// bug #173

it('should not throw an error', () => {
offlineAudioContext.createMediaStreamDestination();
});
});

describe('createMediaStreamSource()', () => {
let audioContext;

afterEach(() => audioContext.close());

beforeEach(() => (audioContext = new webkitAudioContext())); // eslint-disable-line new-cap, no-undef

// bug #172

it('should not throw an error', () => {
const mediaStreamAudioDestinationNode = audioContext.createMediaStreamDestination();

offlineAudioContext.createMediaStreamSource(mediaStreamAudioDestinationNode.stream);
});
});

describe('createScriptProcessor()', () => {
// bug #8

Expand Down

0 comments on commit 73e0b67

Please sign in to comment.