Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
323 views
in Technique[技术] by (71.8m points)

android - Cordova video / audio won't play from cdvfile:// urls after update to 3.3.0

My Cordova app downloads audio files from a server and makes them available to play when the device is offline. This was all working fine until yesterday when I upgraded to the latest version.

Initially, neither the downloading (via the file transfer plugin) nor the playing (via the media plugin) would work. Looking into it further I found that fileSystem.root.fullPath now returns a path relative to the apps local web root folder, but it used to return a fully qualified path. Cordova now recommends using fileSystem.root.toURL() instead (http://cordova.apache.org/news/2014/02/10/plugins-release.html). This did indeed fix the file transfer issue.

However, using the new URL scheme doesn't work for audio files. When attempting to play the file I get an error saying "Cannot use audio file from resource 'cdvfile://localhost/persistent/path/to/file'".

Checking the Cordova issue tracker I found that someone has reported the same issue for video files as well (https://issues.apache.org/jira/browse/CB-6051).

It would seem that Cordova haven't updated the CDVSound plugin to handle the new file name format, but it might still work if I could get access to the fully qualified path as before. I have looked at the new code and docs but have not found a way to do this.

Has anyone managed to get a fully qualified path from the file plugin?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I got it working for video using the dev branches for file and file-transfer. They added a function to the Entry class called toNativeURL You need to download the zip files from the github projects:

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

Then install them into you project:

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>

This is an example I got working:

<!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>

If it works with video, it should definitely work with audio.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...