0
# Media Control
1
2
Comprehensive media playback control supporting various content types, streaming protocols, and playback states. The MediaController provides queue management, seek operations, subtitle control, and detailed status monitoring for all media operations.
3
4
## Capabilities
5
6
### Media Playback Control
7
8
Main controller for playing and controlling media on Chromecast devices.
9
10
```python { .api }
11
class MediaController:
12
"""Controller to interact with the Chromecast media namespace."""
13
14
def play_media(self, url, content_type, *, title=None, thumb=None,
15
current_time=None, autoplay=True, stream_type=STREAM_TYPE_LIVE,
16
metadata=None, subtitles=None, subtitles_lang="en-US",
17
subtitles_mime="text/vtt", subtitle_id=1, enqueue=False,
18
media_info=None, callback_function=None):
19
"""
20
Start playing media.
21
22
Parameters:
23
- url: str, URL of the media to play
24
- content_type: str, MIME type of the media (e.g., 'video/mp4', 'audio/mp3')
25
- title: str | None, Media title
26
- thumb: str | None, Thumbnail image URL
27
- current_time: float | None, Start position in seconds (None for beginning)
28
- autoplay: bool, Start playing immediately (default True)
29
- stream_type: str, Stream type (default STREAM_TYPE_LIVE)
30
- metadata: dict | None, Additional metadata
31
- subtitles: str | None, Subtitle track URL
32
- subtitles_lang: str, Subtitle language code (default "en-US")
33
- subtitles_mime: str, Subtitle MIME type (default "text/vtt")
34
- subtitle_id: int, Subtitle track ID (default 1)
35
- enqueue: bool, Add to queue instead of playing immediately
36
- media_info: dict | None, Custom media information
37
- callback_function: callable | None, Callback for request completion
38
"""
39
```
40
41
**Usage Example:**
42
43
```python
44
# Access media controller
45
media_ctrl = cast.media_controller
46
47
# Play a video file
48
media_ctrl.play_media(
49
url="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
50
content_type="video/mp4",
51
title="Big Buck Bunny",
52
thumb="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg"
53
)
54
55
# Play audio with metadata
56
media_ctrl.play_media(
57
url="https://example.com/audio.mp3",
58
content_type="audio/mp3",
59
title="My Song",
60
metadata={
61
"artist": "Artist Name",
62
"album": "Album Name",
63
"albumArtist": "Album Artist",
64
"duration": 240.5
65
}
66
)
67
68
# Play with subtitles
69
media_ctrl.play_media(
70
url="https://example.com/video.mp4",
71
content_type="video/mp4",
72
title="Movie with Subtitles",
73
subtitles="https://example.com/subtitles.vtt",
74
subtitles_lang="en-US",
75
subtitles_mime="text/vtt"
76
)
77
```
78
79
### Playback Control
80
81
Control media playback state and position.
82
83
```python { .api }
84
def play(self):
85
"""Resume media playback."""
86
87
def pause(self):
88
"""Pause media playback."""
89
90
def stop(self):
91
"""Stop media playback."""
92
93
def rewind(self):
94
"""Rewind media playback."""
95
96
def skip(self):
97
"""Skip current media item."""
98
99
def seek(self, position):
100
"""
101
Seek to specific position in media.
102
103
Parameters:
104
- position: float, Position in seconds to seek to
105
"""
106
107
def set_playback_rate(self, playback_rate):
108
"""
109
Set playback rate/speed.
110
111
Parameters:
112
- playback_rate: float, Playback rate (1.0 = normal speed)
113
"""
114
```
115
116
**Usage Example:**
117
118
```python
119
# Wait for media to start
120
media_ctrl.block_until_active()
121
122
# Control playback
123
media_ctrl.pause()
124
time.sleep(2)
125
media_ctrl.play()
126
127
# Seek to 1 minute mark
128
media_ctrl.seek(60.0)
129
130
# Change playback speed
131
media_ctrl.set_playback_rate(1.5) # 1.5x speed
132
media_ctrl.set_playback_rate(1.0) # Back to normal
133
134
# Stop playback
135
media_ctrl.stop()
136
```
137
138
### Queue Management
139
140
Manage media queue for playlist functionality.
141
142
```python { .api }
143
def queue_next(self):
144
"""Skip to next item in queue."""
145
146
def queue_prev(self):
147
"""Skip to previous item in queue."""
148
149
def queue_insert_items(self, items, current_item_id=None,
150
current_item_index=None, insert_before=None):
151
"""
152
Insert items into the media queue.
153
154
Parameters:
155
- items: list, List of media items to insert
156
- current_item_id: int | None, Current item ID reference
157
- current_item_index: int | None, Current item index reference
158
- insert_before: int | None, Insert before this item ID
159
"""
160
161
def queue_update_items(self, items):
162
"""
163
Update items in the media queue.
164
165
Parameters:
166
- items: list, List of media items with updates
167
"""
168
```
169
170
**Usage Example:**
171
172
```python
173
# Add items to queue
174
queue_items = [
175
{
176
"contentId": "https://example.com/song1.mp3",
177
"contentType": "audio/mp3",
178
"metadata": {"title": "Song 1", "artist": "Artist"}
179
},
180
{
181
"contentId": "https://example.com/song2.mp3",
182
"contentType": "audio/mp3",
183
"metadata": {"title": "Song 2", "artist": "Artist"}
184
}
185
]
186
187
media_ctrl.queue_insert_items(queue_items)
188
189
# Navigate queue
190
media_ctrl.queue_next() # Skip to next song
191
media_ctrl.queue_prev() # Go back to previous song
192
```
193
194
### Volume Control
195
196
Control media-specific volume and muting.
197
198
```python { .api }
199
def set_volume(self, volume):
200
"""
201
Set media volume level.
202
203
Parameters:
204
- volume: float, Volume level (0.0 to 1.0)
205
"""
206
207
def set_volume_muted(self, muted):
208
"""
209
Set media mute state.
210
211
Parameters:
212
- muted: bool, True to mute, False to unmute
213
"""
214
```
215
216
### Status Monitoring
217
218
Monitor media status and wait for state changes.
219
220
```python { .api }
221
def update_status(self, callback_function=None):
222
"""
223
Request updated media status from device.
224
225
Parameters:
226
- callback_function: callable | None, Function to call when status received
227
"""
228
229
def block_until_active(self, timeout=None):
230
"""
231
Block until the media controller is active (media is loaded).
232
233
Parameters:
234
- timeout: float | None, Maximum time to wait. None for no timeout.
235
236
Raises:
237
- RequestTimeout: If timeout expires before becoming active
238
"""
239
240
@property
241
def status(self) -> MediaStatus:
242
"""Current media status"""
243
244
@property
245
def is_active(self) -> bool:
246
"""True if media controller is active"""
247
248
@property
249
def is_playing(self) -> bool:
250
"""True if media is currently playing"""
251
252
@property
253
def is_paused(self) -> bool:
254
"""True if media is currently paused"""
255
256
@property
257
def is_idle(self) -> bool:
258
"""True if media controller is idle"""
259
```
260
261
**Usage Example:**
262
263
```python
264
# Wait for media to load
265
try:
266
media_ctrl.block_until_active(timeout=10.0)
267
print("Media is loaded and ready")
268
except pychromecast.RequestTimeout:
269
print("Media did not load within timeout")
270
271
# Check status
272
if media_ctrl.is_playing:
273
print(f"Playing: {media_ctrl.status.title}")
274
print(f"Position: {media_ctrl.status.adjusted_current_time:.1f}s")
275
print(f"Duration: {media_ctrl.status.duration:.1f}s")
276
277
# Request status update
278
media_ctrl.update_status()
279
```
280
281
### Event Listeners
282
283
Register listeners for media status changes.
284
285
```python { .api }
286
def register_status_listener(self, listener):
287
"""
288
Register a listener for media status updates.
289
290
Parameters:
291
- listener: MediaStatusListener, Object with new_media_status method
292
"""
293
294
class MediaStatusListener:
295
"""Abstract listener for media status events"""
296
def new_media_status(self, status: MediaStatus) -> None: ...
297
298
class MediaStatus:
299
"""Media status information"""
300
def load_media_status(self, data: dict) -> None: ...
301
```
302
303
**Usage Example:**
304
305
```python
306
class MyMediaListener:
307
def new_media_status(self, status):
308
if status.player_state == pychromecast.MEDIA_PLAYER_STATE_PLAYING:
309
print(f"Now playing: {status.title}")
310
elif status.player_state == pychromecast.MEDIA_PLAYER_STATE_PAUSED:
311
print("Playback paused")
312
elif status.player_state == pychromecast.MEDIA_PLAYER_STATE_IDLE:
313
print("Playback idle")
314
315
# Register listener
316
listener = MyMediaListener()
317
media_ctrl.register_status_listener(listener)
318
```
319
320
## Types
321
322
```python { .api }
323
class MediaStatus:
324
"""Current media playback status"""
325
current_time: float
326
content_id: str | None
327
content_type: str | None
328
duration: float | None
329
stream_type: str
330
idle_reason: str | None
331
media_session_id: int | None
332
playback_rate: float
333
player_state: str
334
supported_media_commands: int
335
volume_level: float
336
volume_muted: bool
337
media_custom_data: dict
338
media_metadata: dict
339
subtitle_tracks: dict
340
current_subtitle_tracks: list
341
last_updated: datetime | None
342
343
@property
344
def adjusted_current_time(self) -> float | None:
345
"""Returns calculated current seek time accounting for playback rate"""
346
347
@property
348
def title(self) -> str | None:
349
"""Returns media title from metadata"""
350
351
class MediaImage:
352
"""Media image metadata container"""
353
url: str | None
354
height: int | None
355
width: int | None
356
357
class MediaStatusListener:
358
"""Abstract listener for media status events"""
359
def new_media_status(self, status: MediaStatus) -> None: ...
360
```
361
362
## Constants
363
364
```python { .api }
365
# Stream Types
366
STREAM_TYPE_UNKNOWN = "UNKNOWN"
367
STREAM_TYPE_BUFFERED = "BUFFERED"
368
STREAM_TYPE_LIVE = "LIVE"
369
370
# Media Player States
371
MEDIA_PLAYER_STATE_PLAYING = "PLAYING"
372
MEDIA_PLAYER_STATE_BUFFERING = "BUFFERING"
373
MEDIA_PLAYER_STATE_PAUSED = "PAUSED"
374
MEDIA_PLAYER_STATE_IDLE = "IDLE"
375
MEDIA_PLAYER_STATE_UNKNOWN = "UNKNOWN"
376
377
# Metadata Types
378
METADATA_TYPE_GENERIC = 0
379
METADATA_TYPE_MOVIE = 1
380
METADATA_TYPE_TVSHOW = 2
381
METADATA_TYPE_MUSICTRACK = 3
382
METADATA_TYPE_PHOTO = 4
383
384
# Command Support Flags (bitfield)
385
CMD_SUPPORT_PAUSE = 1
386
CMD_SUPPORT_SEEK = 2
387
CMD_SUPPORT_STREAM_VOLUME = 4
388
CMD_SUPPORT_STREAM_MUTE = 8
389
CMD_SUPPORT_SKIP_FORWARD = 16
390
CMD_SUPPORT_SKIP_BACKWARD = 32
391
CMD_SUPPORT_QUEUE_NEXT = 64
392
CMD_SUPPORT_QUEUE_PREV = 128
393
CMD_SUPPORT_QUEUE_SHUFFLE = 256
394
CMD_SUPPORT_SKIP_AD = 512
395
CMD_SUPPORT_QUEUE_REPEAT_ALL = 1024
396
CMD_SUPPORT_QUEUE_REPEAT_ONE = 2048
397
CMD_SUPPORT_EDIT_TRACKS = 4096
398
CMD_SUPPORT_PLAYBACK_RATE = 8192
399
CMD_SUPPORT_LIKE = 16384
400
CMD_SUPPORT_DISLIKE = 32768
401
CMD_SUPPORT_FOLLOW = 65536
402
CMD_SUPPORT_UNFOLLOW = 131072
403
CMD_SUPPORT_STREAM_TRANSFER = 262144
404
CMD_SUPPORT_ALL_BASIC_MEDIA = 12303
405
406
# Media Error Codes
407
MEDIA_PLAYER_ERROR_CODES = {
408
100: "MEDIA_UNKNOWN",
409
101: "MEDIA_ABORTED",
410
102: "MEDIA_DECODE",
411
103: "MEDIA_NETWORK",
412
104: "MEDIA_SRC_NOT_SUPPORTED",
413
# ... (many more error codes)
414
}
415
```