Phaser 3 game app on iOS generated with Capacitor lacks audio functionality

I have developed a basic test app using Phaser 3 (written in Typescript and transpiled with rollup) and am utilizing Capacitor to convert it into an iOS application on my Mac.

This excerpt highlights the key functionality of the app:

function preload () {
    this.load.audio('boom', ['boom.mp3', 'boom.ogg', './boom-44100.ogg', './boom-44100.mp3']);
    this.load.image('wizball', './wizball.png');
}

function create () {
    const image = this.add.image(400, 300, 'wizball').setInteractive();;
    this.boom = this.sound.add('boom');
    image.on('pointerup', () => {
        this.boom.play();
    });
}

The app displays an image of a wizball, and upon clicking it, you should hear a "boom" sound.

Here is what happens when I run it:

  • Using npm run watch and accessing http://localhost:10001 in a browser on my Mac, everything functions correctly;
  • Loading index.html from the dist/ directory in a browser on my Mac results in successful operation;
  • Accessing on either my Mac or iPad works as expected;
  • However, after building an iOS app in Xcode using Capacitor, clicking the image yields no sound at all.

These are the steps followed to generate the iOS app:

npm i
npm run watch
npx cap add ios
npx cap copy ios
npx cap open ios

The console log in Xcode showcases the following error message:

Error: There is no audio asset with key "boom" in the audio cache
⚡️  URL: capacitor://localhost/game.js

I find it perplexing because the image asset loads without any issues. Both boom.mp3 and wizball.png are present in the ios/App/public/ directory.

To access the complete code along with instructions for reproduction, visit: https://github.com/joostvunderink/soundtest Ensure that you have node 10+ and Xcode (with at least one virtual device configured) installed to build the iOS app.

What could I be missing?

Answer №1

To prevent web audio in your game configuration, add the following code to the bottom of your game config.

let game = new Phaser.Game({
  ...
  audio: {
    disableWebAudio: true
  }
});

Important Note:

  • Disabling web audio will cause Phaser to use html5 audio instead.
  • Using html5 audio instead of web audio may result in slower game performance.

If you encounter this issue, consider these alternatives:

  1. Utilize external audio files, as web audio can still function with audio files that are not part of internal assets (the reason for this is unknown).
  2. Implement a native audio/media plugin to handle audio playback in the phaser-capacitor app.

Answer №2

Encountering a similar issue myself. I discovered that the phaser loader on iOS cannot interpret ArrayBuffer when loading sound. To work around this, I utilize a basic fetch method to load audio content and then incorporate it into phaser using scene.sound.decodeAudio.

fetch(sound.url)
  .then((response) => response.arrayBuffer())
  .then((response) => {
    scene.sound.decodeAudio({
      data: response,
      key: 'audioKey',
    });
  });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for concealing tick labels in d3 using TypeScript

When trying to hide tick labels by passing an empty string to the .tickFormat("") method, I encountered an issue with Typescript. The error message received was as follows: TS2769: No overload matches this call. Overload 1 of 3, '(format: null): Axi ...

What is the best way to display a single instance of a React component that is declared in multiple locations within the app?

Imagine I have 2 main components, A and B. Now, component C needs to be created inside both A and B. How can I guarantee that the same exact instance of C is generated in both places? Essentially, I want them to stay synchronized - any changes made to one ...

The Vue component fails to respond to updates in plugin data

