在更新到3.3.0之后,Cordovavideo/audio将不会从cdvfile:// urls播放

我的Cordova应用程序从服务器下载audio文件,并使其可在设备脱机时播放。 这一切都工作正常,直到昨天,当我升级到最新版本。

最初,下载(通过文件传输插件)和播放(通过媒体插件)都不起作用。 进一步研究,我发现fileSystem.root.fullPath现在返回一个相对应用程序本地web根文件夹的path,但它用来返回一个完全限定的path。 cordova现在build议使用fileSystem.root.toURL()而不是( http://cordova.apache.org/news/2014/02/10/plugins-release.html )。 这确实解决了文件传输问题。

但是,使用新的URLscheme不适用于audio文件。 当试图播放文件时,出现"Cannot use audio file from resource 'cdvfile://localhost/persistent/path/to/file'"

检查cordova问题跟踪器我发现有人报告了同样的问题的video文件以及( https://issues.apache.org/jira/browse/CB-6051 )。

似乎cordova还没有更新CDVSound插件来处理新的文件名格式,但如果我能像以前一样访问完全限定的path,它可能仍然有效。 我已经看了新的代码和文档,但还没有find办法做到这一点。

有没有人设法从文件插件获得完全合格的path?

我使用开发分支进行文件和文件传输。 他们在Entry类中添加了一个函数toNativeURL你需要从github项目下载zip文件:

https://github.com/apache/cordova-plugin-file-transfer/tree/dev

https://github.com/apache/cordova-plugin-file/tree/dev

https://github.com/apache/cordova-plugin-media/tree/dev

然后将它们安装到你的项目:

 cordova plugin rm org.apache.cordova.file-transfer cordova plugin rm org.apache.cordova.file cordova plugin rm org.apache.cordova.media cordova plugin add <path_to_unzipped_dev_branch_of_file_plugin> cordova plugin add <path_to_unzipped_dev_branch_of_file-transfer_plugin> cordova plugin add <path_to_unzipped_dev_branch_of_media_plugin> 

这是我工作的一个例子:

 <!DOCTYPE html> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 --> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> <link rel="stylesheet" type="text/css" href="css/index.css" /> <title>Hello World</title> </head> <body> <div id="main" class="app"> <h1>Apache Cordova</h1> <div id="deviceready" class="blink"> <p class="event listening">Connecting to Device</p> <p class="event received">Device is Ready</p> </div> <div id="messages"> Loading Video... </div> <video width="320px" height="240px" controls></video> </div> <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="js/index.js"></script> <script type="text/javascript"> app.initialize(); document.addEventListener("deviceready", onDeviceReady, false); // device APIs are available // function onDeviceReady() { console.log('Requesting file system'); window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail); } function gotFS(fileSystem) { fileSystem.root.getDirectory("vids", {create: true}, gotDir); } function gotDir(dirEntry) { dirEntry.getFile("video.mp4", {create: true, exclusive: false}, gotFile); } function gotFile(fileEntry) { var localPath = fileEntry.fullPath; var localUrl = fileEntry.toURL(); console.log('Loaded local path: ' + localPath); console.log('Loaded local url: ' + localUrl); var fileTransfer = new FileTransfer(); var uri = encodeURI('http://<url_to_video>.mp4'); console.log('Downloading ' + uri + ' to ' + localPath); fileTransfer.download( uri, localUrl, function(entry) { console.log('download complete (path): ' + entry.fullPath); console.log('download complete (url): ' + entry.toURL()); console.log('download complete (native): ' + entry.toNativeURL()); document.getElementById('messages').innerHTML = 'Downloaded Video path: ' + entry.fullPath + '<br />' + 'Downloaded Video url: ' + entry.toURL() + '<br />' + 'Downloaded Video Native url: ' + entry.toNativeURL() + '<br />'; var videoNode = document.querySelector('video'); videoNode.src = entry.toNativeURL(); }, function(error) { console.log('download error source ' + error.source); console.log('download error target ' + error.target); } ); } function fail(error) { console.log('Error creating file [' + error.name + ']: ' + error.message); } </script> </body> </html> 

如果它与video一起工作,它肯定应该用audio。

[Media] [1]和File插件的开发分支现在可以解决这个问题。 如果你可以从git安装这些插件,那么从cdvfile:// URL播放就可以。

当这个代码被发布的时候,我会在这里发布。

更新 – 截至2014-03-04,媒体和文件的修复已经发布。 文件1.0.1和媒体0.2.9一起工作,从CDV文件的URL播放audio。

我还没有得到一个完全合格的path的答案,但我决定破解iOS插件,直到从Cordova有适当的修复。 (至less我现在可以继续开发。)

下面的代码是从file-transfer插件中获取的,可以添加到CDVSound.m以允许媒体插件使用新的cdvfile://path(仅限iOS)播放audio文件。 但是请注意 ,我从来没有写过一行ObjC,代码也没有经过testing。 这是一个临时修复,直到cordova修补当前的插件。

 #import "CDVSound.h" #import "CDVFile.h" <-- add #import <Cordova/NSArray+Comparisons.h> ... #define RECORDING_WAV @"wav" #define CDVFILE_PREFIX @"cdvfile://" <-- add extern CDVFile *filePlugin; <-- add @implementation CDVSound ... filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]]; NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath); <--- insert this block here ---> } else if ([resourcePath hasPrefix:CDVFILE_PREFIX]) { CDVFilesystemURL *fsURL = [CDVFilesystemURL fileSystemURLWithString:resourcePath]; if (fsURL && fsURL.fileSystemName != nil) { // This requires talking to the current CDVFile plugin NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:fsURL]; if ([fs respondsToSelector:@selector(filesystemPathForURL:)]) { filePath = [fs filesystemPathForURL:fsURL]; NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath); } else { resourceURL = fsURL.url; } } else { NSLog(@"Unknown resource '%@'", resourcePath); } <--- to here ---> } else { // attempt to find file path in www directory or LocalFileSystem.TEMPORARY directory