Tl; Dr - Soru:
Video kontrollerinin çalışmaya devam etmesi için Node.js ile html5 video oynatıcıya bir video dosyası akışını işlemenin doğru yolu nedir ?
Bunun başlıkların işlenme şekliyle ilgisi olduğunu düşünüyorum . Her neyse, işte arka plan bilgileri. Kod biraz uzun, ancak oldukça basit.
Node ile küçük video dosyalarını HTML5 videoya aktarmak kolaydır
Küçük video dosyalarının bir HTML5 video oynatıcıya nasıl aktarılacağını çok kolay bir şekilde öğrendim. Bu kurulumla, kontroller benim tarafımdan herhangi bir işlem yapmadan çalışıyor ve video kusursuz bir şekilde yayınlanıyor. Google Dokümanlar'dan indirilmek üzere , tam olarak çalışan kodun örnek video ile çalışan bir kopyası buradadır .
Müşteri:
<html>
<title>Welcome</title>
<body>
<video controls>
<source src="movie.mp4" type="video/mp4"/>
<source src="movie.webm" type="video/webm"/>
<source src="movie.ogg" type="video/ogg"/>
<!-- fallback -->
Your browser does not support the <code>video</code> element.
</video>
</body>
</html>
Sunucu:
// Declare Vars & Read Files
var fs = require('fs'),
http = require('http'),
url = require('url'),
path = require('path');
var movie_webm, movie_mp4, movie_ogg;
// ... [snip] ... (Read index page)
fs.readFile(path.resolve(__dirname,"movie.mp4"), function (err, data) {
if (err) {
throw err;
}
movie_mp4 = data;
});
// ... [snip] ... (Read two other formats for the video)
// Serve & Stream Video
http.createServer(function (req, res) {
// ... [snip] ... (Serve client files)
var total;
if (reqResource == "/movie.mp4") {
total = movie_mp4.length;
}
// ... [snip] ... handle two other formats for the video
var range = req.headers.range;
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
if (reqResource == "/movie.mp4") {
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
res.end(movie_mp4.slice(start, end + 1), "binary");
}
// ... [snip] ... handle two other formats for the video
}).listen(8888);
Ancak bu yöntem boyutu 1 GB'tan küçük dosyalarla sınırlıdır.
Video dosyalarını (her boyutta) akışla fs.createReadStream
Bunu kullanarak fs.createReadStream()
, sunucu dosyayı bir seferde belleğe okumak yerine bir akışta okuyabilir. Bu, işleri yapmanın doğru yolu gibi görünüyor ve sözdizimi son derece basit:
Sunucu Snippet'i:
movieStream = fs.createReadStream(pathToFile);
movieStream.on('open', function () {
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
// This just pipes the read stream to the response object (which goes
//to the client)
movieStream.pipe(res);
});
movieStream.on('error', function (err) {
res.end(err);
});
Bu, videoyu gayet iyi yayınlar! Ancak video kontrolleri artık çalışmıyor.
writeHead()
kodu yorumda bıraktım , ancak yardımcı olur diye düşündüm . Kod parçacığını daha okunaklı hale getirmek için bunu kaldırmalı mıyım?