ionic-chromecast
v0.0.7
Published
Capacitor plugin for Google Cast SDK (Chromecast) integration with Android support
Downloads
15
Maintainers
Readme
ionic-chromecast
A Capacitor plugin for integrating Google Cast SDK (Chromecast) with Ionic/Capacitor applications.
Features
- ✅ Initialize Google Cast SDK
- ✅ Session management (request, check status)
- ✅ Device discovery
- ✅ Media playback with rich metadata
- ✅ End active Cast session from app
- ✅ Android support
- ✅ Event listeners
- 🚧 iOS support (coming soon)
Install
npm install ionic-chromecast
npx cap syncAndroid Configuration
The plugin automatically configures the necessary permissions and Cast options:
INTERNETACCESS_NETWORK_STATEACCESS_WIFI_STATE
Requirements
- Android API 23+
- Google Play Services
- Chromecast device on the same WiFi network
Quick Start
1. Initialize the Cast SDK
import { IonicChromecast } from 'ionic-chromecast';
// In your app.component.ts or main initialization
async initializeCast() {
const result = await IonicChromecast.initialize({
// Prefer CastVideos CAF receiver for reliable UI on TV. Use 'CC1AD845' if you need the default.
receiverApplicationId: '4F8B3483'
});
if (result.success) {
console.log('✅ Cast SDK ready!');
}
}2. Check for Available Devices
async checkDevices() {
const { available } = await IonicChromecast.areDevicesAvailable();
if (available) {
console.log('📡 Chromecast devices found!');
} else {
console.log('❌ No devices available');
}
}3. Start a Cast Session
async startCasting() {
const result = await IonicChromecast.requestSession();
if (result.success) {
console.log('🎬 Cast session started!');
}
}4. Load Media
async playVideo() {
const result = await IonicChromecast.loadMedia({
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
metadata: {
title: 'Big Buck Bunny',
subtitle: 'Blender Foundation',
images: ['https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'],
contentType: 'video/mp4',
duration: 596
}
});
if (result.success) {
console.log('▶️ Video is playing on TV!');
}
}
// Optional: end the current Cast session from the app
async stopCasting() {
const result = await IonicChromecast.endSession();
if (result.success) {
console.log('⏹ Cast session ended');
}
}Complete Examples
Example 1: Basic Cast Integration
import { Component, OnInit } from '@angular/core';
import { IonicChromecast } from 'ionic-chromecast';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
})
export class HomePage implements OnInit {
castAvailable = false;
sessionActive = false;
async ngOnInit() {
// Initialize Cast SDK
await IonicChromecast.initialize({
receiverApplicationId: 'CC1AD845'
});
// Check for devices
const { available } = await IonicChromecast.areDevicesAvailable();
this.castAvailable = available;
}
async connectToTV() {
const result = await IonicChromecast.requestSession();
if (result.success) {
this.sessionActive = true;
}
}
async checkSession() {
const { active } = await IonicChromecast.isSessionActive();
this.sessionActive = active;
return active;
}
}Example 2: Video Player with Cast
import { Component } from '@angular/core';
import { IonicChromecast } from 'ionic-chromecast';
@Component({
selector: 'app-player',
templateUrl: 'player.page.html',
})
export class PlayerPage {
async castVideo(videoUrl: string, videoTitle: string, posterUrl: string) {
// Check if session is active
const { active } = await IonicChromecast.isSessionActive();
if (!active) {
// Request session first
await IonicChromecast.requestSession();
}
// Load the video
const result = await IonicChromecast.loadMedia({
url: videoUrl,
metadata: {
title: videoTitle,
subtitle: 'Your App Name',
images: [posterUrl],
contentType: 'video/mp4'
}
});
if (result.success) {
console.log('🎥 Now casting:', videoTitle);
}
}
async castFromLibrary() {
const videos = [
{
title: 'Big Buck Bunny',
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
poster: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'
},
{
title: 'Elephants Dream',
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4',
poster: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg'
}
];
// Cast first video
await this.castVideo(videos[0].url, videos[0].title, videos[0].poster);
}
}Example 3: Advanced Cast Controls
import { Component, OnDestroy } from '@angular/core';
import { IonicChromecast } from 'ionic-chromecast';
@Component({
selector: 'app-cast-control',
templateUrl: 'cast-control.page.html',
})
export class CastControlPage implements OnDestroy {
private eventListeners: any[] = [];
async ngOnInit() {
// Initialize
await IonicChromecast.initialize({
receiverApplicationId: 'CC1AD845'
});
// Listen to events
this.setupEventListeners();
}
async setupEventListeners() {
const sessionHandle = await IonicChromecast.addListener('sessionStarted', (event) => {
console.log('✅ Session started:', event);
});
const mediaHandle = await IonicChromecast.addListener('mediaLoaded', (event) => {
console.log('🎬 Media loaded:', event);
});
this.eventListeners.push(sessionHandle, mediaHandle);
}
async fullCastWorkflow() {
// 1. Check for devices
const devicesResult = await IonicChromecast.areDevicesAvailable();
if (!devicesResult.available) {
alert('No Chromecast devices found. Make sure you are on the same WiFi network.');
return;
}
// 2. Request session
const sessionResult = await IonicChromecast.requestSession();
if (!sessionResult.success) {
alert('Failed to connect to Chromecast');
return;
}
// 3. Wait a moment for session to establish
await new Promise(resolve => setTimeout(resolve, 1000));
// 4. Load media
const mediaResult = await IonicChromecast.loadMedia({
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
metadata: {
title: 'Big Buck Bunny',
subtitle: 'A Blender Open Movie',
studio: 'Blender Foundation',
images: [
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'
],
contentType: 'video/mp4',
duration: 596 // seconds
}
});
if (mediaResult.success) {
console.log('🎉 Successfully casting video!');
}
}
ngOnDestroy() {
// Clean up listeners
this.eventListeners.forEach(handle => handle.remove());
}
async stopCast() {
await IonicChromecast.endSession();
}
}Example 4: Cast Button Component
// cast-button.component.ts
import { Component, OnInit } from '@angular/core';
import { IonicChromecast } from 'ionic-chromecast';
@Component({
selector: 'app-cast-button',
template: `
<ion-button
*ngIf="devicesAvailable"
(click)="toggleCast()"
[color]="sessionActive ? 'primary' : 'medium'">
<ion-icon [name]="sessionActive ? 'wifi' : 'wifi-outline'"></ion-icon>
{{ sessionActive ? 'Casting' : 'Cast' }}
</ion-button>
`
})
export class CastButtonComponent implements OnInit {
devicesAvailable = false;
sessionActive = false;
async ngOnInit() {
await this.checkDevices();
await this.checkSession();
// Check periodically
setInterval(() => {
this.checkDevices();
this.checkSession();
}, 5000);
}
async checkDevices() {
const result = await IonicChromecast.areDevicesAvailable();
this.devicesAvailable = result.available;
}
async checkSession() {
const result = await IonicChromecast.isSessionActive();
this.sessionActive = result.active;
}
async toggleCast() {
if (this.sessionActive) {
// Session is active - could implement endSession() here
console.log('Session is active');
} else {
// Request new session
await IonicChromecast.requestSession();
}
}
}API
initialize(...)echo(...)requestSession()isSessionActive()areDevicesAvailable()loadMedia(...)endSession()addListener(ChromecastEventType, ...)- Interfaces
- Type Aliases
initialize(...)
initialize(options: InitializeOptions) => Promise<{ success: boolean; }>Initialize the Google Cast SDK Must be called before any other Cast operations
| Param | Type |
| ------------- | --------------------------------------------------------------- |
| options | InitializeOptions |
Returns: Promise<{ success: boolean; }>
echo(...)
echo(options: { value: string; }) => Promise<{ value: string; }>| Param | Type |
| ------------- | ------------------------------- |
| options | { value: string; } |
Returns: Promise<{ value: string; }>
requestSession()
requestSession() => Promise<RequestSessionResult>Request a Cast session (Android only)
Returns: Promise<RequestSessionResult>
isSessionActive()
isSessionActive() => Promise<SessionStatusResult>Check if there is an active Cast session (Android only)
Returns: Promise<SessionStatusResult>
areDevicesAvailable()
areDevicesAvailable() => Promise<DevicesAvailableResult>Check if there are available Cast devices (Android only)
Returns: Promise<DevicesAvailableResult>
loadMedia(...)
loadMedia(options: LoadMediaOptions) => Promise<{ success: boolean; message?: string; }>Load media on the Cast device (Android only)
| Param | Type |
| ------------- | ------------------------------------------------------------- |
| options | LoadMediaOptions |
Returns: Promise<{ success: boolean; message?: string; }>
endSession()
endSession() => Promise<{ success: boolean; message?: string; }>End the current Cast session (Android only)
Returns: Promise<{ success: boolean; message?: string; }>
addListener(ChromecastEventType, ...)
addListener(eventName: ChromecastEventType, listenerFunc: (event: ChromecastEvent) => void) => PluginListenerHandleListen to Chromecast events (Android only)
| Param | Type |
| ------------------ | ------------------------------------------------------------------------------- |
| eventName | ChromecastEventType |
| listenerFunc | (event: ChromecastEvent) => void |
Returns: PluginListenerHandle
Interfaces
InitializeOptions
| Prop | Type | Description |
| --------------------------- | ------------------- | ----------------------------------------------------------------------------------------- |
| receiverApplicationId | string | The receiver application ID for Google Cast Use "CC1AD845" for the default media receiver |
RequestSessionResult
| Prop | Type |
| ------------- | -------------------- |
| success | boolean |
| message | string |
SessionStatusResult
| Prop | Type |
| ------------- | -------------------- |
| active | boolean |
| message | string |
DevicesAvailableResult
| Prop | Type |
| --------------- | -------------------- |
| available | boolean |
| message | string |
LoadMediaOptions
| Prop | Type |
| -------------- | ------------------------------------------------------- |
| url | string |
| metadata | MediaMetadata |
MediaMetadata
| Prop | Type |
| ----------------- | --------------------- |
| title | string |
| subtitle | string |
| images | string[] |
| studio | string |
| contentType | string |
| duration | number |
PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| remove | () => Promise<void> |
ChromecastEvent
| Prop | Type |
| ---------- | ------------------------------------------------------------------- |
| type | ChromecastEventType |
| data | any |
Type Aliases
ChromecastEventType
'sessionStarted' | 'sessionEnded' | 'mediaLoaded' | 'mediaError' | 'deviceAvailable' | 'deviceUnavailable' | 'volumeChanged' | 'playbackStatusChanged'
Troubleshooting
- No Cast UI on TV after connecting: use the CastVideos CAF receiver ID
4F8B3483instead of the defaultCC1AD845when callinginitialize. - Media returns success but nothing plays: confirm a session is active (
isSessionActive), then retryloadMediawith a known-good HTTPS MP4 (e.g., BigBuckBunny). - Devices not found: ensure the phone and Chromecast are on the same WiFi and Google Play Services is up to date.
