将电影从电子内部的 angularJS SPA 上传到 cloudinary

Posted

技术标签:

【中文标题】将电影从电子内部的 angularJS SPA 上传到 cloudinary【英文标题】:Upload movie to cloudinary from angularJS SPA inside electron 【发布时间】:2019-01-05 15:44:54 【问题描述】:

我想从电子应用程序的前端将文件从用户光盘上传到云端,这是 angularJS SPA。

我已经通过从 input[file] 选择照片从 angularJS 上传照片,但这次我想通过用户光盘上文件的绝对路径上传电影。

由于我使用 electron,我可以在前端层中使用 nodeJS 包作为 path,因此我将使用它来定义 .webm 文件的路径,因为它位于应用程序的根目录中。

$scope.uploadVideo = function () 

    var filePath = __dirname + '\\videos\\example.webm';
    console.log(filePath);

    $upload.upload(
        url: "https://api.cloudinary.com/v1_1/" + cloudinary.config().cloud_name + "/upload",
        data: 
            upload_preset: cloudinary.config().upload_preset,
            file: filePath
        
    )
    .progress(function (info) 
        console.log(info);
    )
    .then(function (res) 
        console.log(res);
    );
;

filePath 是:

C:\Users\Admin\Documents\ngb\desktopApp\videos\example.webm

这是正确的文件路径。但是上面的代码不起作用并给出这个错误:

可能未处理的拒绝:"data":"error":"message":"Unsupported source URL: C:\Users\Admin\Documents\ngb\desktopApp\videos\example.webm"," status":400,"config":"method":"POST","transformRequest":[null],"transformResponse":

我认为我无法通过文件的绝对路径从前端发送到云端电影,但我希望我错了。我也可以对电子的nodeJS端做同样的事情(实际上我尝试过并且它正在工作)但是在nodeJS中我没有这个.progress回调,它显示有关上传进度的当前信息,这有助于在前面创建一些进度条以显示还剩多长时间.

问题是是否可以通过 angularJS 使用文件路径将其发送到 cloudinary,如果不能,如何通过 nodeJS 获得上传进度。 编辑我为第二个问题创建了separate question。 Edit2 经过更多谷歌搜索后,我发现来自 cloudinary 合作者的 information on github 无法在服务器端上传进度,因此我在上面的链接中回答了我自己的问题。


编辑 由于错误是说他们不支持这样的路径,我放弃了在 API 调用中提供文件路径的想法。相反,我想将我的视频文件编码为 base64 格式,然后将其传递给 cloudinary,因为他们说here 有可能:

$scope.uploadVideo = function () 

    var filePath = __dirname + '\\videos\\example.webm';
    var buff = Buffer.from(filePath).toString('base64');
    console.log(filePath);
    console.log(buff);

    $upload.upload(
        url: "https://api.cloudinary.com/v1_1/" + cloudinary.config().cloud_name + "/upload",
        data: 
            upload_preset: cloudinary.config().upload_preset,
            file: 'base64,' + buff
        
    )
    .progress(function (info) 
        console.log(info);
    )
    .then(function (res) 
        console.log(res);
    );
;

但它仍然不起作用..它控制台日志

C:\Users\Admin\Documents\ngb\desktopApp\videos\example.webm

QzpcVXNlcnNcQm9yeXNcRG9jdW1lbnRzXGlndFxkZXNrdG9wQXBwXHZpZGVvc1xleGFtcGxlLndlYm0=

并且错误仍然相同:

可能未处理的拒绝:"data":"error":"message":"不支持的源 URL:base64,QzpcVXNlcnNcQm9yeXNcRG9jdW1lbnRzXGlndFxkZXNrdG9wQXBwXHZpZGVvc1xleGFtcGxlLndlYm0=","status":400,"config":"method "发布","

【问题讨论】:

【参考方案1】:

URI 需要包含实际的文件内容,而不仅仅是路径。比如使用formdata-

(function() 
    var f = document.getElementById('f');

    if (f.files.length)
        processFile();

    f.addEventListener('change', processFile, false);

    function processFile(e) 

        var f = document.getElementById('f');
        var file = f.files[0];

        console.log(file);
        var formdata = new FormData();

        formdata.append('file', file);
        //formdata.append('cloud_name', '<cloud_name>');
        formdata.append('upload_preset', '<upload_preset>');

        var xhr = new XMLHttpRequest();
        xhr.open('POST', "https://api.cloudinary.com/v1_1/<cloud_name>/upload",true);

        xhr.onload = function () 
            // do something to response
            console.log(this.responseText);
        ;

        xhr.send(formdata);
    
)();

【讨论】:

【参考方案2】:

@rcstraus 正确指出我没有转换为 base64 文件,而只是转换为文件路径的字符串。

除了我的file: data 不正确,我应该有file: 'data:video/webm;base64,' + buff,其中buff 是base64 中的文件而不是路径。

而工作代码是:

$scope.uploadVideo = function () 
    $scope.selected.state = $scope.state[3];

    fs.readFile('./videos/example.webm', (err, data) => 
        if(err) alert(err);
        var buff = Buffer.from(data).toString('base64');
        $upload.upload(
            url: "https://api.cloudinary.com/v1_1/" + cloudinary.config().cloud_name + "/upload",
            data: 
                upload_preset: cloudinary.config().upload_preset,
                //tags: 'myphotoalbum',
                //context: 'photo=' + $scope.title,
                file: 'data:video/webm;base64,' + buff
            
        )
        .progress(function (info) 
            //file.progress = Math.round((e.loaded * 100.0) / info.total);
            //file.status = "Uploading... " + file.progress + "%"
            console.log(info);
        )
        .then(function (res) 
            console.log(res);
        );
    );

;

它结合了node和angularJS和ng-file-upload包,电子让它工作。

【讨论】:

以上是关于将电影从电子内部的 angularJS SPA 上传到 cloudinary的主要内容,如果未能解决你的问题,请参考以下文章

在 angularjs SPA 中使用 Knockout 组件

如何使我在 VS 2015 Web 开发环境上运行的 AngularJS SPA 正确刷新

AngularJS SPA 使用 API 和 Mongoose

AngularJs

使用 AngularJS HTML 映射两个集合(内部连接)

在2019年,将网站从Angularjs迁移到另一个框架需要多少钱?