【问题标题】:Cordova file upload科尔多瓦文件上传
【发布时间】:2015-07-29 21:35:21
【问题描述】:

我想从我的手机设备存储中将视频上传到 YouTube。但是,当我上传文件时,它是空白的。当我使用相同的上传代码但使用网络文件时,它可以工作。想知道我哪里错了!

方法一 一切都正确上传,视频在 YouTube 上播放。

loadWebFile('assets/intro.mpg');

function loadWebFile(url) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.onload = function (e) {
        uploadFile(xhr.response); // type: Blob
    };
    xhr.onerror = function (e) {
        console.log('loadWebFile.onerror', e);
    };
    xhr.send();
};

方法二 视频标题和说明出现在 YouTube 上,但视频是空白的。我肯定通过了一个有效的文件。

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
if (window.webkitStorageInfo) {
    window.webkitStorageInfo.requestQuota(access, 1024 * 1024, function (bytes) {
        if (window.requestFileSystem) {
            window.requestFileSystem(access, bytes, function (filesystem) {
                loadFile('/Movies/intro.mpg');
            }, me.onError);
        } else {
            window.alert('requestFileSystem not supported');
        }
    }, me.onError);
} else {
    window.alert('webkitStorageInfo not supported');
}

// this sends an empty video to YouTube
function loadFile(path) {
    filesystem.root.getFile(path, null, function (fileEntry) {
        fileEntry.file(function (file) {
            uploadFile(file); // type: File
        });
    }, function (e) {
        console.log('loadFile.error', e);
    });
}

两种方法共享相同的上传功能:

// uploads using the YouTube script
// https://github.com/youtube/api-samples/blob/master/javascript/cors_upload.js
function uploadFile(file) {
    var metadata = {
        snippet: {
            title: 'Video title',
            description: 'Video description',
            tags: 'Video tags',
            categoryId: 22
        },
        status: {
            privacyStatus: 'unlisted'
        }
    };
    var uploader = new MediaUploader({
        baseUrl: 'https://www.googleapis.com/upload/youtube/v3/videos',
        file: file,
        token: accessToken,
        metadata: metadata,
        params: {
            part: Object.keys(metadata).join(',')
        },
        onError: function (e) {
            console.log('onError', JSON.parse(e));
        },
        onProgress: function (e) {
            console.log('onProgress', e);
        },
        onComplete: function (e) {
            console.log('onComplete', JSON.parse(e));
        }
    });
    uploader.upload();
};

我有一个示例项目,其中包含一些代码(减去上传脚本):

https://github.com/kmturley/cordova-files

【问题讨论】:

  • 您可以在上传视频时查看您的控制台并向我们提供您收到的信息吗?应该有某种response 可以记录的信息,这些信息可以让我们更好地了解正在发生的事情。另外,在fileEntry.file 中,尝试console.log 使用file 参数,看看你得到了什么信息。 Cordova 文件上传和文件系统导航可能很棘手。
  • 在设备上,控制台日志未输出完整信息。环顾四周,似乎最好的选择可能是使用 FileTransfer 插件而不是编写单独的脚本来执行此操作:forums.meteor.com/t/file-uploads-via-cordova/2779/2
  • 这是一个stackoverflow链接:stackoverflow.com/questions/29330360/…

标签: javascript file cordova video phonegap-plugins


【解决方案1】:

官方文件传输插件是deprecated,当我写这篇文章时,它是test script fails

这让我使用了纯 javascript 方法并且它确实有效

function uploadFile (localPath, fileName, remoteUrl, callback) {
  // loads local file with http GET request
  var xhrLocal = new XMLHttpRequest()
  xhrLocal.open('get', localPath)
  xhrLocal.responseType = 'blob'
  xhrLocal.onerror = () => {
    callback(Error('An error ocurred getting localpath on' + localPath))
  }
  xhrLocal.onload = () => {
    // when data is loaded creates a file reader to read data
    var fr = new FileReader()
    fr.onload = function (e) {
      // fetch the data and accept the blob
      console.log(e)
      fetch(e.target.result)
        .then(res => res.blob())
        .then((res) => {
          // now creates another http post request to upload the file
          var formData = new FormData()
          formData.append('imagefile', res, fileName)
          // post form data
          const xhrRemote = new XMLHttpRequest()
          xhrRemote.responseType = 'json'
          // log response
          xhrRemote.onerror = () => {
            callback(Error('An error ocurred uploading the file to ' + remoteUrl))
          }
          xhrRemote.onload = () => {
            if (typeof callback === 'function') {
              callback(null, 'File uploaded successful, ' + xhrRemote.response)
            }
          }

          // create and send the reqeust
          xhrRemote.open('POST', remoteUrl)
          xhrRemote.send(formData)
        })
    }
    fr.readAsDataURL(xhrLocal.response) // async call
  }
  xhrLocal.send()
}

