ionic-chromecast 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +290 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,10 +5,12 @@ A Capacitor plugin for integrating Google Cast SDK (Chromecast) with Ionic/Capac
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- ✅ Initialize Google Cast SDK
|
|
8
|
+
- ✅ Session management (request, check status)
|
|
9
|
+
- ✅ Device discovery
|
|
10
|
+
- ✅ Media playback with rich metadata
|
|
8
11
|
- ✅ Android support
|
|
12
|
+
- ✅ Event listeners
|
|
9
13
|
- 🚧 iOS support (coming soon)
|
|
10
|
-
- 🚧 Session management
|
|
11
|
-
- 🚧 Media playback control
|
|
12
14
|
|
|
13
15
|
## Install
|
|
14
16
|
|
|
@@ -19,61 +21,315 @@ npx cap sync
|
|
|
19
21
|
|
|
20
22
|
## Android Configuration
|
|
21
23
|
|
|
22
|
-
The plugin automatically configures the necessary permissions and Cast options
|
|
24
|
+
The plugin automatically configures the necessary permissions and Cast options:
|
|
25
|
+
- `INTERNET`
|
|
26
|
+
- `ACCESS_NETWORK_STATE`
|
|
27
|
+
- `ACCESS_WIFI_STATE`
|
|
23
28
|
|
|
24
|
-
###
|
|
29
|
+
### Requirements
|
|
30
|
+
- Android API 23+
|
|
31
|
+
- Google Play Services
|
|
32
|
+
- Chromecast device on the same WiFi network
|
|
25
33
|
|
|
26
|
-
|
|
34
|
+
## Quick Start
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
### 1. Initialize the Cast SDK
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
```typescript
|
|
39
|
+
import { IonicChromecast } from 'ionic-chromecast';
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
// In your app.component.ts or main initialization
|
|
42
|
+
async initializeCast() {
|
|
43
|
+
const result = await IonicChromecast.initialize({
|
|
44
|
+
receiverApplicationId: 'CC1AD845' // Default Media Receiver
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (result.success) {
|
|
48
|
+
console.log('✅ Cast SDK ready!');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Check for Available Devices
|
|
33
54
|
|
|
34
55
|
```typescript
|
|
35
|
-
|
|
56
|
+
async checkDevices() {
|
|
57
|
+
const { available } = await IonicChromecast.areDevicesAvailable();
|
|
58
|
+
|
|
59
|
+
if (available) {
|
|
60
|
+
console.log('📡 Chromecast devices found!');
|
|
61
|
+
} else {
|
|
62
|
+
console.log('❌ No devices available');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
36
66
|
|
|
37
|
-
|
|
38
|
-
await IonicChromecast.initialize({
|
|
39
|
-
receiverApplicationId: 'CC1AD845' // Default Media Receiver
|
|
40
|
-
});
|
|
67
|
+
### 3. Start a Cast Session
|
|
41
68
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
69
|
+
```typescript
|
|
70
|
+
async startCasting() {
|
|
71
|
+
const result = await IonicChromecast.requestSession();
|
|
72
|
+
|
|
73
|
+
if (result.success) {
|
|
74
|
+
console.log('🎬 Cast session started!');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
46
77
|
```
|
|
47
78
|
|
|
48
|
-
###
|
|
79
|
+
### 4. Load Media
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
async playVideo() {
|
|
83
|
+
const result = await IonicChromecast.loadMedia({
|
|
84
|
+
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
|
|
85
|
+
metadata: {
|
|
86
|
+
title: 'Big Buck Bunny',
|
|
87
|
+
subtitle: 'Blender Foundation',
|
|
88
|
+
images: ['https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'],
|
|
89
|
+
contentType: 'video/mp4',
|
|
90
|
+
duration: 596
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.success) {
|
|
95
|
+
console.log('▶️ Video is playing on TV!');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
49
99
|
|
|
50
|
-
|
|
51
|
-
- Initialize only once per app session
|
|
52
|
-
- Handle initialization errors appropriately
|
|
100
|
+
## Complete Examples
|
|
53
101
|
|
|
54
|
-
|
|
102
|
+
### Example 1: Basic Cast Integration
|
|
55
103
|
|
|
56
104
|
```typescript
|
|
57
105
|
import { Component, OnInit } from '@angular/core';
|
|
58
106
|
import { IonicChromecast } from 'ionic-chromecast';
|
|
59
107
|
|
|
60
108
|
@Component({
|
|
61
|
-
selector: 'app-
|
|
62
|
-
templateUrl: '
|
|
109
|
+
selector: 'app-home',
|
|
110
|
+
templateUrl: 'home.page.html',
|
|
111
|
+
})
|
|
112
|
+
export class HomePage implements OnInit {
|
|
113
|
+
|
|
114
|
+
castAvailable = false;
|
|
115
|
+
sessionActive = false;
|
|
116
|
+
|
|
117
|
+
async ngOnInit() {
|
|
118
|
+
// Initialize Cast SDK
|
|
119
|
+
await IonicChromecast.initialize({
|
|
120
|
+
receiverApplicationId: 'CC1AD845'
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Check for devices
|
|
124
|
+
const { available } = await IonicChromecast.areDevicesAvailable();
|
|
125
|
+
this.castAvailable = available;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async connectToTV() {
|
|
129
|
+
const result = await IonicChromecast.requestSession();
|
|
130
|
+
if (result.success) {
|
|
131
|
+
this.sessionActive = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async checkSession() {
|
|
136
|
+
const { active } = await IonicChromecast.isSessionActive();
|
|
137
|
+
this.sessionActive = active;
|
|
138
|
+
return active;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Example 2: Video Player with Cast
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { Component } from '@angular/core';
|
|
147
|
+
import { IonicChromecast } from 'ionic-chromecast';
|
|
148
|
+
|
|
149
|
+
@Component({
|
|
150
|
+
selector: 'app-player',
|
|
151
|
+
templateUrl: 'player.page.html',
|
|
152
|
+
})
|
|
153
|
+
export class PlayerPage {
|
|
154
|
+
|
|
155
|
+
async castVideo(videoUrl: string, videoTitle: string, posterUrl: string) {
|
|
156
|
+
// Check if session is active
|
|
157
|
+
const { active } = await IonicChromecast.isSessionActive();
|
|
158
|
+
|
|
159
|
+
if (!active) {
|
|
160
|
+
// Request session first
|
|
161
|
+
await IonicChromecast.requestSession();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Load the video
|
|
165
|
+
const result = await IonicChromecast.loadMedia({
|
|
166
|
+
url: videoUrl,
|
|
167
|
+
metadata: {
|
|
168
|
+
title: videoTitle,
|
|
169
|
+
subtitle: 'Your App Name',
|
|
170
|
+
images: [posterUrl],
|
|
171
|
+
contentType: 'video/mp4'
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (result.success) {
|
|
176
|
+
console.log('🎥 Now casting:', videoTitle);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async castFromLibrary() {
|
|
181
|
+
const videos = [
|
|
182
|
+
{
|
|
183
|
+
title: 'Big Buck Bunny',
|
|
184
|
+
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
|
|
185
|
+
poster: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
title: 'Elephants Dream',
|
|
189
|
+
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4',
|
|
190
|
+
poster: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/ElephantsDream.jpg'
|
|
191
|
+
}
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
// Cast first video
|
|
195
|
+
await this.castVideo(videos[0].url, videos[0].title, videos[0].poster);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Example 3: Advanced Cast Controls
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { Component, OnDestroy } from '@angular/core';
|
|
204
|
+
import { IonicChromecast } from 'ionic-chromecast';
|
|
205
|
+
|
|
206
|
+
@Component({
|
|
207
|
+
selector: 'app-cast-control',
|
|
208
|
+
templateUrl: 'cast-control.page.html',
|
|
63
209
|
})
|
|
64
|
-
export class
|
|
210
|
+
export class CastControlPage implements OnDestroy {
|
|
211
|
+
|
|
212
|
+
private eventListeners: any[] = [];
|
|
65
213
|
|
|
66
214
|
async ngOnInit() {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
215
|
+
// Initialize
|
|
216
|
+
await IonicChromecast.initialize({
|
|
217
|
+
receiverApplicationId: 'CC1AD845'
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Listen to events
|
|
221
|
+
this.setupEventListeners();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async setupEventListeners() {
|
|
225
|
+
const sessionHandle = await IonicChromecast.addListener('sessionStarted', (event) => {
|
|
226
|
+
console.log('✅ Session started:', event);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const mediaHandle = await IonicChromecast.addListener('mediaLoaded', (event) => {
|
|
230
|
+
console.log('🎬 Media loaded:', event);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
this.eventListeners.push(sessionHandle, mediaHandle);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async fullCastWorkflow() {
|
|
237
|
+
// 1. Check for devices
|
|
238
|
+
const devicesResult = await IonicChromecast.areDevicesAvailable();
|
|
239
|
+
if (!devicesResult.available) {
|
|
240
|
+
alert('No Chromecast devices found. Make sure you are on the same WiFi network.');
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 2. Request session
|
|
245
|
+
const sessionResult = await IonicChromecast.requestSession();
|
|
246
|
+
if (!sessionResult.success) {
|
|
247
|
+
alert('Failed to connect to Chromecast');
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// 3. Wait a moment for session to establish
|
|
252
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
253
|
+
|
|
254
|
+
// 4. Load media
|
|
255
|
+
const mediaResult = await IonicChromecast.loadMedia({
|
|
256
|
+
url: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
|
|
257
|
+
metadata: {
|
|
258
|
+
title: 'Big Buck Bunny',
|
|
259
|
+
subtitle: 'A Blender Open Movie',
|
|
260
|
+
studio: 'Blender Foundation',
|
|
261
|
+
images: [
|
|
262
|
+
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'
|
|
263
|
+
],
|
|
264
|
+
contentType: 'video/mp4',
|
|
265
|
+
duration: 596 // seconds
|
|
74
266
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
if (mediaResult.success) {
|
|
270
|
+
console.log('🎉 Successfully casting video!');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
ngOnDestroy() {
|
|
275
|
+
// Clean up listeners
|
|
276
|
+
this.eventListeners.forEach(handle => handle.remove());
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Example 4: Cast Button Component
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// cast-button.component.ts
|
|
285
|
+
import { Component, OnInit } from '@angular/core';
|
|
286
|
+
import { IonicChromecast } from 'ionic-chromecast';
|
|
287
|
+
|
|
288
|
+
@Component({
|
|
289
|
+
selector: 'app-cast-button',
|
|
290
|
+
template: `
|
|
291
|
+
<ion-button
|
|
292
|
+
*ngIf="devicesAvailable"
|
|
293
|
+
(click)="toggleCast()"
|
|
294
|
+
[color]="sessionActive ? 'primary' : 'medium'">
|
|
295
|
+
<ion-icon [name]="sessionActive ? 'wifi' : 'wifi-outline'"></ion-icon>
|
|
296
|
+
{{ sessionActive ? 'Casting' : 'Cast' }}
|
|
297
|
+
</ion-button>
|
|
298
|
+
`
|
|
299
|
+
})
|
|
300
|
+
export class CastButtonComponent implements OnInit {
|
|
301
|
+
|
|
302
|
+
devicesAvailable = false;
|
|
303
|
+
sessionActive = false;
|
|
304
|
+
|
|
305
|
+
async ngOnInit() {
|
|
306
|
+
await this.checkDevices();
|
|
307
|
+
await this.checkSession();
|
|
308
|
+
|
|
309
|
+
// Check periodically
|
|
310
|
+
setInterval(() => {
|
|
311
|
+
this.checkDevices();
|
|
312
|
+
this.checkSession();
|
|
313
|
+
}, 5000);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async checkDevices() {
|
|
317
|
+
const result = await IonicChromecast.areDevicesAvailable();
|
|
318
|
+
this.devicesAvailable = result.available;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async checkSession() {
|
|
322
|
+
const result = await IonicChromecast.isSessionActive();
|
|
323
|
+
this.sessionActive = result.active;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async toggleCast() {
|
|
327
|
+
if (this.sessionActive) {
|
|
328
|
+
// Session is active - could implement endSession() here
|
|
329
|
+
console.log('Session is active');
|
|
330
|
+
} else {
|
|
331
|
+
// Request new session
|
|
332
|
+
await IonicChromecast.requestSession();
|
|
77
333
|
}
|
|
78
334
|
}
|
|
79
335
|
}
|
package/package.json
CHANGED