I am currently working on implementing a feature where a component reacts to data changes in a custom Vue plugin. To achieve this, the plugin creates a new instance of a Vue object in its constructor: this._vm = new Vue({ data: { obj: null, stat ...

What is the reason for the reconnect function not activating when manually reconnecting in Socket.IO?

After disconnecting the client from the node server using socket.disconnect(true);, I manually re-establish the connection on the client side with socket.open(). The issue arises when triggering socket.open(); the socket.on('reconnect', (attempt ...

the div background is limited to the exact size of the text, not filling the entire

Currently, as I work on my web page using react.js, I'm facing the challenge of implementing a full-size background. Despite my efforts, the background only occupies the size of the text within the div. Here is the snippet of code I am working with: a ...

Discover the magic of Google Charts with the ability to showcase HTML source code within tooltips

I am attempting to show a Pie Chart using Google Charts with HTML in the tooltips, but I am encountering an issue where the HTML source is visible. I have tried setting html:true on the data column and tooltip.isHtml in the options, but I am unsure of what ...

"Encountering a 403 error while using the request method in Node.js

app.post("/",function(req,res){ // console.log(req.body.crypto); request("https://apiv2.bitcoinaverage.com/indices/global/ticker/all?crypto=BTC&fiat=USD,EUR",function(error,response,body){ console.error('error:', error ...

What is the best way to transform a BLOB Buffer into a Base64 string using Swift?

I am facing an issue where I have stored a base64 string as a BLOB in Swift, but now I am struggling to figure out how to convert the buffered blob back into a UIImage. When storing it, Blob converts it into buffer, here is what I did: let image: UII ...

TypeScript implementation of internationalization message extraction in Create React App

I am facing challenges in getting i18n messages extracted, as defined by react-intl's defineMessages, to function correctly in a TypeScript-based CRA. Here are the methods I've attempted: Initial Approach I tried following this guide to make i ...

Issue with model not being updated after making a request using $http service

I have a hunch as to why it's not functioning properly, but I'm unsure on how to troubleshoot this. Despite looking at similar questions and answers on SO, I am unable to resolve my issue. My goal is to trigger a service upon page load in order ...

Using AngularJS, we can create a nested ng-repeat with an expression to filter the

I'm having trouble using a value from the initial ng-repeat as a filter in the nested ng-repeat. The issue lies with {{alpha.value}}. It displays correctly in the first repeat, including the filter and the h3 tag. However, in the second repeat, it s ...

Using CSS properties as false values within React applications

Can you provide guidance on using conditional styles with conditional operators? What would be the ideal code example? Is it possible to use non-CSS values? margin: isOpen ? '10px' : undefined margin: isOpen ? '10px' : 'initial&a ...

Ways to update the entire MobX observable array with new values

When working with MobX, is there a way to update the values of an observable array without re-setting every value? At first glance, one might think the solution is: let arr = observable([]); autorun(() => { console.log('my array changed!') ...

Encountering an 'Uncaught TypeError' with Tumblr API due to undefined property 'type' not being read

I have multiple feeds on my website, each fetching posts from various tags. The first feed is functioning properly, but the 2nd and 3rd feeds are displaying the following error: Uncaught TypeError: Cannot read property 'type' of undefined All ...

Creating a new version of an existing method found within a component in a Vue store.js file

As I navigate through the learning curve of vue.js, a seemingly simple question has arisen: how can I achieve the following task? Within one of my vue components, I am facing challenges with the implementation of the "loadSuggestedUsers" method. Here is t ...

Sending state properties to components within a route

In my React structure, I have the following setup: <Provider store={ store }> <Router> <Switch> <Route path="/how-to" component={ Help } /> <Route path="/start" c ...

Unable to include or create the ios platform in Cordova version 5.0.0

Whenever I attempt to add the ios platform to a boilerplate Cordova project, I encounter the following issues: jondamato$ cordova platform add ios Adding ios project... mv: no such file or directory: project.pbxproj mv: dest is not a directory (too many ...

I am trying to retrieve the class name of each iframe from within the iframe itself, as each iframe has a unique class name

My index HTML file contains multiple Iframes. I am trying to retrieve the class names of all iframes from inside an iframe. Each iframe has a different class name. If any of the iframes have a class name of 'xyz', I need to trigger a function. I ...

Distributing information to modules made of Polymer

Is there a way to create a single source for all data that my elements can utilize but not change (one-way data-binding)? How can I achieve this without using a behavior? I attempted the following in my code: <script type="text/javascript" src="/data. ...

Preserve the previous and current state within a React application

Within my code, there is a state called newuser that undergoes changes based on the inputs entered into the input fields. This change occurs once all input fields are filled and the submit button is clicked. The goal I have in mind is to store the current ...