Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

411 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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/castjs@v7.0.0/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/castjs@v7.0.0/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.io/media/poster.jpg',
      title: 'Sintel',
      description: 'Third Open Movie by Blender Foundation',
      subtitles: [{
        active: true,
        label: 'English',
        src: 'https://castjs.io/media/english.vtt'
      }, {
        label: 'Spanish',
        src: 'https://castjs.io/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


About

πŸ“Ί Chromecast Sender Library for the Browser

Topics

Resources

Stars

295 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages