使用Cordova / Phonegap通过Filetransfer发送录制的文件

时间:2014-08-06 09:56:59

标签: ios cordova file-upload media

我正在尝试发送通过媒体插件录制的录音。

当我尝试发送文件时,我收到此FileError.NOT_FOUND_ERR错误:

Error opening file /myRecording100.wav: Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be completed. (Cocoa error 260.)" UserInfo=0xa358640 {NSFilePath=/myRecording100.wav, NSUnderlyingError=0xa34fb30 "The operation couldn’t be completed. No such file or directory"}
2014-08-06 17:02:26.919 Bring Me[40961:c07] FileTransferError {
    code = 1;
    source = "/myRecording100.wav";
    target = "http://XXXX.xom";
}

然而,录制后我可以播放录音

为什么我能够播放该文件(显示文件已录制且正确保存)但FileTransfer 无法发送?

这是我的代码(对于ios):

var my_recorder = null;
var mediaFileFullName = null; // iOS
var mediaRecFile = "myRecording100.wav";
var checkFileOnly = false;

/******
 Call when start recording
******/
function startRecording() {
    checkFileOnly = false;
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onSuccessFileSystem, function() {
        console.log("***test: failed in creating media file in requestFileSystem");
    });
}

function onSuccessFileSystem(fileSystem) {
    if (checkFileOnly === true) {        
        // Get File and send
        fileSystem.root.getFile(mediaRecFile, { create: false, exclusive: false }, onOK_GetFile, onFail_GetFile);
    }
    else {
        // Create File
        fileSystem.root.getFile(mediaRecFile, { create: true, exclusive: false }, onOK_SaveFile, onFail_GetFile);
      }
}

