代码之家  ›  专栏  ›  技术社区  ›  Harshith Rai

NodeJs API在转换较大文件时发送空白响应

  •  0
  • Harshith Rai  · 技术社区  · 5 年前

    mp4 我的视频 localhost 到服务器上。最基本的是如果视频是 .mp4 .mp4 然后上传。我用的是视频转换器 handbrake-js

    .on(end) 回调,我在角度控制器中收到一些空白响应,甚至在转换完成之前。我注意到它发生在大约30%到40%的转化率。它有一个 readystate XMLHttpRequest.DONE 还有 status = 200

    try {
        if (fs.existsSync(uploadPath + filename.substring(0, filename.lastIndexOf('.')) + '.mp4')) {
            res.end('<b><i>' + filename + '</i></b> already exists in the directory.');
        }
        else {
            const fstream = fs.createWriteStream(path.join(cfg.tempStoragePath, filename));
            file.pipe(fstream);
            console.log("\nfile_type: " + file_type);
            filename = filename.substring(0, filename.lastIndexOf('.'));
    
            // On finish of the copying file to temp location
            fstream.on('close', () => {
                hbjs.spawn({
                    input: cfg.tempStoragePath + filename + '.' + file_type,
                    output: uploadPath + filename + '.mp4'
                })
                    .on('error', err => {
                        // invalid user input, no video found etc
                        console.log('error! No input video found at: \n: ' + cfg.tempStoragePath + filename + '.' + file_type);
                        res.send('Conversion of the file, <b><i>' + filename + '</i></b>, from <b>.' + file_type + '</b>' + ' to <b>.mp4</b> failed because no input video was found at: \n: ' + cfg.tempStoragePath + filename + '.' + file_type);
                    })
                    .on('progress', progress => {
                        progress_percent = (Number(progress.percentComplete) * 2 <= 100) ? Number(progress.percentComplete) * 2 : 100;
                        eta = progress.eta.split(/[a-zA-Z]/);
                        minutes = ((+eta[0]) * 60 + (+eta[1])) / 2;
                        console.log('Percent complete: %d, ETA: %d ///// %s ==> mp4', progress_percent, minutes, file_type);
                    })
                    .on('end', end => {
                        console.log('Conversion from .' + file_type + ' to .mp4 complete.');
                        //delete the temp file
                        fs.unlink(cfg.tempStoragePath + filename + '.' + file_type);
                        let new_path = uploadPath + filename + '.mp4';
                        let stat = fs.statSync(new_path);
                        console.log(`Upload of '${filename}' finished`);
                        if(Number(progress_percent) === Number(100))
                            res.send('The file, <b><i>' + filename + '</i></b>, has been converted from <b>.' + file_type + '</b>' + ' to <b>.mp4</b> complete.');
                        })
                    });
                }
        } 
    
        catch (err) {
            res.end(err);
        }
    

    以下是我的角度控制器的一部分:

    
    request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
            showConversionModal('<p>' + request.responseText + '</p>', 'done');
        }
    };
    showSomeModal('something');
    request.open("POST", client.clientHost + ":" + client.clientPort + "/uploadVideoService");
    formData = new FormData();
    formData.append("file", files[0], files[0].name);
    request.send(formData);
    
    

    注意 :所有正在执行的数据 console.log() 节点内部如预期。甚至 res.end/send 适用于占用较少时间的较小文件。但问题只出现在那些转换时间比小文件长的情况下。

    if handbrake 部分。但事实并非如此。

    在浏览器中,我得到一个错误:

    Failed to load resource: net::ERR_CONNECTION_RESET

    request.send(formData); 我也尝试过几乎所有的解决方案 this SO article ,效果不佳。不过,这种转变还是很顺利的。

    :还请注意,转换和上载即使对于较大的文件也没有问题,只是我在客户端收到的响应一直是我头疼的问题。

    更新: res.end() 如果 循环检查现有的文件场景,但由于某些奇怪的原因,角度控制器没有对其作出反应。这种情况只发生在较大的文件上。

    0 回复  |  直到 5 年前
        1
  •  0
  •   Harshith Rai    5 年前

    我自己想了很久。原来里面有个缓冲器 Busboy .

    busboy express 这样地:

    app.use(busboy());

    只需设置字段名为 highWaterMark 一个大于文件大小的任意大小就可以做到这一点。

    app.use(busboy({
        highWaterMark: 2048 * 1024 * 1024, // Set buffer size in MB
    }));
    

    我不知道是什么导致了这个问题,也不知道新领域是如何解决这个问题的,但是,我所知道的是,它只是起作用了。如果有人能详细说明一下这一点会有帮助的。