现在就这样称呼它

uploadFile('file:///storage/emulated/0/Android/data/myfile.jpg',
  'myfile.jpg',
  'https://example.com/upload_url',
  (err, res) => {
    if (err) {
      console.error(err)
    } else {
      console.log(res)
    }
  })

【讨论】:

    【解决方案2】:

    这里是另一个可行的解决方案。我现在进行了测试,它确实有效。你需要标准的cordova-plugin-file

    function uploadFileToServer (fileUri, fileName, remoteUrl, callback) {
      window.resolveLocalFileSystemURL(fileUri, function (fileEntry) {
        fileEntry.file(function (file) {
          var reader = new FileReader()
          reader.onloadend = function () {
            var blob = new Blob([new Uint8Array(this.result)], { type: 'application/octet-stream' })
            var fd = new FormData()
    
            fd.append('file', blob, fileName)
    
            var xhr = new XMLHttpRequest()
            xhr.open('POST', remoteUrl, true)
            xhr.onload = function () {
              if (xhr.status === 200) {
                if (typeof callback === 'function') { callback() }
              } else {
                if (typeof callback === 'function') { callback(xhr.status) }
              }
            }
            xhr.onerror = function (err) {
              if (typeof callback === 'function') { callback(err) }
            }
            xhr.send(fd)
          }
          reader.readAsArrayBuffer(file)
        }, function (err) {
          if (typeof callback === 'function') { callback(err) }
        })
      })
    }
    
    

    你叫它:

    uploadFileToServer('file:///storage/emulated/0/Android/data/myfile.jpg',
      'myfile.jpg',
      'https://example.com/upload_url',
      (err) => {
        if (err) {
          console.error('Error uploading file', err)
        } else {
          console.log('Upload done it with success')
        }
      })
    

    【讨论】:

      【解决方案3】:

      所以要上传我实现的文件:

      我现在用于本地文件的代码用于上传文件并设置正确的元数据:

      function uploadVideo(fileURL) {
          var options = new FileUploadOptions();
          options.fileKey = 'file';
          options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
          options.mimeType = 'video/mpg';
          options.chunkedMode = false;
          options.headers = {
              Authorization: 'Bearer ' + accessToken
          };
          options.params = {
              "": {
                  snippet: {
                      title: 'Video title',
                      description: 'Video description',
                      tags: 'Video tags',
                      categoryId: 22
                  },
                  status: {
                      privacyStatus: 'unlisted'
                  }
              }
          };
          var ft = new FileTransfer();
          ft.upload(fileURL, 'https://www.googleapis.com/upload/youtube/v3/videos?part=snippet,status', function (data) {
              console.log('upload success', data);
          }, function (e) {
              console.log('upload error', e);
          }, options, true);
          ft.onprogress = function (progressEvent) {
              console.log('onprogress: ' + ((progressEvent.loaded / progressEvent.total) * 100) + '%');
          };
      }
      

      我还必须修改插件以允许使用单个请求将元数据传递到 YouTube:

      文件传输.java 第 374 - 376 行

      beforeData.append("Content-Disposition: form-data; name=\"").append(key.toString()).append("\";");
      beforeData.append(" filename=\"").append("file.json").append('"').append(LINE_END);
      beforeData.append("Content-Type: ").append("application/json").append(LINE_END).append(LINE_END);
      

      如果您确实修改了插件,请记住 cordova 缓存此代码。我使用这个命令来强制它更新插件:

      cordova platform remove android; cordova platform add android;
      

      【讨论】:

      • 显然该插件已被弃用
      猜你喜欢
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      相关资源
      最近更新 更多