Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot play files in document folder #39

Open
gillarf opened this issue Sep 1, 2021 · 9 comments
Open

Cannot play files in document folder #39

gillarf opened this issue Sep 1, 2021 · 9 comments

Comments

@gillarf
Copy link

gillarf commented Sep 1, 2021

The native audio plugin is working really well for files provided in the build, but we are downloading files from the cloud and storing them in the document folder of the app (e.g. /var/mobile/Containers/Data/Application/5CF2D476-0B24-4F2C-A331-AEECDF390071/Documents/ in my case), which is where Capacitor filesystem saves them. We would like to play them from there.

However when I try this, and I set the path to, for example "var/mobile/Containers/Data/Application/5CF2D476-0B24-4F2C-A331-AEECDF390071/Documents/1630516106806.m4a" then I get an 'Error: Asset Path is missing' error message.

Is there a way around this? I tried "/var..." and "file://var..." as the path to no avail.

Any help much appreciated.

@mariusbolik
Copy link

@gillarf I have the same issue. Did you get it working?

@gillarf
Copy link
Author

gillarf commented Dec 15, 2021

@mariusbolik no unfortunately not. In the end we played them directly over http. It was the only solution. It's a shame really. Maybe someone can solve it. If it were possible to copy the file from documents to the right location, that would be OK I suppose, but i seem to remember I couldn't do this either.

@mariusbolik
Copy link

Totally my fault. It works great. I misspelled the file path!
Here is my code:

  const AUDIO_FILE_DIRECTORY = 'podcast';

  async preload() {
    if (this.platform.is('capacitor')) {
      const currentEpisode = 'https://domain.com/files/my-audio-file.mp3';
      await this.downloadFile(currentEpisode);

      await NativeAudio.preload({
        assetId: 'xyz',
        assetPath: await this.getFileUri(this.extractFileNameFromUrl(currentEpisode)),
        audioChannelNum: 1,
        isUrl: true
      });
    }
  }

  private async downloadFile(url: string) {
    if (this.platform.is('capacitor')) {
      const { data } = await Http.get({
        url,
        responseType: 'blob',
        headers: {
          accept: 'audio/mp3',
          contentType: 'audio/mp3',
        }
      });
      await Filesystem.writeFile({
        directory: Directory.Data,
        path: `${AUDIO_FILE_DIRECTORY}/${this.extractFileNameFromUrl(url)}`,
        data
      });
    }
  }

  private async getFileUri(filename: string) {
    const { uri } = await Filesystem.getUri({
      directory: Directory.Data,
      path: `${AUDIO_FILE_DIRECTORY}/${filename}`
    });
    return uri;
  }

  private extractFileNameFromUrl(url: string) {
    return url.split('/').pop();
  }

@timstoute
Copy link

thanks @mariusbolik for your code example here (how to download a mp3 file from a server, store it locally and play it). My question is: why are you choosing this pattern instead of playing the file directly from an http stream?

More broadly speaking, why do Ionic / Capacitor app developers rely on this plugin vs a web/js audio player like, for example OpenPlayerJs ?

@mariusbolik
Copy link

Hi @timstoute,
my approach is a good solution to provide an offline mode like Spotify. Meanwhile I'm using HTML5 Audio to stream audio files in Ionic / Capacitor applications. I also use HTML5 Audio to play local audio files. I'm not using the native audio plugin anymore. HTML5 is great because no plugin, framework, etc. is needed.

@timstoute
Copy link

@mariusbolik thanks for your reply, I appreciate the discussion. I've been using HTML5 Audio to stream audio files in my Ionic / Capacitor application and I'm running into a problem with the app on iOS 15.4 when it's the device is locked and/or the app is in background mode. When my app is in background, the code responsible to get the next track url executes, but the stream does not play. I see following error like the following:

ProcessAssertion: Failed to acquire RBS assertion 'WebKit Media Playback'

originator doesn't have entitlement com.apple.runningboard.assertions.webkit AND originator doesn't have entitlement com.apple.multitasking.systemappassertions

So, generally speaking, I'm wondering if you've had success with playback of a series of files (a playlist) while your app is in background mode?

@mariusbolik
Copy link

@timstoute sounds interesting! Does the problem only happen if the next track start automatically? Or does it also happen if a user skips a track using the lockscreen controls?

@timstoute
Copy link

timstoute commented Apr 6, 2022

@mariusbolik good question; the lockscreen does not show any "skip" buttons for my app, so this implies that the iOS has no knowledge of the playlist (next track), or the app's ability to play successive tracks. I'm thinking that I'll need to create a custom Capacitor plugin to work around this issue by accessing the native iOS AVQueuePlayer. I agree with you that "HTML5 is great because no plugin, framework, etc. is needed." but in this case it appears a plugin is needed. I can't find any existing Capacitor plugins that provide this audio playlist in background requirement. If you have any further thoughts or suggestions on this I'd love to hear them. I just found this and will check it out: https://github.com/phiamo/capacitor-plugin-playlist/blob/main/README.md

@simon-acuitymd
Copy link

simon-acuitymd commented Aug 18, 2023

@mariusbolik do you have code samples for playing a file using html5 audio from a file stored in the local filesystem? Would love to see the minimal code for that as well. Do you just set the src to a file:: url?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants