thibauts / node-castv2-client Goto Github PK
View Code? Open in Web Editor NEWA Chromecast client based on the new (CASTV2) protocol
License: MIT License
A Chromecast client based on the new (CASTV2) protocol
License: MIT License
Hello,
Has anyone tested node-castv2-client on chromecast 2?
I received this error logs from Stremio users with Chromecast 2. They say it can be re-produced on a regular basis, meanwhile the original Chromecast is working with the app fine.
Error: Load failed(…)
Uncaught TypeError: Cannot read property 'mediaSessionId' of null
Uncaught Error: Illegal wire type for field Message.Field
.extensions.api.cast_channel.CastMessage.payload_type: 5 (0 expected)
Uncaught Error: Illegal wire type for unknown field 13 in Message
.extensions.api.cast_channel.CastMessage#decode: 7
Uncaught Error: Illegal number of bytes for Message.Field
.extensions.api.cast_channel.CastMessage.payload_binary: 99 required but
got only 96
Uncaught Error: Illegal wire type for unknown field 13 in Message
.extensions.api.cast_channel.CastMessage#decode: 7
castplayer Error: Device timeout(…)
This probably doesn't give enough information to directly go and debug the issue, but it may offer some guidelines.
Having issues with running two chromecasts on the same network. I want to stream two different videos to each screen. With only one connected, things work fine because it's discovered automatically and its status is sent and received without issue. With two devices, i get this error message:
node_modules/chromecast-js/node_modules/castv2-client/lib/controllers/receiver.js:50
callback(null, response.status.applications || []);
^
TypeError: Cannot read property 'applications' of undefined
It seems that the status comes back undefined because the two chromecasts are interfering with each other or something. Is there a way to launch a new device/browser and specify the IP address manually?
See https://nodesecurity.io/advisories/46
Caused by:
[email protected] > [email protected] > [email protected]
You need to use the latest version of debug, which pulls in ms
version 0.7.1 or greater.
Hi. First, great job. (Sorry my bad grammar)
After a long time PAUSE errors occurs in a session, for example, such as "Device timeout", "read ECONNRESET", "ECONREFUSSED". What is the logic to follow to a proper RESUME or STOP?
My Chromecast is no longer findable using this module... Has something changed that I need to update?
From yesterday on my Chromecast does no longer reply to any mDNS query. I have restarted it, plugged it off for a while, etc., but it is no longer discoverable this way.
The official Chromecast app and Youtube on Android still see it, the UPnP based DIAL Service is also still present and working.
Anybody else experiences this? Was there maybe some change within the device regarding discovery? My firmware version is 26653.
Status event is emitted with idleReason equal to "ERROR" but no "error" event is emitted on the client for a detailed error report.
This could be an issue with chromecast, but I don't know.
Is there a way to get a detailed error report of what is happening when playback stops due to an error?
Let me tell you about my use case: I have an HLS stream which works perfectly on the Apple stuff (iOS, airplay, QuickTime) but plays choppily on Chromecast for about 20-30 seconds before stopping playing with an error.
I am writing an application that monitors devices on the network and allows a person to setup default applications etc. One problem I am having is that when you launch an application and then say end the process, the chromecast app session ends.
Right now I have two differrent needs:
The first one works great for me doing the following:
function onConnect(service) {
var client = new PlatformSender();
client.connect(service.addresses[0], function() {
var receiver = client.receiver;
function syncApp(app) {
if(syncApp.launching || app.appId === syncAppId) return;
syncApp.launching = true;
console.log("Restoring %s to default app: %s...", app.name, syncAppId);
if(app.sessionId) {
receiver.stop(app.sessionId, function(err, apps) {
log(apps);
});
}
receiver.launch(syncAppId, function(err, response) {
syncApp.launching = false;
});
}
client.on("status", function(status) {
syncApp((status && status.applications && status.applications[0]) || {});
});
client.getStatus(function(err, status) {
if(!err) {
client.emit("status", status);
}
});
});
}
This will launch the app and keep it launched no matter what. If the process that executed the above code were to exit the app stays on the chromecast just fine and if the process then comes back up it recovers just fine and doesn't force the running app to relaunch.
The second need requires me to have established a custom namespaced channel for sending requests to the ALREADY LAUNCHED app. For this I basically cloned the Youtube custom sender project and am using a different namespace.
The problem is that for one, when doing client.launch(App, cb)
it "closes" the ALREADY LAUNCHED app and re-launches it. The second issue is that if I ONLY use the app then when the process exits it also causes the app the close on the Chromecast:
function onConnect(service) {
var client = new PlatformSender();
client.connect(service.addresses[0], function() {
function syncApp(app) {
if(syncApp.launching || app.appId === syncAppId) {
return;
}
syncApp.launching = true;
console.log("Restoring %s to default app: %s...", app.name, syncAppId);
if(app.sessionId) {
receiver.stop(app.sessionId, function(err, apps) {
log(apps);
});
}
client.launch(PipecastApp, function(err, pio) {
log('app launched');
syncApp.launching = false;
pio.request(...)
});
}
client.on("status", function(status) {
syncApp((status && status.applications && status.applications[0]) || {});
});
client.getStatus(function(err, status) {
if(!err) {
client.emit("status", status);
}
});
});
}
Again, the above works so long as I am maintaining the process but as soon as it exits the app on the Chromecast also closes.
I need to figure out a way to either have an app join an existing session in a way that it won't auto close it later or I need to figure out why it's closing in the first place and get it to stop.
Any help would be greatly appreciated, thanks!
Hello,
Just testing the setVolume functionality as seen in this example script:
testing-castv2-client.js it doesn't seem to work, has it been tested before?
What's the best way to stop the current playing media and load something else?
The way I'm doing is keeping the player
object around and calling player.load(..)
with the new media when requested.
The problem is that sometimes I get this: [TypeError: Cannot call method 'send' of null]
Hi.
I'm trying to keep track of the position of the played media on the chrome cast but I can't seem to find the proper event to listen on and alternatively I can't see to find a way to extract the position of the media.
Help needed :)
I am trying to use this module with node-webkit, but after some debugging im stuck at the following error:
>> dyld: lazy symbol binding failed: Symbol not found: __ZN2v86String3NewEPKci
>> Referenced from: /Users/james/projects/deildu-time/dist/DeilduTime.app/Contents/Resources/app.nw/node_modules/castv2-client/node_modules/castv2/node_modules/protobuf/build/Release/protobuf_for_node.node
>> Expected in: dynamic lookup
>>
>> dyld: Symbol not found: __ZN2v86String3NewEPKci
>> Referenced from: /Users/james/projects/deildu-
>> time/dist/DeilduTime.app/Contents/Resources/app.nw/node_modules/castv2-client/node_modules/castv2/node_modules/protobuf/build/Release/protobuf_for_node.node
>> Expected in: dynamic lookup
>> Exited with code: 6.
After some research i am not quite able to find the cause of this, although i did find this module here https://github.com/fuwaneko/node-protobuf
which seems to be essentially the same except it builds on 32 bit platforms and is better maintained. I am going to continue researching this, but i haven't been able to solve this with chrisdew's version.
Can this play local files?
e.g. contentId: 'file:///Users/cameron/Video.mp4
As when I do that I get the error Load failed here:
player.load(media, { autoplay: true }, function(err, status) {
console.log('camstatus', err);
The exemple code crashes for me after a (supposed) dongle update. Preliminary tests with Google's own code seem to indicate it doesn't work either. I've been able to cast images, haven't tried with audio yet. I'll peer into this as soon as I have time and will happily get any feedback on the issue.
@jamiees2 have you noticed anything ? I will gladly take feedback if you happen to have the time to reproduce.
The app used by Chrome is "Chrome Mirroring", and has application ID 0F5096E8
.
The app is launched as usual and advertises protocols urn:x-cast:com.google.cast.webrtc
and urn:x-cast:com.google.cast.media
.
Once the app is launched, Chrome issues a CONNECT
message to the transportId with two additional fields :
origin
which value is {}
userAgent
which contains the browser UA stringThen an OFFER
is sent over the urn:x-cast:com.google.cast.webrtc
channel :
{
"type": "OFFER",
"seqNum": 22790009,
"offer": {
"supportedStreams": [
{
"index": 0,
"type": "audio_source",
"codecName": "opus",
"rtpProfile": "cast",
"rtpPayloadType": 127,
"ssrc": 306348,
"storeTime": 400,
"targetDelay": 400,
"aesKey": "e91d41098c89ffb1352e8f65aa760bd4",
"aesIvMask": "cabed613fdaf330a5576cc9ba0373e77",
"bitRate": 128000,
"sampleRate": 48000,
"timeBase": "1\/48000",
"channels": 2,
"receiverRtcpEventLog": true
},
{
"index": 1,
"type": "video_source",
"codecName": "vp8",
"rtpProfile": "cast",
"rtpPayloadType": 96,
"ssrc": 866107,
"storeTime": 400,
"targetDelay": 400,
"aesKey": "e91d41098c89ffb1352e8f65aa760bd4",
"aesIvMask": "cabed613fdaf330a5576cc9ba0373e77",
"maxFrameRate": "30000\/1000",
"timeBase": "1\/90000",
"maxBitRate": 5000,
"resolutions": [
{
"width": 1280,
"height": 720
}
],
"receiverRtcpEventLog": true
}
]
}
}
The Chromecast responds with an ANSWER
:
{
"answer": {
"sendIndexes": [ 0, 1 ],
"ssrcs": [ 306349, 866108 ],
"udpPort": 36916
},
"result": "ok",
"type": "ANSWER"
}
Chrome follows up with a PRESENTATION
message on urn:x-cast:com.google.cast.webrtc
(here I was browsing www.google.com) :
{
"sessionId": "D9322EE6-C345-4B9D-E6E5-0B7370F7FBAA",
"seqNum": 22790010,
"type": "PRESENTATION",
"title": "www.google.com (Tab)",
"icons": [
{
"url": "https:\/\/www.google.com\/favicon.ico"
}
]
}
And then sends a GET_STATUS
on the media channel which returns the playing state (PLAYING
) and a few other informations.
Then UDP traffic kicks in and the tab appears on the TV screen. I guess the OFFER/ANSWER cycle is somehow translated to its SDP counterpart but not knowing the WebRTC internals I cannot say much more.
Hi there,
Thanks for this great module! Using the sample provided in the README.md I have a working app streaming to one Chromecast Audio at a time. I also have these same devices in a Cast Group. I can find each device and the group:
found device "Living Room" at 192.168.1.111:8009
found device "Basement" at 192.168.1.139:8009
found device "All Speakers(1)" at 192.168.1.139:38143
(I have no idea why it's adding the (1)
to the end of my group. Separate question I guess.)
However, if I try to play to that group, it seems to almost work, and then it fails:
connected, launching app ...
app "Default Media Receiver" launched, loading media http://192.168.1.115:3000/All_Speakers(1).mp3 ...
[Error: Load failed]
Do you have any idea why it is failing to load? Is there something different I have to do on a group? Does the fact that it's using a different port have anything to do with it?
I have also confirmed that I never get an HTTP request to the media URL that it's trying to load. It looks like it never makes it that far. Any help you could offer would be great!
Thanks!
I tried the sample you specified with a http stream by peerflix. I got [Error: Load failed]
. The only thing i did was to replace the contentId with a valid peerflix link. I checked the link on a remote computer with VLC, and it worked. Any ideas why this could be happening?
Don't know if its already in here, but can we change for example the subs file (vtt) when we already have one subs file and one movie file streaming?
Hi,
May be a stupid question ? Can I cast HTML5 content from local ExpressJS to chromecast ?
I'm trying to control our Styled Media Receiver with your CASTV2 module for NodeJS. It has been very easy to implement so far. But right after I launch the receiver application the following error occurs:
Error: Illegal wire type for field Message.Field .extensions.api.cast_channel.CastMessage.payload_type: 5 (0 expected)
at Error (<anonymous>)
at ProtoBuf.Reflect.FieldPrototype.decode (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/node_modules/protobufjs/dist/ProtoBuf.js:3043:27)
at ProtoBuf.Reflect.MessagePrototype.decode (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/node_modules/protobufjs/dist/ProtoBuf.js:2462:49)
at Function.Message.decode (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/node_modules/protobufjs/dist/ProtoBuf.js:2190:41)
at Object.module.exports.(anonymous function).parse (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/lib/proto.js:22:34)
at PacketStreamWrapper.onpacket (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/lib/client.js:61:31)
at PacketStreamWrapper.EventEmitter.emit (events.js:95:17)
at CleartextStream.eval (/private/var/folders/jp/k4c47sy57b3chb9fv4wfg9xh0000gn/T/.org.chromium.Chromium.Zvgrtn/node_modules/castv2-client/node_modules/castv2/lib/packet-stream-wrapper.js:28:16)
at CleartextStream.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:408:10)
After that error message it goes on about some other errors about groupings.
This is the code I used:
var Chromecast = require('castv2-client').Client;
function connectChromecast(name, service) {
var client = new Chromecast();
client.connect(service.addresses[0], function() {
console.log('Connected to ' + name);
client.launch({
APP_ID: '[Our App ID]'
}, function(err, app) {
console.log(name + ' is ready to cast.');
});
});
}
Hi there, is it possible to provide the userAgent string sent over to the receiver? i.e. the one that ends up in onSenderConnected.
Right now it is the empty string.
Thanks!
Hi, I use this modul to write a little webapp tracking the state of my chromecast.
I noticed some problems when I turn of my TV so the chromecast shuts down, it seems the handling for this is a bit incomplete/incompatible to the actual implementation.
thats the changes I made in my app to make the shutdown happen without endless repeating errors from the still running heartbeat.
Flyingmana/home-media-center@cca450e
Iam very fresh to nodeJS, but I have the feeling you call some "close()" which are not implemented here https://github.com/thibauts/node-castv2-client/blob/master/lib/senders/platform.js#L41
Hi,
thanks for creating the client.
I'm trying to show an image for an hour or so.
Showing the image works, but I can't get the cast to stop. If I disconnect the client the cast continues (as expected ;-))
It seems like I need a player.unload()
(see "The second movie I try to play -- doesn't" at https://developers.google.com/cast/docs/player )
Any help would be appreciated.
Hans
Is there a way to have a multiple chromecast then plays the same video at the same time? Like having them group then send the message to that group.
Hi,
I'm trying to display the user friendly name of a chromecast, and I can't seem to figure out how to get it. Right now, I'm using MDNS to find the name, and I'm getting something like "Chromecast-Audio-9cd1691d91e3dd6a3b2edbe9b2f8aff4".
Any ideas on how to go about that? Thanks! (Sorry if I missed it!)
I have a raspberry pi that is capable of asserting/removing a 12v trigger signal connected to my home stereo equipment. In the past I have successfully had it monitoring my Sonos Connect device, allowing it to turn on the external amp when the Sonos begins playback, and turn off the external amp shortly after the Sonos stops playback.
I'm hoping to achieve the same thing with a Chromecast (being used exclusively for audio, via an HDMI->toslink separator). Basically, I need to have something running on the rpi that can detect when there's something running on the Chromecast, and when it's idle.
In a perfect world, it would be able to reliably sense whether the current app on the Chromecast -- receiver, if I understand correctly -- is actively playing music / making noise, but I'm not sure if there's a reliable and general way to do that.
Probably sufficient is to just detect whether anything is running on the Chromecast at all, or if it has reverted to its default state, and toggle the trigger signal then.
Does this sound like something that's possible to achieve at all with Chromecast? And, if so, am I looking in the right place? Most documentation of various projects seems (understandably) to be focused on writing a custom receiver and interacting with it, while I'm just trying to monitor the Chromecast / watch for broadcast messages about its state.
Thanks for any help or thoughts you have!
Using mafintosh/chromecasts on top of this module, I keep hitting a very serious issue:
When playing a video, then pausing for N minutes, or simply stopping, and then trying to play again, I get "cannot access .send of undefined", since the socket has been closed.
This is OK to some extent, because we have 'close' events which we can handle.
The weird thing is that 'error' never fires (where var client = new castv2.Client()
), not on client
, nor client.client
, nor on player
(where client.launch(castv2.DefaultMediaReceiver, function (err, player) { ... })
)
It does fire sometimes, a few minutes after the actual close
But how to handle the cases when the connection is closed? A simple reconnect on the same chromecast address does not work - with our without .launch
-ing DefaultMediaReceiver
. In both cases getStatus
keeps returning undefined
for status and null
as an error.
For whatever reason some state is kept somewhere. Or it requires the .play to be called again.
In any case, I haven't find a robust way to re-initiate the connection like nothing happened.
The heartbeat is working properly, but doesn't seem to be helping.
Thanks for your great library. I was able to successfully use it in my project.
Google has launched multi-cast support for audio devices. I tried to use chrome-cast but I did not manage to get it working.
I am able to connect and retrieve the client status but I do not know what to do next. I noticed that one device in the group becomes the MultizoneLeader while the others become MultizoneFollower:
{"applications":[{"appId":"MultizoneLeader","displayName":"Plex","sessionId":"92AE3423-8D88-4D97-BD6F-C94302C6E81F","statusText":"Plex"}],"volume":{"level":0.20000000298023224,"muted":false}}
{"applications":[{"appId":"MultizoneFollower","displayName":"Plex","namespaces":[{"name":"urn:x-cast:com.google.cast.media"}],"sessionId":"C80FDF67-4A60-42E9-B6A3-2A932D83D5F8","statusText":"Plex","transportId":"multizone-2"}],"volume":{"level":0.20000000298023224,"muted":false}}
The transportId is the same in all the followers but I do not know why this is not included in the MultizoneLeader.
I can join the sesion for the MultizoneFollower but I never get status updates. Trying to connect to the MultizoneLeader fails an uncaught exception error.
Using MDNS or SSDP does not return the name of the group, only the individual devices.
Any ideas or documentation sources? Did you have to reverse-engineer the protocol with Whitesark?
Hello again. Apologies for all the questions.
I've been trying to figure out how to update the title and image of currently playing media without reloading the media itself. (ie. no gaps in the audio/video). Does anyone have any ideas about how I might go about that? Things I've tried:
SET_METADATA
and METADATA
packets.LOAD
again.Any Ideas? Thanks so much!
Is there a way to show a fullscreen background image during the initial buffering?
Is there a way to unload the DefaultMediaReceiver when done playing media? As in return the chromecast to the picture slideshow instead of the blue icon. Thanks in advance!
Is it possible to add VTT text track support?
It is supported on the DefaultMediaReceiver
Love this library! I'm wondering if there's plan to support playing YouTube video. Thanks!
TODO
Hello guys, does anybody know or has any idea on how to set the volume up?
I'm seeing this in the logs when I have a long-running daemon that uses castv2-client:
(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
at HeartbeatController.addListener (events.js:160:15)
at HeartbeatController.once (events.js:185:8)
at HeartbeatController.ping (/srv/atlascast-server/node_modules/castv2-client/lib/controllers/heartbeat.js:38:8)
at oninterval (/srv/atlascast-server/node_modules/castv2-client/lib/controllers/heartbeat.js:60:10)
at wrapper [as _onTimeout] (timers.js:261:14)
at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)
Looking at the code for heartbeat.js
, I'm wondering if it should perhaps be aborting ping() calls if there's already one in progress?
Hi,
Occasionally, when I attempt to .close
a PlatformSender
, I get an error:
TypeError: Cannot read property 'close' of null
at PlatformSender.close (/Users/ariporad/dev/project/node_modules/castv2-client/lib/senders/platform.js:66:14)
at Object.die (/Users/ariporad/dev/project/Bridge.js:30:12)
at Browser.<anonymous> (/Users/ariporad/dev/project/castbridge.js:17:31)
at emitTwo (events.js:106:13)
at Browser.emit (events.js:191:7)
at Browser.on_service_changed (/Users/ariporad/dev/project/node_modules/mdns/lib/browser.js:79:14)
at SocketWatcher.MDNSService.self.watcher.callback (/Users/ariporad/dev/project/node_modules/mdns/lib/mdns_service.js:18:40)
I've traced this back to here. After some debugging, it would seem that platformSender.client
is null
, for some reason.
Any ideas on why this might be occurring? For now, I'm just checking if platformSender.client != null
before I close it.
Thanks!
How did you bypass the user interaction need to establish a session with chromecast? I am trying to understand how do this in my own chromecast sender.
Hello,
Many thanks for your library.
I'm using your example code for playing a video on my chromecast. It works very well.
I would like to know how to set repeat mode (REPEAT_ON / REPEAT_OFF) on video launch.
Can you help me please ?
Thanks
I get a few errors while running normally causing a crash.
I can reproduce every time if I power off the chromecast by unplugging it.
I am getting an error through the client on('error' event.
Any ideas as to if this is more likely me or the lib?
Any suggestions on how to handle this properly?
events.js:72
throw er; // Unhandled 'error' event
^
Error: Device timeout
at HeartbeatController.ontimeout (/home/bmiller/git/nwjs-cast/node_modules/castv2-client/lib/senders/platform.js:56:26)
at HeartbeatController.g (events.js:180:16)
at HeartbeatController.emit (events.js:92:17)
at ontimeout as _onTimeout
at Timer.listOnTimeout as ontimeout
I'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.
Not sure if this is the right place to post this question, but I'm having issues detecting when ChromeCasts join and leave the network.
I originally thought this was a problem with the mdns lib and the way it polled, so I filed an issue. The author of node_mdns helped me out and it looks like the ChromeCast device is the culprit:
Not sure if this is related, but after I start and stop my app a few times, I'll have to turn my wifi off and then on again to pick up serviceUps.
Sample App:
var mdns = require('mdns');
var browser = mdns.createBrowser(mdns.tcp('googlecast'));
browser.on('serviceUp', function(service){
console.log('chromecast detected -', service.name);
});
browser.on('serviceDown', function(service){
console.log('chromecast lost -', service.name);
});
browser.start();
Thanks for any help you can provide
Is it possible to cast static or dynamic html files instead video files with this Cast Client? (or maybe with any?)
TypeError: Cannot read property 'stop' of null
at Client.onclose (/node_modules/castv2-client/lib/senders/platform.js:42:21)
at Client.g (events.js:260:16)
at emitNone (events.js:72:20)
at Client.emit (events.js:166:7)
at TLSSocket.onclose (/node_modules/castv2-client/node_modules/castv2/lib/client.js:59:10)
at TLSSocket.g (events.js:260:16)
at emitOne (events.js:82:20)
at TLSSocket.emit (events.js:169:7)
at TCP._onclose (net.js:486:12)
Seems that the heartbeat isn't initialized
Greetings! Is it possible to work with multiple audio tracks of video stream (provided via URL)? Switch between them during video playback.
Will appreciate any help in this direction.
I can't seem to figure out how I could check the details of what is currently being casted, without first sending media to the tv. I'd like to be able to just get the name of the Program using the chromecasts and see it's volume level and seek position before trying to take over control.
Is that possible with this library?
Is there a way to cast a website like http://www.google.com/ ?
I have built a custom receiver that I use with the Google Cast Extension for Chrome.
But can I use this with this package? Your docs only mention the default receiver...
I'm trying to add Chromecast support to my Electron app and I stumbled upon a bug. What I do is I setup a temporary server when the user requests to cast and serve the audio they want (I know this part is fine because I setup the server and created a mini test file for Chrome with the regular Cast extension and it casted the audio fine). The problem is that when using node-castv2-client
, the audio never stops buffering. A little bit after the initial load request, I get a status update saying that the audio has been paused, but the Chromecast just keeps buffering. I even made sure to add audio/mpeg
as the contentType
, but nothing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.