Profile
Back to NewsBack
GitHub Trending 4 min
Reader Mode
castjs/castjs: 📺 Chromecast Sender Library for the Browser

castjs/castjs: 📺 Chromecast Sender Library for the Browser

16 hours ago

Castjs

Javascript library (<10kb) for the complex Chromecast SDK

Castjs provides simple events and functions to communicate with Chromecast devices from the browser.
This library works in Chrome, Opera, Brave, Edge and Vivaldi. See it in action on the online demo.



Do you want to support my work? Feel free to donate a ☕ Hot Beverage


Getting Started

Include the library from cdnjs:

<script src="https://cdn.jsdelivr.net/gh/castjs/[email protected]/cast.min.js"></script>
The Google Cast framework (cast_sender.js) is automatically loaded if it is not already present on the page.

Casting Media

Make sure you enable CORS on your media resources:

Access-Control-Allow-Origin: *
<button id="cast">Cast</button>

<script src="https://cdn.jsdelivr.net/gh/castjs/[email protected]/cast.min.js"></script> <script> const cjs = new Castjs();

document.getElementById('cast').addEventListener('click', () => { if (cjs.available()) { // Simple example cjs.cast('https://www.peach.themazzone.com/durian/movies/sintel-1024-surround.mp4');

// Full example with metadata + subtitles cjs.cast('https://www.peach.themazzone.com/durian/movies/sintel-1024-surround.mp4', { poster: 'https://castjs.com/media/poster.jpg', title: 'Sintel', description: 'Third Open Movie by Blender Foundation', subtitles: [{ active: true, label: 'English', src: 'https://castjs.com/media/english.vtt' }, { label: 'Spanish', src: 'https://castjs.com/media/spanish.vtt' }] }); } }); </script>


Supported Browsers

Almost any Chromium-based browser supports the Cast framework:

Requires HTTPS (or localhost)

API Documentation

Initialize

// Default instance
const cjs = new Castjs();

// Custom options const cjs = new Castjs({ joinpolicy: 'tab_and_origin_scoped', // default // 'tab_and_origin_scoped' | 'origin_scoped' | 'page_scoped' receiver: 'CC1AD845', // default media receiver debug: true // enable debug logs });

Methods

cjs.cast(src, metadata)     // Start casting
cjs.play()                  // Resume playback
cjs.pause()                 // Pause playback
cjs.disconnect()            // End session

cjs.time() // Get current time (seconds) cjs.time(120) // Seek to 2:00 cjs.time(true) // Get formatted time ("02:00")

cjs.duration() // Get duration (seconds) cjs.duration(true) // Get formatted duration

cjs.volume() // Get volume (0 → 1) cjs.volume(0.5) // Set volume

cjs.muted() // Get mute state cjs.muted(true) // Mute cjs.muted(false) // Unmute

cjs.subtitle(0) // Change active subtitle by index

Events

cjs.on('available',      () => {})    // Cast framework is ready
cjs.on('connect',        () => {})    // Connected to a device
cjs.on('disconnect',     () => {})    // Session ended

cjs.on('statechange', () => {}) // Player state changed cjs.on('playing', () => {}) // Media is playing cjs.on('pause', () => {}) // Media is paused cjs.on('buffering', () => {}) // Buffering / seeking cjs.on('end', () => {}) // Media ended

cjs.on('timeupdate', () => {}) // Current time changed cjs.on('volumechange', () => {}) // Volume changed cjs.on('mute', () => {}) // Muted cjs.on('unmute', () => {}) // Unmuted cjs.on('subtitlechange', () => {}) // Active subtitle changed

cjs.on('event', (e) => {}) // Catch all events except 'error' cjs.on('error', (e) => {}) // Catch any errors

Getters

cjs.available()      // boolean  – is Cast available
cjs.connected()      // boolean  – is connected to a device
cjs.device()         // string   – device name
cjs.state()          // string   – current state
cjs.paused()         // boolean  – is paused

cjs.src() // current media URL cjs.title() // media title cjs.description() // media description cjs.poster() // poster image URL cjs.subtitles() // array of subtitle tracks cjs.progress() // progress (0 → 100)

cjs.volume() // volume (0 → 1) cjs.muted() // is muted cjs.time() // current time in seconds cjs.time(true) // formatted time ("01:23") cjs.duration() // duration in seconds cjs.duration(true) // formatted duration

Metadata

cjs.cast('https://example.com/video.mp4', {
  title: 'My Video',
  description: 'Optional description',
  poster: 'https://example.com/poster.jpg',
  time: 30,                    // start position in seconds
  paused: false,

subtitles: [{ label: 'English', src: 'https://example.com/en.vtt', subtype: 'SUBTITLES', // SUBTITLES | CAPTIONS | DESCRIPTIONS | CHAPTERS | METADATA active: true }],

// Optional (Netflix-style defaults are already applied) subtitleStyle: { backgroundColor: '#00000000', foregroundColor: '#FFFFFF', edgeType: 'DROP_SHADOW', edgeColor: '#000000FF', fontFamily: 'CASUAL', fontScale: 1.0 } });


FAQ

Question: Can I cast local resources?
Answer: It was possible in the past using service workers, but Google dropped support. See this issue.

Question: Do I need to enable CORS?
Answer: Yes. Chromecast is strict about CORS. You can allow the CrKey user-agent if you want to be more specific, but Access-Control-Allow-Origin: * is the simplest solution.


Do you want to support my work? Feel free to donate a ☕ Hot Beverage


Chat with me