native-audio icon indicating copy to clipboard operation
native-audio copied to clipboard

Audio Asset already exists error message

Open HarelM opened this issue 2 years ago • 9 comments

Describe the bug I'm getting a weird error message when using the plugin: Audio Asset already exists

To Reproduce My code is as follows, very simple basically - configure then preload as can be seen here: https://github.com/IsraelHikingMap/Site/blob/83f9795ecc065dc3437b529243307e29361bdea5/IsraelHiking.Web/src/application/services/audio-player.factory.ts#L23

Expected behavior No error should be raised.

Smartphone (please complete the following information):

  • Device: Samsung SM-G998B
  • OS: Android 13

Additional context I've looked in the past at the code and couldn't find a place where this error is returned which would make sense. Any help would be appreciated. This doesn't always happen according to the logs I've got from some clients, I'm running this code when the app starts once, so I don't expect the audio file to already exist... IDK...

HarelM avatar Sep 11 '23 19:09 HarelM

I had this error too when I reload my application. I think it's because the file is load in the cache. This error appear only when the application is already launch once. But I'm not 100% sure of that, I need more test ^^'

Racthor avatar Sep 24 '23 09:09 Racthor

I see this when the application start and not just when resuming the app as far as I can tell from the logs. But I can't see what in the code can cause this, which is strange...

HarelM avatar Sep 24 '23 13:09 HarelM

You can see more precisely the error with .catch() when you call the function : NativeAudio.preload( options ).catch((error) => console.log(error));

Racthor avatar Sep 24 '23 18:09 Racthor

I have the full error message, but that's not helpful. I also looked at the plugin code, the list is static, which means that it should be cleared every time the app starts, but it's not the case...

HarelM avatar Sep 24 '23 19:09 HarelM

Hello thanks for the report, sorry for the late reply, do you see this with builded app or in live reload mode ?

riderx avatar Jan 17 '24 00:01 riderx

Not sure what you mean by live reload, but I see this in my production app log on the device itself.

HarelM avatar Jan 17 '24 09:01 HarelM

live reload is this: https://capacitorjs.com/docs/v4/vscode/build-and-run#live-reload

But seems that not the case, can you provide a reproduction repo ? i cannot reproduce your issue

riderx avatar Jan 18 '24 19:01 riderx

The above linked repo is what I use to reproduce the issue. I don't know if I can create a more minimal reproduction. https://github.com/IsraelHikingMap/Site/tree/main/IsraelHiking.Web/ You'll need to build the app and run it, but you should be able to do it with npm install && npm run build:mobild && npx cap sync and run the app using android studio / build apk and run it on a real device.

I think I tried to reproduce this with the simulator but was not able to, but don't trust my memory.

HarelM avatar Jan 19 '24 20:01 HarelM

@Racthor any updates on this? I can still see the error message in my log files...

HarelM avatar May 22 '24 13:05 HarelM

Hello Harelm, I really need a reproduction repo where you isolate the issue to help you. I cannot test on your app, there are many moving parts involved, and you use CS instead of JS.

riderx avatar May 24 '24 17:05 riderx

I'm not sure I can create a minimal reproduction. Can you create a branch maybe with more logging I can run so I can send you the logs?

HarelM avatar May 24 '24 19:05 HarelM

I think I'm able to reproduce this issue on my personal device now, but I'm not sure I'll be able to attach a debugger. I can use a fork or a brach if needed to install on my device, let me know how I can help.

HarelM avatar May 25 '24 05:05 HarelM

I really understand how this is frustrating @HarelM this doesn’t work for you and that annoying.

I need you to understand my point of view as well. I maintain dozens of open source plugin, I cannot spend time on each issue if the issue is not well isolated. especially when you are the only one reporting it right now.

Please create a reproduction repository, then i will fix it the same day.

sincerely Martin

riderx avatar May 25 '24 07:05 riderx

I fully understand your point of view as an open source maintainer. I want to help here, hopefully by even opening a PR to fix this issue. But I need some guidance where to place logs, what could cause this error message etc.

HarelM avatar May 25 '24 07:05 HarelM

You have here a way to create a super simple app with the CLI: https://capacitorjs.com/docs/getting-started Or you can fork our demo app here: https://github.com/Cap-go/demo-app/tree/main

riderx avatar May 25 '24 08:05 riderx

Ok, thanks for the tip, I'll see if I can reproduce this on my device using the simplest setup.

HarelM avatar May 25 '24 20:05 HarelM

failure.zip

The above is a minimal reproduction. To reproduce the issue do the following:

  1. Unzip
  2. run the app: npm i && npx cap add android && npm run build && npx cap sync android
  3. I needed to change grade to be 8.0.1, not sure it's mandatory.
  4. Open the app - no issues
  5. Close the app using the back button
  6. Open the app fast (without debug, just press the app icon), see the alert with the relevant error message.

I was able to reproduce this on a simulator running android 13 and also on a physical device.

