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

Received a syntax error from the DOM parser even after successfully downloading it through NPM

Seeking guidance as a beginner in this technology field. I have installed dom-parser from the NPM package. However, when I tried to declare it below, I encountered a syntax error. Although it seems like a minor issue, I am puzzled and unsure of where I am ...

Using various conditions and operators to display or conceal HTML elements in React applications, particularly in NextJS

I am seeking ways to implement conditional logic in my React/Next.js web app to display different HTML elements. While I have managed to make it work with individual variable conditions, I am encountering difficulties when trying to show the same HTML if m ...

How to Programmatically Disable OnClick Functionality in a Nested Div Using JavaScript and jQuery

I'm currently working on a Javascript application that allows users to enable/disable controls dynamically. While I've had success in disabling/enabling nested inputs and buttons, I'm facing an issue with disabling an onclick event within a ...

Utilize the id in AngularJS to bring attention to a specific row within a table

I am brand new to using angularjs. I currently have a table structured like this: HTML <table class="table table-striped" id="manageResumeTable"> <thead class="text-center text-info text-capitalize"> <th class="text-center col- ...

what sets apart parseint from minus

Typically, my approach for parsing numbers in JavaScript involves the following code snippet: var x = "99" var xNumber = x - 0 as opposed to using: var xNumber = parseInt(x) I am curious to know if there are any potential issues with this method in ter ...

When the user clicks on the iframe, they will be redirected to the

My goal is to create a scenario where clicking on an iframe opens the same URL in a new browser tab, while ensuring that scroll and other mouse events within the iframe are not affected. I have experimented with various approaches but none have been succe ...

A guide to building a dynamic form slider that showcases variable output fields with Javascript

I'm interested in creating a Slider Form that shows different output fields when sliding, using Javascript. Something like this: Could anyone provide suggestions on how to achieve this or share any links related to something similar? I haven't b ...

Tips for setting a default value in an input type file using JavaScript

While trying to upload a file from my local system to the server, I encountered an issue where the local path was not being set in the input type file field. As a result, I am unable to successfully upload the file. I would greatly appreciate any assistan ...

Combining CSR and SSR in the next iteration of our project will

In my application, I have three main user roles: Consumer, Merchant, and Admin. I want the pages that Consumers access to be SEO friendly and server rendered. However, for Merchants and Admins, I prefer them to be client rendered with their own respective ...

Error in TypeScript: Typography type does not accept 'string' type as valid

As I attempt to implement the Typography component from material-ui using TypeScript, I encounter a perplexing error message TypeScript is throwing an error: Type 'string' is not assignable to type 'ComponentClass<HTMLAttributes<HTMLE ...

What are the appropriate situations for utilizing getStaticPaths()?

Right now, an API call is being made in a main component and the fetched data is saved in a Singleton. This singleton data needs to be accessed by the getStaticPaths() function. However, due to the fact that getStaticPaths() pre-renders it, the singleton ...

Obtaining an address using latitudes and longitudes with React Google Maps

I created a map using the react-google-map plugin where users can drag the marker to get the latitude and longitude of a location. However, I am only able to retrieve the lat and lng values and not the address. How can I obtain the address as well? Take a ...

Does anyone have any insight on why I can't seem to remove an item from my list of tasks?

Having trouble with my React todo list. After submitting, the list item looks fine. I expect to be able to delete it by clicking on the item, but nothing happens. When I try to add another item, the page refreshes and all items are removed. The console ...

Having difficulty retrieving the necessary information for manipulating the DOM using Express, Ajax, and Axios

When working on DOM manipulation based on AJAX calls, I've encountered an issue where the response is being displayed on my page instead of in the console.log output. This makes it difficult for me to view the data and determine what needs to be inser ...

Using array values with styled-components may lead to an object being potentially 'undefined'

Currently, I am developing a custom Skeleton component that allows for the input of a property called circleSizes. This property is an array of numbers used to define the width and height of the Skeleton element. Below is the code snippet for the componen ...

An error arises when using the command window.close()

I have encountered an issue with this code where it closes all Safari windows but works fine in Internet Explorer. What should I do? Is there an alternative method for closing the current opened window in every browser? <input type='button' v ...

pausing a timer using JavaScript or jQuery

My goal is to make my clock stop at zero and then display the results page. Unfortunately, I am currently facing difficulties in achieving this. var clock = { time: 2, timeleft: 0, bigben: null, countDown: function() { clock.time--; $("#timer") ...

Assigning value to a member variable in a TypeScript Angular class

Currently, I am in the process of learning Angular. To enhance my skills, I am developing a simple web application using Angular and Spring Boot. One challenge I encountered is assigning a variable to the member variable of a Class. import { Injectable } f ...

Running AngularJS controllers should only occur once the initialization process has been fully completed

I am facing a situation where I need to load some essential global data before any controller is triggered in my AngularJS application. This essentially means resolving dependencies on a global level within AngularJS. As an example, let's consider a ...

Switch the checked status of an input dynamically using jQuery function

It seems like I might be overlooking something quite obvious, but I can't figure out why this jquery function is behaving inconsistently. HTML: <label id="income_this_tax_year"> <div class="left"> <p>Have you had Self-Employm ...