{"id":13583546,"url":"https://github.com/castjs/castjs","last_synced_at":"2025-04-06T21:32:20.330Z","repository":{"id":40516098,"uuid":"155550965","full_name":"castjs/castjs","owner":"castjs","description":"📺 Chromecast Sender Library for the Browser","archived":false,"fork":false,"pushed_at":"2024-10-10T14:19:15.000Z","size":782,"stargazers_count":275,"open_issues_count":6,"forks_count":31,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-06T05:45:01.245Z","etag":null,"topics":["casting","chromecast","sender"],"latest_commit_sha":null,"homepage":"https://castjs.io","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/castjs.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-31T12:05:28.000Z","updated_at":"2025-03-19T00:14:00.000Z","dependencies_parsed_at":"2024-11-06T00:41:52.917Z","dependency_job_id":null,"html_url":"https://github.com/castjs/castjs","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castjs%2Fcastjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castjs%2Fcastjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castjs%2Fcastjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/castjs%2Fcastjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/castjs","download_url":"https://codeload.github.com/castjs/castjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247555824,"owners_count":20957844,"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":["casting","chromecast","sender"],"created_at":"2024-08-01T15:03:34.522Z","updated_at":"2025-04-06T21:32:20.056Z","avatar_url":"https://github.com/castjs.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://i.imgur.com/ZjTpQ3S.png\" alt=\"Castjs\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n\u003ch4 align=\"center\"\u003eJavascript library (\u003c10kb) for the complex chromecast SDK\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eCastjs\u003c/b\u003e provides simple events and functions to communicate with chromecast devices from the browser.\n  \u003cbr\u003e\n  This library works in chrome, opera, brave, firefox and vivaldi, see it in action and check out the \u003ca href=\"https://castjs.io/\"\u003eonline demo\u003c/a\u003e.\n  \u003cbr\u003e\u003cbr\u003e\n  \u003ca href=\"https://castjs.io/\"\u003e\u003cimg src=\"https://i.imgur.com/1nBtUac.png\" width=\"100%\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  Do you want to support my work, feel free to donate a \u003ca href=\"https://www.buymeacoffee.com/fenny\" target=\"_blank\"\u003e☕ Hot Beverage\u003c/a\u003e\n\u003c/p\u003e\n\n\n# Getting Started\n\nInclude the `cast.min.js` from [cdnjs](https://cdnjs.com/libraries/castjs):\n```html\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/castjs/5.3.0/cast.min.js\"\u003e\u003c/script\u003e\n```\n\n# Casting Media\n\nCasting a media source to your chromecast device. Make sure you enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) `Header set Access-Control-Allow-Origin \"*\"` on your media resources.\n\n```html\n\u003cbutton id=\"cast\"\u003eCast\u003c/button\u003e\n\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/castjs/5.3.0/cast.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n// Create new Castjs instance\nconst cjs = new Castjs();\n\n// Wait for user interaction\ndocument.getElementById('cast').addEventListener('click', function() {\n    // Check if casting is available\n    if (cjs.available) {\n        // Initiate new cast session with a simple video\n        cjs.cast('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4');\n\n        // A more complex example\n        cjs.cast('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4', {\n            poster     : 'https://castjs.io/media/poster.jpg',\n            title      : 'Sintel',\n            description: 'Third Open Movie by Blender Foundation',\n            subtitles: [{\n                active: true,\n                label : 'English',\n                src   : 'https://castjs.io/media/english.vtt'\n            }, {\n                label : 'Spanish',\n                src   : 'https://castjs.io/media/spanish.vtt'\n            }],\n        })\n    }\n});\n\u003c/script\u003e\n```\n\n# Supported Browsers\nAlmost any [Chromium]() based browser supports cast framework out of the box.\n\u003ca href=\"https://vivaldi.com/\"\u003e\u003cimg src=\"https://vivaldi.com/favicon.ico\" height=\"13\"\u003e Vivaldi\u003c/a\u003e\n\u003ca href=\"https://brave.com/\"\u003e\u003cimg src=\"https://brave.com/static-assets/images/brave-favicon.png\" height=\"15\"\u003e Brave\u003c/a\u003e\n\n# API Documentation:\n\n```javascript\n// Default instance\nconst cjs = new Castjs();\n\n// Custom receiver or joinpolicy\nconst cjs = new Castjs({\n    receiver  : 'CC1AD845',              // default\n    joinpolicy: 'tab_and_origin_scoped', // default\n//  joinpolicy: 'custom_controller_scoped',\n//  joinpolicy: 'origin_scoped',\n//  joinpolicy: 'page_scoped',\n});\n\n// Castjs Events\ncjs.on('available',    ()  =\u003e {});  // Casting is available\ncjs.on('connect',      ()  =\u003e {});  // Connected with device\ncjs.on('disconnect',   ()  =\u003e {});  // Disconnected with device\ncjs.on('statechange',  ()  =\u003e {});  // Device state\ncjs.on('timeupdate',   ()  =\u003e {});  // Current time changed\ncjs.on('volumechange', ()  =\u003e {});  // Volume changed\ncjs.on('mute',         ()  =\u003e {});  // Muted state changed\ncjs.on('unmute',       ()  =\u003e {});  // Muted state changed\ncjs.on('playing',      ()  =\u003e {});  // Media is playing\ncjs.on('pause',        ()  =\u003e {});  // Media is paused\ncjs.on('end',          ()  =\u003e {});  // Media ended\ncjs.on('buffering',    ()  =\u003e {});  // Media is buffering / seeking\ncjs.on('event',        (e) =\u003e {});  // Catch all events except 'error'\ncjs.on('error',        (e) =\u003e {});  // Catch any errors\n\n// Castjs functions\ncjs.cast(source, [metadata]); // Create session with media\ncjs.volume(0.7);              // Change volume\ncjs.play();                   // Play media\ncjs.pause();                  // Pause media\ncjs.mute();                   // Mutes media\ncjs.unmute();                 // Unmutes media\ncjs.subtitle(2);              // Change active subtitle index\ncjs.seek(15);                 // Seek 15 seconds\ncjs.seek(15.9, true);         // Seek 15.9% percentage\ncjs.disconnect();             // Disconnect session\n\n// Castjs properties\ncjs.version          // Castjs Version\ncjs.receiver         // Receiver ID\ncjs.available        // Casting is available\ncjs.connected        // Connected with cast device\ncjs.device           // Cast device name\ncjs.src              // Media source\ncjs.title            // Media title\ncjs.description      // Media description\ncjs.poster           // Media poster image\ncjs.subtitles        // Media subtitles\ncjs.volumeLevel      // Volume level\ncjs.muted            // If muted\ncjs.paused           // If paused\ncjs.time             // Time in seconds\ncjs.timePretty       // Time formatted in time hh:mm:ss\ncjs.duration         // Duration in seconds\ncjs.durationPretty   // Duration formatted in hh:mm:ss\ncjs.progress         // Progress in percentage 0 - 100\ncjs.state            // State of cast device\n```\n\n# FAQ\n\n**Question:** Can I cast local resources?\u003cbr\u003e\n**Answer:** It was possible in the past from the browser by using service workers. But we had to remove it from our library because Google dropped support, see https://github.com/fenny/chromecast-service-worker-crash\n\n**Question:** Do I need to enable CORS for all hosts?\u003cbr\u003e\n**Answer:** Yes and no. Chromecast is using an User-Agent that contains the word `CrKey` -\u003e `Mozilla/5.0 (X11; Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.225 Safari/537.36 CrKey/1.56.500000 DeviceType/Chromecast` so you could allow agents containing `CrKey` or `Chromecast` but this is not officialy documented.\n\n# TODO\n\n```\n- Add local media and stream support after google fixes service worker crash\n- Add name space messaging support for custom receivers\n- Maybe add video element support: new Castjs($('#video'))\n\n// Suggestions? Let me know!\n```\n\n\u003cp align=\"center\"\u003e\n  Do you want to support my work, feel free to donate a \u003ca href=\"https://www.buymeacoffee.com/fenny\" target=\"_blank\"\u003e☕ Hot Beverage\u003c/a\u003e\n\u003c/p\u003e\n","funding_links":["https://www.buymeacoffee.com/fenny"],"categories":["HarmonyOS","JavaScript"],"sub_categories":["Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcastjs%2Fcastjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcastjs%2Fcastjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcastjs%2Fcastjs/lists"}