Ionic 2 / iOS - native sound does not find file in cordova.file.dataDirectory
I am using cordova-plugin-nativeaudio to play audio in an application. When I try to preload a file using an iOS device:
preload('testsound', cordova.file.dataDirectory + "audio/0/Hello.mp3");
I am getting the error:
ERROR: Unhandled promise rejection: (NATIVE AUDIO) No assets found. (file: /// var / mobile / Containers / Data / Application / "[GUID] /Library/NoCloud/audio/0/Hello.mp3); Zone :; Task: setTimeout; Value: (NATIVE AUDIO) No assets found . (File: /// var / mobile / Containers / Data / Application / [GUID] /Library/NoCloud/audio/0/Hello.mp3)
Target file
The target file (audio / 0 / Hello.mp3) is loaded from external url and stored in cordova.file.dataDirectory. It loads successfully as follows:
Download complete: file: /// var / mobile / Containers / Data / Application / [GUID] /Library/NoCloud/audio/0/Hello.mp3
To make sure it is indeed saved in its intended location, I checked:
this.file.checkFile(cordova.file.dataDirectory, "audio/0/Hello.mp3")
The console output shows it successfully saved:
file: /// var / mobile / Containers / Data / Application / [GUID] /Library/NoCloud/audio/0/Hello.mp3 EXIST file!
Now I tried to preload the file with native sound, I get the error above (first error in this question).
The problem is where the file is stored
I also tried preloading from local applicationDirectory (/www/assets/audio/0/Hello.mp3), preload worked fine. However, applicationDirectory is readonly directory, so I cannot load audio from external url and save them there.
Native audio must support preloading from url (not just from local applicationDirectory) as it is listed in their Ionic API doc.
I am getting the same error with both emulator and iOS device.
Has anyone experienced the same problem and managed to figure it out?
Thank you for your help. BR /
source to share
On iOS, if you need to play audio in sync as part of a sequence or transition, the only thing that worked for me was to preload with Anative PreloadComplex with a file in my / asset.
import { NativeAudio } from '@ionic-native/native-audio';
...
let id = new Date().toISOString();
this.nativeAudio.preloadComplex(id, 'assets/file.m4a', 1, 1, 0).then(() => {
this.nativeAudio.play(id, () => {
this.nativeAudio.unload(id).then(() => {
// Next step
});
});
});
If the audio can be played asynchronously and is recorded by the user, the only thing that worked for me is the Media Plugin.
import { Media, MediaObject } from '@ionic-native/media';
...
if (this.mediaObject) {
this.mediaObject.release();
}
this.mediaObject = this.media.create('../Library/NoCloud/MediaFiles/file.m4a');
this.mediaObject.play();
...
ionViewDidLeave() {
if (this.mediaObject) {
this.mediaObject.release();
}
}
source to share
I found a workaround which is to use the Media plugin instead of native audio to play the mp3 file.
Although the Media plugin has the same problem: you cannot access the .dataDirectory cord file from iOS and is discussed in this Jira - there is at least a workaround for that, which is to use .InInternalURL ().
toInternalURL : Returns the path in the form file: /// persistent / path / to / entry (Firefox, IE). Chrome returns the path in the form cdvfile: // localhost / persistent / file.
The internalURL of the cordova.file.dataDirectory file (file: /// var / mobile / Containers / Data / Application / [GUID] / Library / NoCloud) is "cdvfile: // localhost / library-nosync /"
So, replacing:
storageDirectory = cordova.file.dataDirectory;
from:
storageDirectory = "cdvfile://localhost/library-nosync/"
The media plugin can now load and play mp3 files downloaded and saved in cordova.file.dataDirectory with an iOS device.
audioMedia = new MediaPlugin(storageDirectory + "test.mp3");
audioMedia.play();
PS1 This is a working solution as of June 2017.
PS2 I tried using internalURL with Native Audio which didn't work.
source to share