{"id":13583795,"url":"https://github.com/superhawk610/multicast","last_synced_at":"2025-04-06T23:18:19.223Z","repository":{"id":48842325,"uuid":"105903541","full_name":"superhawk610/multicast","owner":"superhawk610","description":":green_heart: A persistent solution to presenting content across multiple Chromecast devices.","archived":false,"fork":false,"pushed_at":"2022-12-07T08:36:00.000Z","size":3664,"stargazers_count":219,"open_issues_count":23,"forks_count":25,"subscribers_count":19,"default_branch":"v2.x","last_synced_at":"2025-03-30T19:11:04.930Z","etag":null,"topics":["chromecast-device","mdns","multicast","node","receiver"],"latest_commit_sha":null,"homepage":"https://superhawk610.github.io/multicast-site/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/superhawk610.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-05T14:58:27.000Z","updated_at":"2025-02-20T08:51:27.000Z","dependencies_parsed_at":"2023-01-24T15:31:00.906Z","dependency_job_id":null,"html_url":"https://github.com/superhawk610/multicast","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superhawk610%2Fmulticast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superhawk610%2Fmulticast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superhawk610%2Fmulticast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superhawk610%2Fmulticast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/superhawk610","download_url":"https://codeload.github.com/superhawk610/multicast/tar.gz/refs/heads/v2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247563942,"owners_count":20958971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chromecast-device","mdns","multicast","node","receiver"],"created_at":"2024-08-01T15:03:48.375Z","updated_at":"2025-04-06T23:18:19.196Z","avatar_url":"https://github.com/superhawk610.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# MultiCast v2.0\n\n[![npm version](https://badge.fury.io/js/multicast.svg)](https://badge.fury.io/js/multicast)\n\n:green_heart: A persistent solution to presenting content across multiple Chromecast devices, inspired by [Greenscreen](http://greenscreen.io/).\n\nDeveloped with Node, Express, and Mongo.\n\n## Usage\n\n### Home\n\n![home](screens/home.png)\n\nFrom the home page, you can manage displays via Chromecasts, manage all available content via Channels, create and trigger alerts via Push Alerts, or takeover all display by starting a Takeover.\n\n### Channels\n\n![channels](screens/channels.png)\n\nAll content is managed via Channels, which are unique URLs that can be assigned to each individual device. There is no limit on the number of Channels you can have available at any one time, and you can freely switch between them on a per-device basis.\n\nTo access Channels, select Channels from the homepage, or click Channels in the top right of the interface.\n\n![channel](screens/channel.png)\n\nA channel consists of a Name and Layout. The channel's name will be used to refer to it throughout the interface, but will never be displayed on the actual device when it is being cast. The channel's layout allows one or more URLs to be embedded (via iframe) into the page that will be cast. Two layouts are provided, though creating additional layouts is not especially difficult (see [Creating Layouts](#creating-layouts)).\n\n### Devices\n\n![devices](screens/devices.png)\n\nChromecast devices are now interfaced with as mDNS devices via the new [Castv2 API](https://github.com/thibauts/node-castv2). This removes the Chrome/Chromium browser restriction that previously existed with Chromecast devices, and even allows Multicast to be run remotely from a headless server (see [Setup](#setup)).\n\nAll Chromecast devices on the same network as the host will display here. Devices can be _registered_ to be activated as Multicast receivers and assigned a channel, receive push alerts, and so on.\n\nTo register a device, click on the device's name or click Register Chromecast.\n\n![register](screens/register.png)\n\nA device's name will be whatever the Chromecast's name was when it was set up. A device's Location can be set to anything you would like to clarify where it is located. Make sure to choose something descriptive, as this will make Channel management easier down the line.\n\nYou can choose not to select a Channel when registering a device - doing so will leave the device on the default registration screen until a Channel is selected.\n\n![device](screens/device.png)\n\nOnce a device has been registered, you can select its name from the Devices list to change the Channel it is displaying, refresh its Channel content, or Reconnect it if loses connection.\n\n### Push Alerts\n\n![push](screens/push.png)\n\nPush Alerts are useful for displaying small pieces of information to all receiver devices. Alerts will begin displaying on all connected receivers as soon as they are created, and will continue to display until their set duration is reached or the receiver is reset.\n\n### Channel Takeover\n\n![takeover](screens/takeover.png)\n\nA Channel Takeover allows all receiver devices to be temporarily, indefinitely redirected to a single channel. A Takeover will begin immediately after it is started, and will last until it is manually stopped from the homepage.\n\n\\*_Takeovers will also affect devices that are registered after they have begun._\n\n## Getting Started\n\n### Prerequisites\n\nThis project requires Node.js and NPM (bundled with Node), as well as a MongoDB server. Since Node is cross-platform, it should work on Windows, MacOS, and Linux.\n\nThis project depends on [node_mdns](https://github.com/agnat/node_mdns), which in turn requires a mDNS stack. Follow the installation instructions [here](https://github.com/agnat/node_mdns#installation) for whichever platform you are on to install a mDNS stack. If you're on Linux, this is as simple as\n\n#### Debian/Ubuntu\n\n```shell\nsudo apt-get install build-essential libavahi-compat-libdnssd-dev\n```\n\n#### RedHat/Fedora/CentOS\n\n```shell\nsudo yum install gcc gcc-c++ avahi avahi-compat-libdns_sd avahi-compat-libdns_sd-devel nss_mdns\n```\n\n### Setup\n\nIf you don't already have access to a MongoDB server installation, follow the guide [here](https://docs.mongodb.com/manual/administration/install-community/).\n\nGrab the latest stable copy of Node/NPM from [here](https://nodejs.org/en/download/) or install it via [nvm](http://nvm.sh).\n\nIn order to access the Chromecast API, you need to [register as a Cast developer](https://cast.google.com/publish/) (it costs \\$5).\n\nOnce you've done this, log in to the [Cast Developer SDK Console](https://cast.google.com/u/1/publish/#/overview) and click **Add New Application**. Choose **Custom Receiver**, then name it `Multicast` and set the **Receiver Application URL** to `http://YOUR_LOCAL_IP:3944/landing`. Disable **Guest Mode** and then **Save**.\n\n**NOTE:** Make sure to use your LAN IP here (192.168.1.xx or similar), not your WAN/external IP. This should resolve to your server only within your local network.\n\nYou now need to register your Chromecast devices as developer devices. For each device, locate the Serial Number (located on the back of the device and on the box), click **Add New Device**, and enter the Serial Number and a brief Description. (**NOTE**: This may take up to 15 minutes to take effect. Go grab a cup of coffee and then head back.)\n\nInstallation is a snap with NPM.\n\n```shell\nnpm i multicast -g\nmulticast config\nmulticast start\n```\n\nHead over to `http://YOUR_LOCAL_IP:3944/` in your browser to get started, then simply follow the [Usage](#usage) guide to get off the ground.\n\nFor development, you can install locally via Github - clone this repository to your local machine, then head into the cloned directory and create a `.config` file for your setup.\n\n```shell\ngit clone https://github.com/superhawk610/multicast\ncd multicast\ncp .config.template .config\nvim .config\n```\n\n**NOTE**: You should leave `mongoAuthSource` and `mongoPort` set to their default unless you know what you're doing.\n\nInstall Node modules\n\n```shell\nnpm install\n```\n\nBuild files using Gulp\n\n```shell\ngulp\n```\n\nRun the application\n\n```shell\nnode .\n```\n\n### Firewall Settings\n\nIn order for a Chromecast to establish and maintain a connection with a Cast sender, the sender must open two ports:\n\n```html\n1900/UDP (DIAL) 5353/UDP (mDNS)\n```\n\nMake sure that the device running MultiCast has these ports open, as well as the standard HTTP ports\n\n```html\n80/TCP/UDP (HTTP) 443/TCP/UDP (HTTPS)\n```\n\n### Flags\n\n`--serve-only` - Do not attempt to connect to any devices, just serve files via Express. Useful for debugging.\n\n## Having Trouble?\n\n### Common Errors\n\n```html\n*** WARNING *** The program 'nodejs' uses the Apple Bonjour compatibility layer\nof Avahi. *** WARNING *** Please fix your application to use the native API of\nAvahi! *** WARNING *** For more information see\nhttp://0pointer.de/avahi-compat?s=libdns_sd\u0026e=nodejs *** WARNING *** The program\n'nodejs' called 'DNSServiceRegister()' which is not supported (or only supported\npartially) in the Apple Bonjour compatibility layer of Avahi. *** WARNING ***\nPlease fix your application to use the native API of Avahi! *** WARNING *** For\nmore information see\nhttp://0pointer.de/avahi-compat?s=libdns_sd\u0026e=nodejs\u0026f=DNSServiceRegister\n```\n\nDon't worry about this. This warning shows up in all Node apps on Linux that depend on `libavahi-compat-libdnssd-dev`. You can safely ignore it.\n\n**Can't launch after installing via NPM?**\nMake sure your `NODE_PATH` environment variable correctly includes the global store for node dependencies. On Linux:\n\n```shell\nexport NODE_PATH=/opt/lib/node_modules\n```\n\n**Multicast can't find your devices?**\nMake sure they've already been setup and powered on and the display that they're connected to is powered on and displaying their output.\n\nIf you can view them from other Cast-enabled apps but not from Multicast, its likely an issue with your firewall. Make sure you configured your firewall correctly (see [Firewall Settings](#firewall-settings)).\n\n**Using Node 8.6+?**\n\n**EDIT:** This has been patched as of node_mdns 2.3.4. This fix is no longer required.\n\nThe most recent version of node_mdns has an incompatibility with v8.6 due to changed syntax for a method (see [this pull request](https://github.com/agnat/node_mdns/pull/200)). Until it is fixed in the main branch, you will need to patch it yourself. Edit `node_modules/mdns/lib/resolver_sequence_tasks.js` and make the following change (roughly line 115):\n\n```diff\n\n   function getaddrinfo_0_11(host, family, cb) {\n     var req = new cares.GetAddrInfoReqWrap()\n-      , err = cares.getaddrinfo(req, host, family)\n+      , err = cares.getaddrinfo(req, host, family, 0, false)\n       ;\n     req.oncomplete = function oncomplete(err, addresses) {\n         getaddrinfo_complete(err, addresses, cb);\n\n```\n\n**Running CentOS and Seeing This Error?**\n\n```shell\nError: getaddrinfo -3008\n```\n\nMake sure you have `nss_mdns` installed:\n\n```shell\nsudo yum install nss_mdns\n```\n\n### Issues\n\nIf you run into any problems while using this, please report them [here](https://github.com/superhawk610/multicast/issues).\n\n## Authors\n\n![superhawk610](https://avatars0.githubusercontent.com/u/18172185?v=4\u0026s=32) Aaron Ross - _author_ - [superhawk610](https://github.com/superhawk610)\n\n![Brekmister](https://avatars0.githubusercontent.com/u/8389366?v=4\u0026s=32) [Brekmister](https://github.com/Brekmister) - _contributor_\n\n![ocelotsloth](https://avatars0.githubusercontent.com/u/9255772?v=4\u0026s=32) Mark Stenglein - _contributor_ - [ocelotsloth](https://github.com/ocelotsloth)\n\n![andrewpryor](https://avatars3.githubusercontent.com/u/1560890?v=4\u0026s=32) Andrew Pryor - _contributor_ - [andrewpryor](https://github.com/andrewpryor)\n\n## Contributing\n\n- **NEW**: Use a code editor that supports [Prettier](https://prettier.io/) and the included `.prettierrc.yml`\n- Follow the existing code formatting (2 spaces, not tabs, no hanging brackets, no semicolons, etc)\n- Comment your code to explain anything more complex than a routine action\n- Provide rationale for any changes you request\n- Use thorough commit/pull request messages\n\n### Active Branches\n\n**main** (_stable_) all features in this branch are fully implemented and ready to go\n\n**api** (_unstable_) this branch implements receiver grouping and remote control by splitting all functions out into an independent REST API\n\n**rotation** (_stable_) this branch adds the ability to display channels at 90/180/270 degress of rotation\n\n**authentication** (_unstable_) this branch adds a login page and POST/DELETE request verification\n\n**logging** (_unstable_) this branch adds real-time logging \u0026 monitoring of all console/page-load errors from receiver devices back to Multicast's web interface\n\n### Creating Layouts\n\nCreating a channel layout is simple, and consists of two things:\n\n**CSS Layout**\n\nCopy `app/views/layouts/template.pug` and change the name to your new channel layout name (e.g. - `my-layout.pug`).\n\nChange the class applied to the body to the name of your channel layout (e.g. - `body.my-layout`).\n\nIn `build/css/channel.css`, add rules to style each `iframe` in your layout, prefixing each with \u003ccode\u003ebody.\u003cem\u003elayout-name\u003c/em\u003e\u003c/code\u003e, replacing _layout-name_ with your layout name. Refer to the existing rules for inspiration.\n\n**NOTE**: Channel sections are currently limited to 4 per channel. To increase this, change `maxSectionCount` on `app/views/channel.pug`.\n\n**CSS Icon Design**\n\nIn `app/views/channel.pug`, add a div under `#channel-layout` with the class `layout` and \u003ccode\u003e\u003cem\u003elayout-name\u003c/em\u003e\u003c/code\u003e, again replacing _layout-name_ with your layout name. Make sure this div has the class `active` when the channel is using your layout, as such:\n\n\u003cpre\u003e\u003ccode\u003e.layout.\u003cem\u003elayout-name\u003c/em\u003e(class=(channel \u0026\u0026 channel.layout == '\u003cem\u003elayout-name\u003c/em\u003e' ? 'active' : ''))\u003c/code\u003e\u003c/pre\u003e\n\nStyle this div in `build/css/channel-edit.css` to conform to the existing channel layouts:\n\n```css\nwidth: 250px;\nheight: 150px;\nborder: 1px solid rgb(202, 206, 215);\n```\n\nOnce you finish, don't forget to `gulp` everything to apply your new layout.\n\n## Security Disclosure\n\nThis project relies on [node-castv2](https://github.com/thibauts/node-castv2) which uses an outdated version of [protobuf](https://github.com/dcodeIO/ProtoBuf.js/). I am in the process of getting this vulnerability patched - current status is tracked\n[here](https://github.com/thibauts/node-castv2/issues/39). Details of the vulnerability can be found [here](https://nvd.nist.gov/vuln/detail/CVE-2018-3738).\n\n## License\n\nThis project is licensed under the MIT License - see [LICENSE](LICENSE) for more details.\n\n## Acknowledgments\n\nSpecial thanks to [Greenscreen](https://github.com/groupon/greenscreen) and the team over at Groupon for inspiring this product.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperhawk610%2Fmulticast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuperhawk610%2Fmulticast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperhawk610%2Fmulticast/lists"}