【问题标题】:Node JS Request + Express PipeNode JS 请求 + 快速管道
【发布时间】:2015-06-29 17:05:51
【问题描述】:

我在将视频文件从一个服务器流式传输到另一个服务器时遇到问题。

我写了这个脚本

var request = require("request"),
    express = require("express");

var app = express();

app.get("/cast", function(req, res) {

    var url = req.query.video;

    res.writeHead(200, {
        'Content-Type': 'video/mp4'
    });

    request({
        url: url,
        headers: {
            Referer: "http://example.com/1706398/" + url
        }
    })
        .on('response', function(response) {

            response.on('data', function(data) {
                console.log("data chunk received: " + data.length)
            });

            response.on('end', function(data) {
                console.log('Video completed');
            });

        })
        .pipe(res);

});

app.listen(8080);

但视频响应有时有效,有时会损坏,相反,如果请求的数据被写入可写缓冲区并保存为视频文件,则它适用于任何 url。 我在我的代码中找不到任何错误或问题,这里有一些网址:

这是我尝试过的一些网址: https://gist.github.com/FrancisCan/f2bb86f8ff73b45fa192

谢谢:)

【问题讨论】:

标签: node.js express request pipe


【解决方案1】:

移除 writeHead 200,当您进行流式传输时,您应该返回 http 206 结果(部分内容),而不是 http200。我有和你一样的场景(将视频文件从云中的 blob 容器流式传输到 Angular 应用程序),不需要 http200 响应。

更新:添加一些关于我如何做的代码:

AzureStorageHelper.prototype.streamBlob = function streamBlob(req, res, blob, params) {
    if(!params){
        params.container = container;
    }
    blob_service.getBlobProperties(params.container, blob, function (error, result, response) {
        if(!result) return res.status(404).end();
        if(error) return res.status(500).end();

        var blobLength = result.contentLength;
        var range = req.headers.range ? req.headers.range : "bytes=0-";
        var positions = range.replace(/bytes=/, "").split("-");
        var start = parseInt(positions[0], 10);
        var end = positions[1] ? parseInt(positions[1], 10) : blobLength - 1;
        var chunksize = (end - start) + 1;
        var options = {
            rangeStart: start,
            rangeEnd: end,
        }

        //this is what's interesting for your scenario. I used to set this up myself but it's is now handled by the Azure Storage NodejsSDK

        /*res.writeHead(206, {
            'Accept-Ranges': 'bytes',
            'Content-Range': "bytes " + start + "-" + end + "/" + blobLength,
            'Content-Type': result.contentType,
            'Content-Length': chunksize,
            'Content-MD5': result.contentMD5,
        });*/

        var options = {
            rangeStart: start,
            rangeEnd: end,
        }

//this is an API from the Azure Storage nodejsSDK I use. You might want to check the source of this method in github to see how this lib deals with the http206 responses and the piping
        blob_service.getBlobToStream(params.container, blob, res, options, function (error, result, response) {
            if (error) {
                return res.status(500).end();
            }
        });
    });

【讨论】:

  • 完成,但问题仍然存在。即使文件存在并且通过请求下载的文件可以正常播放,流式传输也会显示“文件已损坏”
  • 好的,我已经用上面的答案更新了我使用的代码。检查这是否能让你解决你的问题。本质上,客户端在流式传输期间要求特定的字节范围,我将其作为请求选项的一部分转发到服务器。过去,我自己处理响应(代码注释掉),但现在由我正在使用的库处理。
  • 谢谢!我找不到它在哪里发送 res 代码 206,所以我试图手动执行此操作,但较新的 azure-storage 库似乎已经为我解决了这个问题。同样有趣的是,如果您的代码未设置为流式传输,而只是下载文件,它仍会在 chrome、firefox 中播放文件。但是它不允许在 iOS 中这样做。
猜你喜欢
  • 2019-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 2021-08-12
相关资源
最近更新 更多