[英]Streaming music synchronously from a mp3 file via a nodejs server + socket.io
[英]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.