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

后端 未结 3 1623
一向
一向 2020-12-14 12:50

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

相关标签:
3条回答
  • 2020-12-14 13:13

    I still don't have an answer for getting a fully qualified path, but I decided to hack the iOS plugin until there is a proper fix from Cordova. (At least I can continue on with dev for the moment.)

    The following code was taken from the file-transfer plugin, and can be added to CDVSound.m to allow the media plugin to play audio files with the new cdvfile:// paths, iOS only. Be warned though, I have never written a line of ObjC before and the code has hardly been tested. It is a temp fix until Cordova patches the current plugin.

    #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
    
    0 讨论(0)
  • 2020-12-14 13:28

    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.

    0 讨论(0)
  • 2020-12-14 13:38

    The development branch of the [Media][1] and File plugins now fix this issue. If you can install those plugins from git, then playing from cdvfile:// URLs should just work.

    I'll post back here when this code gets released, as well.

    Update -- As of 2014-03-04, the fixes for Media and File have been published. File 1.0.1 and Media 0.2.9 work together to play audio from cdvfile URLs.

    0 讨论(0)
提交回复
热议问题