/* Save the file*/
function onOK_SaveFile(fileEntry) {
    mediaFileFullName = fileEntry.fullPath;
    my_recorder = new Media(mediaFileFullName, 
        function() { document.location ="address_form.html"; // Redirect the user to an other page  },
        function(err) { console.log("playAudio():callback Record Error: "+err);}
    );
    my_recorder.startRecord();
}

/* Get the file and send it */
function onOK_GetFile(fileEntry) {
    mediaFileFullName = fileEntry.fullPath;
    /*
        // Read the recorded file is WORKING !
        my_player = new Media(mediaFileFullName, onMediaCallSuccess, onMediaCallError);
        my_player.play();
    */
    var options = new FileUploadOptions();
    options.fileKey = "want";
    options.fileName = "file.wav";
    options.mimeType = "audio/wav";
    options.chunkedMode = false;
    options.params = parameters;

    var ft = new FileTransfer();
    ft.upload(mediaFileFullName, "https://SERVER_ADDRESS", win, fail, options);
}



/******
    Called when stop recording
******/
function stopRecording() {
    if (my_recorder) {
        my_recorder.stopRecord();
    }
}

2 个答案:

答案 0 :(得分:1)

我在iOS上遇到了完全相同的问题,而FileUploadOptions对我来说并不起作用。

如果有人也在苦苦挣扎,我的解决方案就是切换到LocalFileSystem.Temporary。

这里有一个片段,显示了一个完整的示例(在Android上测试):

var accessType = LocalFileSystem.TEMPORARY; // It was LocalFileSystem.PERSISTENT;

/** Utility function to return a fileEntry together with the metadata. */
var getFile = function(name, create, successCallback, failCallback) {

    WL.Logger.debug("Request for file " + name + " received, create is " + create + ".");

    var onSuccessFileSystem = function(fileSystem) {

        fileSystem.root.getFile(name, { create: create, exclusive: false },
            function(fileEntry){

                WL.Logger.debug("Success, file entry for " + name + " is " + JSON.stringify(fileEntry));

                fileEntry.getMetadata(function(metadata){
                    WL.Logger.debug("File entry " + name + " metadata is: " + JSON.stringify(metadata));
                    successCallback(fileEntry, metadata);
                }, function(err) {
                    WL.Logger.debug("Fail to retrieve metadata, error: " + JSON.stringify(err));
                    if(failCallback) failCallback(err);
                });

            }, 
            function(err) {
                    WL.Logger.error("Failed to retrieve the media file " + name + ".");
                    if(failCallback) failCallback(err);
            });

    }

    window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;

    window.requestFileSystem(accessType, 0, onSuccessFileSystem, function(err) {
        WL.Logger.error("Failed to access file system.");
        if(failCallback) failCallback(err);
    });

};


var Recorder = declare([  ], {

    mediaSrc : null,
    mediaObj : null,

    constructor : function(data, domNode){
        this.mediaSrc = "new_recording.wav";
    },

    startRecord : function() {

        var self = this;

        var startRecording = function(source) {

            var onMediaCallSuccess = function()  { WL.Logger.debug("Media object success."); };
            var onMediaCallError = function(err) { WL.Logger.error("Error on the media object: " + JSON.stringify(err)); };

            self.mediaObj = new Media(source, onMediaCallSuccess, onMediaCallError);
            self.mediaObj.startRecord();

        };

        // On iOS, first I need to create the file and then I can record.
        if (deviceCheck.phone.ios) {
            WL.Logger.debug("iOS detected, making sure the file exists.");
            getFile(this.mediaSrc, true, function(fileEntry){ startRecording(fileEntry.fullPath); });
        } else {
            if (!deviceCheck.phone.android)
                WL.Logger.warn("Don't know the device, trying to record ...");
            else
                WL.Logger.debug("Android detected.");
            startRecording(this.mediaSrc);
        }

    },

    stopRecord : function() {
        this.mediaObj.stopRecord();
        this.mediaObj.release();
    },

    play: function() {

        var p,
            playSuccess = function() { WL.Logger.debug("Play success."); p.release(); },
            playFail = function() { WL.Logger.debug("Play fail."); };

        p = new Media(this.mediaSrc, playSuccess, playFail);
        p.play();

    },

    getData : function(successCallback, failCallback) {

        var fileName = (deviceCheck.phone.android ? "/sdcard/" : "") + this.mediaSrc;

        WL.Logger.debug("Asking for the file entry ... ");

        getFile(this.mediaSrc, false,
                function(fileEntry, metadata) {

                    WL.Logger.debug("Success: I found a file entry: " + fileEntry.nativeURL + ", size is " + metadata.size);

                    fileEntry.file(function(file) {
                        WL.Logger.debug("Success: file retrieved!");
                        var reader = new FileReader();
                        reader.onloadend = function(evt) {
                            WL.Logger.debug("Sending content and event data to success callback.");
                            successCallback(this.result, metadata, evt);
                        };
                        reader.readAsDataURL(file);
                    }, function(err){
                        WL.Logger.error("Error: Impossible to retrieve the file");
                        failCallback(err);
                    })

                }, function(err){
                    WL.Logger.error("Fail: no file entry found: " + JSON.stringify(err));
                    failCallback(err);
                });

    }

});

有一些Worklight(调试输出)和dojo(声明),但这段代码可以作为参考。

答案 1 :(得分:0)

从文件插件的v1.0开始,要通过文件传输插件在文件系统中上传文件,你需要使用.toURL()方法来访问它。

  

如果要升级到新的(1.0.0或更新版本)File,和   您以前一直使用entry.fullPath作为参数   下载()或upload(),然后您将需要更改您要使用的代码   而是文件系统URL。

     

FileEntry.toURL()和DirectoryEntry.toURL()返回文件系统URL   形式

所以正确的代码是:

/* Get the file and send it */
function onOK_GetFile(fileEntry) {

    var options = new FileUploadOptions();
    options.fileKey = "want";
    options.fileName = "file.wav";
    options.mimeType = "audio/wav";
    options.chunkedMode = false;
    options.params = parameters;

    var ft = new FileTransfer();
    ft.upload(fileEntry.toURL(), "https://SERVER_ADDRESS", win, fail, options);
}