Open wootwoot1234 opened 9 years ago
:+1: please
@wootwoot1234 @fidoboy Have either of you found a solution or workaround to this?
Thanks.
no :(
@fidoboy turns out I may be onto something.
In the LowLatencyAudio.m file around line 52 is where it is looking for the file.
I have modified this based on some code I found at https://github.com/floatinghotpot/cordova-plugin-lowlatencyaudio/blob/master/src/ios/LowLatencyAudio.m and from the CDVFile.m file for finding files.
Basically I am checking for the file in two different places so that I can use local files in the www and ones that I have downloaded and am passing the full CDV File path (cordova.file.dataDirectory +
NSNumber* existingReference = [audioMapping objectForKey: audioID];
if (existingReference == nil)
{
NSString* basePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"www"];
NSString* path = [NSString stringWithFormat:@"%@", assetPath];
NSString* pathFromWWW = [NSString stringWithFormat:@"%@/%@", basePath, assetPath];
NSURL *fileURL = [NSURL URLWithString:path];
NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath];
path = [resolvedFileURL path];
if ([[NSFileManager defaultManager] fileExistsAtPath : path])
{
NSLog(@"could find file at path: %@", path);
LowLatencyAudioAsset* asset = [[LowLatencyAudioAsset alloc] initWithPath:path withVoices:voices];
[audioMapping setObject:asset forKey: audioID];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED];
[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackID];
}
else if ([[NSFileManager defaultManager] fileExistsAtPath : pathFromWWW]) {
NSLog(@"could find file at pathFromWWW: %@", pathFromWWW);
LowLatencyAudioAsset* asset = [[LowLatencyAudioAsset alloc] initWithPath:pathFromWWW withVoices:voices];
[audioMapping setObject:asset forKey: audioID];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED];
[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackID];
}
else
{
NSLog(@"could not file: %@", path);
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_NOT_FOUND];
[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackID];
}
}
else
{
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: WARN_EXISTING_REFERENCE];
[self.commandDelegate sendPluginResult:pluginResult callbackId:callbackID];
}
@fidoboy I just realized that I was using an even older version of this plugin so I believe it would actually be more like this for this project
NSString* basePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"www"];
NSString* path = [NSString stringWithFormat:@"%@", assetPath];
NSString* pathFromWWW = [NSString stringWithFormat:@"%@/%@", basePath, assetPath];
NSURL *fileURL = [NSURL URLWithString:path];
NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath];
path = [resolvedFileURL path];
if ([[NSFileManager defaultManager] fileExistsAtPath : path]) {
NSLog(@"could find file at path: %@", path);
LowLatencyAudioAsset* asset = [[LowLatencyAudioAsset alloc] initWithPath:path withVoices:voices withVolume:volume];
[audioMapping setObject:asset forKey: audioID];
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED] callbackId:callbackId];
} else if ([[NSFileManager defaultManager] fileExistsAtPath : pathFromWWW]) {
NSLog(@"could find file at pathFromWWW: %@", pathFromWWW);
LowLatencyAudioAsset* asset = [[LowLatencyAudioAsset alloc] initWithPath:pathFromWWW withVoices:voices withVolume:volume];
[audioMapping setObject:asset forKey: audioID];
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: CONTENT_LOAD_REQUESTED] callbackId:callbackId];
} else {
NSLog( @"audio file not found" );
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: ERROR_NOT_FOUND] callbackId:callbackId];
}
Thanks gylippus your code is very useful, but it could be pretty cool to have the same on android.
Hi @gylippus can you provide a working fork for this issue? I'm trying to integrate your posted code but struggling with errors like error: use of undeclared identifier 'voices'
which is definitely a really simple case but I'm not Cocoa Dev so I just need to get it running :) Thx a lot if possible.
@gylippus helps sometimes to ask and the answers follow by them self. Got it at least compiling now so no need to answer. Thanks!
@ddresch glad to help :)
-Rubber Duck
Are there any updates on this feature? I'm looking to play multiple audio tracks downloaded and saved in the app's Documents dir.
Anyone implemented the fix for Android? I wish "file://" instead of appending "www/" to path was the implementation here
Honestly, cordovas media plugin has a great function for both android and ios.
IOS for example:
// Maps a url for a resource path for playing
// "Naked" resource paths are assumed to be from the www folder as its base
- (NSURL*)urlForPlaying:(NSString*)resourcePath
{
NSURL* resourceURL = nil;
NSString* filePath = nil;
// first try to find HTTP:// or Documents:// resources
if ([resourcePath hasPrefix:HTTP_SCHEME_PREFIX] || [resourcePath hasPrefix:HTTPS_SCHEME_PREFIX]) {
// if it is a http url, use it
NSLog(@"Will use resource '%@' from the Internet.", resourcePath);
resourceURL = [NSURL URLWithString:resourcePath];
} else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) {
NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]];
NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath);
} else if ([resourcePath hasPrefix:CDVFILE_PREFIX]) {
CDVFile *filePlugin = [self.commandDelegate getCommandInstance:@"File"];
CDVFilesystemURL *url = [CDVFilesystemURL fileSystemURLWithString:resourcePath];
filePath = [filePlugin filesystemPathForURL:url];
if (filePath == nil) {
resourceURL = [NSURL URLWithString:resourcePath];
}
} else {
// attempt to find file path in www directory or LocalFileSystem.TEMPORARY directory
filePath = [self.commandDelegate pathForResource:resourcePath];
if (filePath == nil) {
// see if this exists in the documents/temp directory from a previous recording
NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], resourcePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) {
// inefficient as existence will be checked again below but only way to determine if file exists from previous recording
filePath = testPath;
NSLog(@"Will attempt to use file resource from LocalFileSystem.TEMPORARY directory");
} else {
// attempt to use path provided
filePath = resourcePath;
NSLog(@"Will attempt to use file resource '%@'", filePath);
}
} else {
NSLog(@"Found resource '%@' in the web folder.", filePath);
}
}
// if the resourcePath resolved to a file path, check that file exists
if (filePath != nil) {
// create resourceURL
resourceURL = [NSURL fileURLWithPath:filePath];
// try to access file
NSFileManager* fMgr = [NSFileManager defaultManager];
if (![fMgr fileExistsAtPath:filePath]) {
resourceURL = nil;
NSLog(@"Unknown resource '%@'", resourcePath);
}
}
return resourceURL;
}
I am using cordovaMedia (via its angular wrapper ngCordova) and the problem is the delay. May be it is because there is no preload, like in NativeAudio.
I have an easy solution for this for anyone interested. Use CDV urls and then just resolve them to a full path.
export const getFile = function(path) {
return new Ember.RSVP.Promise( (resolve) => {
window.resolveLocalFileSystemURL(path, function(entry) {
resolve(entry);
});
});
};
then you can
let path = fileEntry.toURL();
// need a root level path
path = path.replace('file://', '');
then use my fork which eliminates the hardcoded www, so you can play files from anywhere on your device.
https://github.com/optikalefx/cordova-plugin-lowlatencyaudio/commit/7aaf6ce948a697d344efe0e186aa017cf6569bc4
How has this not been resolved yet? It's pretty important not being restricted to the www/ folder.
My fork has this resolved.
simply...
path = path.replace('file://', '');
-- the above worked for ios, android needed a little more
in the folder plugin/cordova-plugin-nativeaudio/src/android
edit line 85 of NativeAudio.java from
String fullPath = concat("www"+assetPath);
to
String fullPath = assetPath;
you will then need to remove the android platform and then re-add it for the plugin to update
cordova platforms rm android
cordova platforms add android
Cordova has cleaned up it's file api and now makes it really easy to create/edit/move files. The problem is, I can't pass a 'file://' url to this plugin only relative paths. Would it be possible to add support for absolute paths or for 'file://" urls?
https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md
Thanks