更新到3.3.0后,Cordova视频/音频将无法播放cdvfile:// urls

时间:2014-02-18 06:35:57

标签: android ios audio cordova

我的Cordova应用程序从服务器下载音频文件,并在设备离线时可以播放。这一切都正常,直到昨天我升级到最新版本。

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

但是,使用新的URL方案不适用于音频文件。尝试播放该文件时,我收到错误消息"Cannot use audio file from resource 'cdvfile://localhost/persistent/path/to/file'"

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

似乎Cordova没有更新CDVSound插件来处理新的文件名格式,但如果我能像以前一样访问完全限定的路径,它仍然可以工作。我查看了新的代码和文档,但还没有找到办法。

有没有人设法从文件插件中获取完全限定的路径?

3 个答案:

答案 0 :(得分:8)

我使用dev分支进行文件传输和文件传输。他们在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>

如果它适用于视频,它肯定适用于音频。

答案 1 :(得分:2)

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

此代码发布后,我会在此发回。

更新 - 截至2014-03-04,已发布媒体和文件的修复程序。文件1.0.1和媒体0.2.9一起工作以播放来自cdvfile URL的音频。

答案 2 :(得分:0)

我仍然没有获得完全合格路径的答案,但我决定破解iOS插件,直到Cordova正确修复。 (至少我现在可以继续使用dev。)

以下代码来自file-transfer插件,可以添加到CDVSound.m以允许媒体插件播放具有新cdvfile://路径的音频文件,仅限iOS。 虽然被警告,但我之前从未写过一行ObjC,而且代码几乎没有经过测试。在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