使用nodejs和socket.IO传输mp4视频

时间:2016-11-16 03:46:55

标签: node.js video socket.io video-streaming webrtc

我正在开发一个在线课程申请表。一旦用户注册了课程,那么该用户当然可以转到主页,然后单击任何视频讲座来查看它。 要流式传输.mp4格式的视频,我使用的是socket.io。 这就是我现在正在做的事情。

router.get('/learn/:courseName/lecture/:video', isAuthenticated, function (req, res) {

    // var file = path.resolve(__dirname,"movie.mp4");

    console.log('courseName is: ' + req.params.courseName);
    console.log('video name is: ' + req.params.video);

    var file = "/home/mobileedx/WebstormProjects/passportAuthentication/videoLecture/movie.mp4";
    console.log('file is: ' + file);
    fs.stat(file, function(err, stats) {
        if (err) {
            if (err.code === 'ENOENT') {
                // 404 Error if file not found
                return res.sendStatus(404);
            }
            res.end(err);
        }

        var range = req.headers.range;
        console.log('value of range is: ' + range);
        if(!range) {
            return res.sendStatus(416);
        }

        var positions = range.replace(/bytes=/, "").split("-");
        var start = parseInt(positions[0], 10);
        var total = stats.size;
        var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
        var chunksize = (end - start) + 1;

        res.writeHead(206, {
            "Content-Range": "bytes " + start + "-" + end + "/" + total,
            "Accept-Ranges": "bytes",
            "Content-Length": chunksize,
            "Content-Type": "video/mp4"
        });

        var stream = fs.createReadStream(file, { start: start, end: end   })
            .on("open", function() {
                stream.pipe(res);
            }).on("error", function(err) {
                res.end(err);
            });
        console.log('stream value is: ' + stream);
    });
});

但是,当我尝试从浏览器访问它时,我在浏览器中收到错误,因为"范围不满意"。我正在使用谷歌浏览器和Mozilla Firefox进行测试。

range not Satisfiable

我记录了req.headers.range,并将其值设为' undefined'。 这里是。 undefined value for range.

当我们通过浏览器访问它时,这是请求和响应标头。你可以注意到,没有'范围' GET请求中的标头。

Request and Response header

请告诉我,这里出了什么问题。因为,如果我运行与独立应用程序相同的代码,那么它可以工作。

2 个答案:

答案 0 :(得分:0)

正如您可能知道的那样,您正在从代码直接生成错误消息,因为未定义范围值 - 这些行将其发回:

var range = req.headers.range;
        console.log('value of range is: ' + range);
        if(!range) {
            return res.sendStatus(416);
        }

416错误将生成您显示的消息。

我认为问题在于您的代码假设在没有范围请求的情况下接收HTTP请求是错误的,但这实际上是一个可选参数:

  

使用条件或无条件GET方法的HTTP检索请求可以使用Range请求标头(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2

请求实体的一个或多个子范围,而不是整个实体

浏览器第一次请求没有任何范围值的正常情况。当服务器响应以指示它接受范围请求时,浏览器将发送另一个包含范围的请求。

此答案中有一个非常有用的流程示例:https://stackoverflow.com/a/8507991/334402

如果您想为此使用Express静态服务功能,因为它支持范围,那么这里有详细记录:https://github.com/expressjs/serve-static

以上链接中的示例代码:

var finalhandler = require('finalhandler')
var http = require('http')
var serveStatic = require('serve-static')

// Serve up public/ftp folder
var serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})

// Create server
var server = http.createServer(function onRequest (req, res) {
  serve(req, res, finalhandler(req, res))
})

// Listen
server.listen(3000)

<强>更新

这是一个非常简单的node.js视频服务器。

您只需要在与app.js相同的文件夹中创建一个视频目录,然后将视频放在那里。

如果您的视频名为BigBuckBunny.mp4,则可以通过网址http://localhost:3000/BigBuckBunny.mp4

访问该视频
var express = require('express')
var serveStatic = require('serve-static')

var app = express()

app.use(serveStatic(__dirname + '/videos'))

app.listen(3000)

答案 1 :(得分:0)

截至目前,我已经实施了一个非常天真的解决方案,我当然希望改进。所以这是我的代码,肯定需要优化。任何第三方npm模块也会帮助我。

NSTimeInterval

请让我知道,我如何优化此解决方案或我以前的代码才能工作。即使任何第三方npm模块也会帮助我。 感谢。