Skip to content

Inconsistent return type of createBufferSource() between platforms (Promise on Web, AudioBufferSourceNode on iOS) #574

@niklasdahlheimer

Description

@niklasdahlheimer

Description

While following this example, I encountered an issue on Expo Web due to CORS protection on the remote audio file. To work around it, I used a local audio file via Expo assets as suggested in the example for decodeAudioDataSource().

Then I used the following code:
const playerNode = audioContext.createBufferSource();

This worked as expected on iOS, but on Web I received the following error:
Uncaught (in promise) TypeError: playerNode.connect is not a function

After some investigation, I found the root cause:

  • On iOS, createBufferSource() returns an AudioBufferSourceNode.
  • On Web, it returns a Promise<AudioBufferSourceNode>.

Changing the code to:
const playerNode = await audioContext.createBufferSource();
resolved the issue on both platforms.

📌 Suggestion
If this behavior is intended, it would be very helpful to document the platform-specific return type of createBufferSource()—especially since it's unexpected and can cause runtime issues.

If this is not intended, I recommend unifying the behavior so that createBufferSource() returns a consistent type across platforms.

Thanks again for the great work on this library—just wanted to flag this inconsistency to help improve the dev experience

Steps to reproduce

    const audioContext = new AudioContext();

    const buffer = await
        Asset.fromModule(require('@/assets/audio/example-music-01.mp3'))
            .downloadAsync()
            .then((asset) => {
                if (!asset.localUri) {
                    throw new Error('Failed to load audio asset');
                }
                return audioContext.decodeAudioDataSource(asset.localUri);
            })


    const playerNode = audioContext.createBufferSource();
    playerNode.buffer = buffer;
    playerNode.connect(audioContext.destination);
    playerNode.start(audioContext.currentTime);
    playerNode.stop(audioContext.currentTime + 10);

Snack or a link to a repository

https://snack.expo.dev/@niklasdahlheimer/createbuffersource-example

React Native Audio API version

0.6.5

React Native version

0.79.5

Platforms

iOS

JavaScript runtime

None

Workflow

Expo Dev Client

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions