Refresh Image Without Blanking Screen
See original GitHub issueI’m trying to cast a webpage that displays stats from a headless box to my Chromecast using Node.js. My current implementation involves using PhantomJS in an external process to render the webpage to an image and then cast that image to the Chromecast using node-castv2-client, and then repeat that in an interval. Here is my code as it stands:
/*
* Written by Turing Eret
* Based on code example by Thibaut Séguy from
* https://github.com/thibauts/node-castv2-client/blob/master/README.md
*/
var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
var mdns = require('mdns');
var http = require('http');
var internalIp = require('internal-ip');
var router = require('router');
var path = require('path');
var fs = require('fs');
var mime = require('mime');
var finalhandler = require('finalhandler');
var port = 8800;
var prefixPath = startServer();
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
browser.on('serviceUp', function(service) {
console.log('found device "%s" at %s:%d', service.name, service.addresses[0], service.port);
if(service.name == process.argv[2]) {
onDeviceFound(service.addresses[0]);
}
browser.stop();
});
browser.start();
function onDeviceFound(host) {
var client = new Client();
var statsFile = 'stats.png';
var statsImagePath = prefixPath + statsFile;
client.connect(host, function() {
console.log('connected, launching app ...');
client.launch(DefaultMediaReceiver, function(err, player) {
var media = {
contentId: statsImagePath,
contentType: 'image/png'
};
player.on('status', function(status) {
console.log('status broadcast playerState=%s', status.playerState);
});
console.log('app "%s" launched, loading media %s ...', player.session.displayName, media.contentId);
var loadStats = function() {
// renderStats('stats.png'); //Will eventually reload and rerender the page.
player.load(media, { autoplay: true }, function(err, status) {
console.log('media loaded playerState=%s', status.playerState);
});
}
loadStats();
setInterval(function() {
console.log('Executing interval function.');
loadStats();
}, 5000); //Set to 5 seconds for debug purposes.
});
});
client.on('error', function(err) {
console.log('Error: %s', err.message);
client.close();
});
}
function startServer() {
var route = router();
var ip = internalIp();
var prefix = 'http://' + ip + ':' + port + '/';
route.all('/:path', function(req, res) {
serveFile(req, res, req.params.path, prefix);
});
http.createServer(function(req, res) {
route(req, res, finalhandler(req, res))
}).listen(port)
console.log('Started simple webserver at %s', prefix);
return prefix;
}
function serveFile(req, res, filePath, prefix) {
console.log('Serving file: %s', filePath)
var stat = fs.statSync(filePath);
var total = stat.size;
var range = req.headers.range;
var type = mime.lookup(filePath);
res.setHeader('Content-Type', type);
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Refresh', '5;url=' + prefix + filePath);
if (!range) {
res.setHeader('Content-Length', total);
res.statusCode = 200;
return fs.createReadStream(filePath).pipe(res);
}
var part = rangeParser(total, range)[0];
var chunksize = (part.end - part.start) + 1;
var file = fs.createReadStream(filePath, {start: part.start, end: part.end});
res.setHeader('Content-Range', 'bytes ' + part.start + '-' + part.end + '/' + total);
res.setHeader('Accept-Ranges', 'bytes');
res.setHeader('Content-Length', chunksize);
res.statusCode = 206;
return file.pipe(res);
};
Now, this code has two issues. First off, whenever the interval hits, the Chromecast redisplays the image, but the screen blanks out before doing so. Ideally, it wouldn’t blank out like that. Second, when the Chromecast redraws the designated image, I can see that it is not being reloaded from the webserver, which means that even if the image changes, nothing will change on screen. How do I fix this? Thanks.
Issue Analytics
- State:
- Created 8 years ago
- Comments:19 (17 by maintainers)
Here is my complete code of the test application I’ve created. I already know my chromecast host, so I set it to connect it directly.
Code for loadQueue on Media Controller
Code for Default-Media-Receiver for loadQueue
Closing for inactivity.