If I needed to guess the static memory is not cleaned, but I have no clue as to why. Edit: might be related to this SO question: https://stackoverflow.com/questions/15995425/how-to-destroy-static-field-when-app-exits

HarelM avatar May 26 '24 09:05 HarelM

i got your code and modified it a bit:

import { SplashScreen } from '@capacitor/splash-screen';
import { NativeAudio } from "@capgo/native-audio";
import { App } from "@capacitor/app";

window.customElements.define(
  'capacitor-welcome',
  class extends HTMLElement {
    constructor() {
      super();

      SplashScreen.hide();

      const root = this.attachShadow({ mode: 'open' });

      root.innerHTML = `
    <style>
      :host {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
        display: block;
        width: 100%;
        height: 100%;
      }
      h1, h2, h3, h4, h5 {
        text-transform: uppercase;
      }
      .button {
        display: inline-block;
        padding: 10px;
        background-color: #73B5F6;
        color: #fff;
        font-size: 0.9em;
        border: 0;
        border-radius: 3px;
        text-decoration: none;
        cursor: pointer;
      }
      main {
        padding: 15px;
      }
      main hr { height: 1px; background-color: #eee; border: 0; }
      main h1 {
        font-size: 1.4em;
        text-transform: uppercase;
        letter-spacing: 1px;
      }
      main h2 {
        font-size: 1.1em;
      }
      main h3 {
        font-size: 0.9em;
      }
      main p {
        color: #333;
      }
      main pre {
        white-space: pre-line;
      }
    </style>
    <div>
      <capacitor-welcome-titlebar>
        <h1>Capacitor</h1>
      </capacitor-welcome-titlebar>
      <main>
        <p>
          Capacitor makes it easy to build powerful apps for the app stores, mobile web (Progressive Web Apps), and desktop, all
          with a single code base.
        </p>
        <h2>Getting Started</h2>
        <p>
          You'll probably need a UI framework to build a full-featured app. Might we recommend
          <a target="_blank" href="http://ionicframework.com/">Ionic</a>?
        </p>
        <p>
          Visit <a href="https://capacitorjs.com">capacitorjs.com</a> for information
          on using native features, building plugins, and more.
        </p>
        <a href="https://capacitorjs.com" target="_blank" class="button">Read more</a>
        <h2>Tiny Demo</h2>
        <p>
          This demo shows how to call Capacitor plugins. Say cheese!
        </p>
        <p>
          <button class="button" id="take-photo">Play sound</button>
        </p>
        <p>
        </p>
      </main>
    </div>
    `;
    }

    connectedCallback() {
      const self = this;

      NativeAudio.configure({focus: false});
      NativeAudio.preload({
          assetId: "uh-oh",
          assetPath: "public/assets/uh-oh.mp3",
          audioChannelNum: 1,
          isUrl: false
      }).catch((error) => { 
        alert(error); 
        
      });

      App.addListener("backButton", () => {
        App.exitApp();
      });

      
      self.shadowRoot.querySelector('#take-photo').addEventListener('click', async function (e) {
        try {
          NativeAudio.play({ assetId: 'uh-oh' });
        } catch (e) {
          console.warn('NativeAudio cannot play', e);
        }
      });
    }
  }
);

window.customElements.define(
  'capacitor-welcome-titlebar',
  class extends HTMLElement {
    constructor() {
      super();
      const root = this.attachShadow({ mode: 'open' });
      root.innerHTML = `
    <style>
      :host {
        position: relative;
        display: block;
        padding: 15px 15px 15px 15px;
        text-align: center;
        background-color: #73B5F6;
      }
      ::slotted(h1) {
        margin: 0;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
        font-size: 0.9em;
        font-weight: 600;
        color: #fff;
      }
    </style>
    <slot></slot>
    `;
    }
  }
);

I was able to preload and then play the sound with the button. If I do return with back-button, then open the app again. I receive the "cannot preload" alert, but the sound can still play. So for me the error message is correct as, the sound play after then message display the sound is already preloaded

riderx avatar Jun 03 '24 12:06 riderx

If the error is correct, then is there a way to avoid it by asking if the file is already preloaded? I would like to have the code that is not wrapped with a try-catch.

HarelM avatar Jun 03 '24 12:06 HarelM

you can now use isPreload in 6.4.1

riderx avatar Jun 03 '24 13:06 riderx

Thanks!! I think you should update the docs to reflect that change. I don't think this is the ideal solution because every developer would need to use this "if isPreload" to avoid getting this error, but I respect your decision and the fact that you are maintaining this library, and it is up to you.

Also I think a better name would be "isPreloaded", but again, your call.

Thanks a lot for all your work on this plugin!!

HarelM avatar Jun 03 '24 16:06 HarelM

You are welcome! Others devs will use try catch i believe that normal path. Reset the list as you did in your Pr will create a leak memory as the assets are never really released i think so i didn't wanted to go that path. I created this solution because you asked for it in your previous message and i found that was a good midway

riderx avatar Jun 03 '24 20:06 riderx

Fair enough. Thanks!

HarelM avatar Jun 04 '24 05:06 HarelM