簡體   English   中英

使用nodejs和socket.IO流式傳輸mp4視頻

[英]streaming mp4 video using nodejs and socket.IO

我正在開發一個在線課程應用程序。 用戶注冊課程后,該用戶可以轉到課程首頁,然后單擊任何視頻講座進行查看。 要流式播放.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);
    });
});

但是,當我嘗試從瀏覽器訪問它時,在瀏覽器中出現錯誤,顯示為“ Range not Satisfiable”。 我正在使用google chrome和mozilla firefox進行測試。

范圍不滿意

我正在記錄req.headers.range,我得到它的值為'undefined'。 這里是。 范圍的不確定值。

當我們通過瀏覽器訪問它時,這是請求和響應頭。 您會注意到,GET請求中沒有“ Range”標頭。

請求和響應頭

請讓我知道,這里出了什么問題。 因為,如果我運行與獨立應用程序相同的代碼,那么它將起作用。

您可能已經知道,由於未定義范圍值,因此直接從您的代碼生成錯誤消息-這些行將其發送回去:

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)

到目前為止,我已經實現了一個非常幼稚的解決方案,我肯定會對此加以改進。 所以這是我的代碼,絕對需要對其進行優化。 任何第三方npm模塊也將對我有所幫助。

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

var filePath = path.join(__dirname, 'movie.mp4');
var stat = fs.statSync(filePath);

res.writeHead(200, {
    'Content-Type': 'audio/mpeg',
    'Content-Length': stat.size
});

var readStream = fs.createReadStream(filePath);
// We replaced all the event handlers with a simple call to util.pump()
util.pump(readStream, res);

});

請讓我知道,我如何優化此解決方案或以前的代碼以使其工作。 甚至任何第三方npm模塊也將為我提供幫助。 謝謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM