Git Product home page Git Product logo

node-castv2-client's People

Contributors

angelnu avatar guerrerocarlos avatar sfossen avatar strml avatar thibauts avatar xat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-castv2-client's Issues

Any testing with Chromecast 2?

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.

specific launching multiple chromecasts / specific IP address

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?

What is the logic to retrieve a closed session?

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?

  1. getSession -> joinSession -> (Play or Stop)
  2. Connect -> getSession -> joinSession -> (Play or Stop)
  3. Connect -> getSession -> joinSession -> launch -> (Play or Stop)
    some other?
    Grateful for some help.

mDNS no longer working?

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.

'error' never emitted even though 'status' is emitted with idleReason ERROR

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.

How to have an application join an existing session

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:

  1. Monitor devices and make sure each one is casting the right app
  2. Listen for commands from another location (http server) and forward them on to a device running the app.

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!

Change playing media

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]

Keeping track of media position

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 :)

Error when attempting to use the module in node-webkit

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.

Playing local files

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);

Can't play video with DefaultMediaReceiver app after dongle update

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.

Tab Mirroring over CASTV2

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 string

Then 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.

Error Streaming to Chromecast Audio Group

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!

Error when playing some HTTP streams without specifying a contentType

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?

Change subtitles on playing movie

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?

Cast HTML5 Content

Hi,
May be a stupid question ? Can I cast HTML5 content from local ExpressJS to chromecast ?

Error: Illegal wire type for field Message.Field

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.');   
        });
    });
}

Set the user-agent?

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!

broken Chromecast Shutdown handling

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

Stop casting

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

Multiple Chromecast and One Sender

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.

How to get Chromecast display name?

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!)

Monitor chromecast for media playback (from any receiver?)

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!

handling timeout properly

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.

Audio multicast

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?

Update Metadata

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:

  1. Issuing SET_METADATA and METADATA packets.
  2. Calling LOAD again.
  3. Switching between metadata tracks. (I think I was close with this one, but I couldn't get it working.)

Any Ideas? Thanks so much!

Background Image

Is there a way to show a fullscreen background image during the initial buffering?

Unloading DefaultMediaReceiver

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!

Play YouTube video

Love this library! I'm wondering if there's plan to support playing YouTube video. Thanks!

volume control

Hello guys, does anybody know or has any idea on how to set the volume up?

Leaky heartbeat logic

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?

Cannot read property 'close' of null

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!

Bypass the user interaction need

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.

Set REPEAT_ON on DefaultMediaReceiver

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

Unhandled timeout error

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

Refresh Image Without Blanking Screen

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.

Detecting ChromeCast Connect and Disconnect Events

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:

  • The first time the app starts, I receive a single serviceUp event for each ChromeCast on the network.
  • If i unplug a ChromeCast, no serviceDown event is sent.
  • If I add new ChromeCasts to the network after the app is started, I get no new serviceUp event.

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

Web Pages

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

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

Multiple audio tracks for video stream?

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.

Monitoring a cast without taking over it.

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?

Implementing a Custom Receiver

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...

Audio never loads

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.