or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio-control.mdcore-playback.mddata-structures.mddiscovery-renderers.mdevent-system.mdindex.mdlow-level-functions.mdmedia-lists.mdvideo-control.md

discovery-renderers.mddocs/

0

# Media Discovery and Renderers

1

2

Network media discovery, renderer discovery for casting, and media library management capabilities. These features enable building applications that can discover network media sources and cast to remote devices.

3

4

## Capabilities

5

6

### Media Discovery

7

8

The MediaDiscoverer class provides network media discovery capabilities for finding media sources on the network.

9

10

```python { .api }

11

class MediaDiscoverer:

12

def __init__(self, instance, service_name):

13

"""Create a media discoverer.

14

15

Args:

16

instance (Instance): VLC instance

17

service_name (str): Name of discovery service

18

"""

19

...

20

21

def start(self):

22

"""Start the media discovery service.

23

24

Returns:

25

int: 0 on success, -1 on error

26

"""

27

...

28

29

def stop(self):

30

"""Stop the media discovery service."""

31

...

32

33

def media_list(self):

34

"""Get the media list discovered by this service.

35

36

Returns:

37

MediaList: List of discovered media items

38

"""

39

...

40

41

def event_manager(self):

42

"""Get the event manager for this media discoverer.

43

44

Returns:

45

EventManager: Event manager for discovery events

46

"""

47

...

48

49

def is_running(self):

50

"""Check if the discoverer is currently running.

51

52

Returns:

53

bool: True if running, False otherwise

54

"""

55

...

56

57

def release(self):

58

"""Release the media discoverer."""

59

...

60

```

61

62

### Media Discovery Services

63

64

Static methods for enumerating available discovery services.

65

66

```python { .api }

67

@staticmethod

68

def media_discoverer_list_get(instance, category):

69

"""Get list of available media discovery services.

70

71

Args:

72

instance (Instance): VLC instance

73

category (MediaDiscovererCategory): Category of services to list

74

75

Returns:

76

list: List of (service_name, long_name) tuples

77

"""

78

...

79

80

@staticmethod

81

def media_discoverer_list_release(services_list):

82

"""Release a media discoverer services list.

83

84

Args:

85

services_list (list): List returned by media_discoverer_list_get

86

"""

87

...

88

```

89

90

### Renderer Discovery

91

92

The RendererDiscoverer class provides discovery of renderers (casting targets) on the network.

93

94

```python { .api }

95

class RendererDiscoverer:

96

def __init__(self, instance, service_name):

97

"""Create a renderer discoverer.

98

99

Args:

100

instance (Instance): VLC instance

101

service_name (str): Name of renderer discovery service

102

"""

103

...

104

105

def start(self):

106

"""Start the renderer discovery service.

107

108

Returns:

109

int: 0 on success, -1 on error

110

"""

111

...

112

113

def stop(self):

114

"""Stop the renderer discovery service."""

115

...

116

117

def event_manager(self):

118

"""Get the event manager for this renderer discoverer.

119

120

Returns:

121

EventManager: Event manager for renderer events

122

"""

123

...

124

125

def release(self):

126

"""Release the renderer discoverer."""

127

...

128

```

129

130

### Renderer Management

131

132

The Renderer class represents discovered casting targets.

133

134

```python { .api }

135

class Renderer:

136

def name(self):

137

"""Get the renderer name.

138

139

Returns:

140

str: Human-readable name of the renderer

141

"""

142

...

143

144

def type(self):

145

"""Get the renderer type.

146

147

Returns:

148

str: Type of renderer (e.g., "chromecast", "upnp")

149

"""

150

...

151

152

def icon_uri(self):

153

"""Get the renderer icon URI.

154

155

Returns:

156

str: URI to renderer icon or None

157

"""

158

...

159

160

def flags(self):

161

"""Get renderer capability flags.

162

163

Returns:

164

int: Bitfield of renderer capabilities

165

"""

166

...

167

168

def can_render_audio(self):

169

"""Check if renderer can handle audio.

170

171

Note: Not directly available - check flags() & RendererFlags.Audio

172

173

Returns:

174

bool: True if can render audio

175

"""

176

return (self.flags() & vlc.RendererFlags.Audio) != 0

177

178

def can_render_video(self):

179

"""Check if renderer can handle video.

180

181

Note: Not directly available - check flags() & RendererFlags.Video

182

183

Returns:

184

bool: True if can render video

185

"""

186

return (self.flags() & vlc.RendererFlags.Video) != 0

187

188

def hold(self):

189

"""Hold a reference to this renderer.

190

191

Returns:

192

Renderer: This renderer instance

193

"""

194

...

195

196

def release(self):

197

"""Release this renderer."""

198

...

199

```

200

201

### Renderer Discovery Services

202

203

Static methods for managing renderer discovery services.

204

205

```python { .api }

206

@staticmethod

207

def renderer_discoverer_list_get(instance):

208

"""Get list of available renderer discovery services.

209

210

Args:

211

instance (Instance): VLC instance

212

213

Returns:

214

list: List of (service_name, long_name) tuples

215

"""

216

...

217

218

@staticmethod

219

def renderer_discoverer_list_release(services_list):

220

"""Release a renderer discoverer services list.

221

222

Args:

223

services_list (list): List returned by renderer_discoverer_list_get

224

"""

225

...

226

```

227

228

### Media Player Renderer Integration

229

230

Methods on MediaPlayer for using discovered renderers.

231

232

```python { .api }

233

# Renderer methods on MediaPlayer

234

def set_renderer(self, renderer):

235

"""Set a renderer for casting output.

236

237

Args:

238

renderer (Renderer): Renderer to cast to, or None to stop casting

239

240

Returns:

241

int: 0 on success, -1 on error

242

"""

243

...

244

```

245

246

### Discovery Categories

247

248

Enumeration for media discovery service categories.

249

250

```python { .api }

251

class MediaDiscovererCategory:

252

"""Media discovery service categories."""

253

Devices = 0

254

Lan = 1

255

Podcasts = 2

256

LocalDirs = 3

257

```

258

259

### Discovery Event Types

260

261

Event types for discovery operations.

262

263

```python { .api }

264

class EventType:

265

# Media Discoverer Events

266

MediaDiscovererStarted = 0x500

267

MediaDiscovererEnded = 0x501

268

269

# Renderer Discoverer Events

270

RendererDiscovererItemAdded = 0x700

271

RendererDiscovererItemDeleted = 0x701

272

```

273

274

### Renderer Flags

275

276

Capability flags for renderers.

277

278

```python { .api }

279

class RendererFlags:

280

"""Renderer capability flags."""

281

Audio = 0x01

282

Video = 0x02

283

284

# Usage: Check renderer capabilities with bitwise operations

285

# has_audio = (renderer.flags() & vlc.RendererFlags.Audio) != 0

286

# has_video = (renderer.flags() & vlc.RendererFlags.Video) != 0

287

```

288

289

## Usage Examples

290

291

### Media Discovery Basic Usage

292

293

```python

294

import vlc

295

import time

296

297

def on_discoverer_started(event):

298

print("Media discoverer started")

299

300

def on_discoverer_ended(event):

301

print("Media discoverer ended")

302

303

# Create instance and list available discovery services

304

instance = vlc.Instance()

305

services = vlc.MediaDiscoverer.media_discoverer_list_get(

306

instance, vlc.MediaDiscovererCategory.Lan

307

)

308

309

print("Available LAN discovery services:")

310

for service_name, long_name in services:

311

print(f" {service_name}: {long_name}")

312

313

if services:

314

# Create discoverer for first service

315

service_name = services[0][0]

316

discoverer = vlc.MediaDiscoverer(instance, service_name)

317

318

# Attach events

319

em = discoverer.event_manager()

320

em.event_attach(vlc.EventType.MediaDiscovererStarted, on_discoverer_started)

321

em.event_attach(vlc.EventType.MediaDiscovererEnded, on_discoverer_ended)

322

323

# Start discovery

324

print(f"Starting discovery with service: {service_name}")

325

discoverer.start()

326

327

# Wait for discovery

328

time.sleep(5)

329

330

# Get discovered media

331

media_list = discoverer.media_list()

332

if media_list:

333

count = media_list.count()

334

print(f"Discovered {count} media items:")

335

336

for i in range(count):

337

media = media_list.item_at_index(i)

338

if media:

339

mrl = media.get_mrl()

340

print(f" {i}: {mrl}")

341

342

# Stop discovery

343

discoverer.stop()

344

discoverer.release()

345

346

# Clean up

347

vlc.MediaDiscoverer.media_discoverer_list_release(services)

348

```

349

350

### Comprehensive Media Discovery

351

352

```python

353

import vlc

354

import time

355

356

class MediaDiscoveryManager:

357

def __init__(self, instance):

358

self.instance = instance

359

self.discoverers = []

360

self.discovered_media = {}

361

362

def discover_all_categories(self):

363

"""Start discovery for all available categories."""

364

categories = [

365

vlc.MediaDiscovererCategory.Devices,

366

vlc.MediaDiscovererCategory.Lan,

367

vlc.MediaDiscovererCategory.Podcasts,

368

vlc.MediaDiscovererCategory.LocalDirs

369

]

370

371

category_names = ["Devices", "LAN", "Podcasts", "Local Directories"]

372

373

for category, name in zip(categories, category_names):

374

print(f"\n=== {name} Discovery ===")

375

services = vlc.MediaDiscoverer.media_discoverer_list_get(

376

self.instance, category

377

)

378

379

if not services:

380

print(f"No {name.lower()} discovery services available")

381

continue

382

383

for service_name, long_name in services:

384

print(f"Starting {service_name}: {long_name}")

385

386

try:

387

discoverer = vlc.MediaDiscoverer(self.instance, service_name)

388

em = discoverer.event_manager()

389

390

# Setup events with service context

391

em.event_attach(

392

vlc.EventType.MediaDiscovererStarted,

393

lambda e, sn=service_name: self.on_started(e, sn)

394

)

395

em.event_attach(

396

vlc.EventType.MediaDiscovererEnded,

397

lambda e, sn=service_name: self.on_ended(e, sn)

398

)

399

400

discoverer.start()

401

self.discoverers.append((service_name, discoverer))

402

403

except Exception as e:

404

print(f"Failed to start {service_name}: {e}")

405

406

vlc.MediaDiscoverer.media_discoverer_list_release(services)

407

408

def on_started(self, event, service_name):

409

print(f"βœ“ {service_name} discovery started")

410

411

def on_ended(self, event, service_name):

412

print(f"βœ— {service_name} discovery ended")

413

414

def collect_discovered_media(self):

415

"""Collect all discovered media from active discoverers."""

416

print("\n=== Discovered Media ===")

417

418

for service_name, discoverer in self.discoverers:

419

if discoverer.is_running():

420

media_list = discoverer.media_list()

421

if media_list:

422

count = media_list.count()

423

if count > 0:

424

print(f"\n{service_name} ({count} items):")

425

items = []

426

427

for i in range(count):

428

media = media_list.item_at_index(i)

429

if media:

430

mrl = media.get_mrl()

431

items.append(mrl)

432

print(f" {i+1}: {mrl}")

433

434

self.discovered_media[service_name] = items

435

436

def stop_all(self):

437

"""Stop all discoverers."""

438

print("\nStopping all discoverers...")

439

for service_name, discoverer in self.discoverers:

440

discoverer.stop()

441

discoverer.release()

442

self.discoverers.clear()

443

444

# Usage

445

instance = vlc.Instance()

446

manager = MediaDiscoveryManager(instance)

447

448

# Start discovery for all categories

449

manager.discover_all_categories()

450

451

# Wait for discovery

452

print("\nWaiting for discovery to complete...")

453

time.sleep(10)

454

455

# Collect results

456

manager.collect_discovered_media()

457

458

# Stop all discoverers

459

manager.stop_all()

460

461

# Summary

462

print(f"\nDiscovered media in {len(manager.discovered_media)} services:")

463

for service, items in manager.discovered_media.items():

464

print(f" {service}: {len(items)} items")

465

```

466

467

### Renderer Discovery and Casting

468

469

```python

470

import vlc

471

import time

472

473

def on_renderer_added(event):

474

"""Handle renderer discovered."""

475

renderer = event.u.item

476

print(f"βœ“ Renderer discovered: {renderer.name()} ({renderer.type()})")

477

478

def on_renderer_deleted(event):

479

"""Handle renderer removed."""

480

renderer = event.u.item

481

print(f"βœ— Renderer removed: {renderer.name()}")

482

483

# Create instance and list renderer discovery services

484

instance = vlc.Instance()

485

services = vlc.RendererDiscoverer.renderer_discoverer_list_get(instance)

486

487

print("Available renderer discovery services:")

488

for service_name, long_name in services:

489

print(f" {service_name}: {long_name}")

490

491

discovered_renderers = []

492

493

if services:

494

# Start discovery for all renderer services

495

discoverers = []

496

497

for service_name, long_name in services:

498

try:

499

print(f"Starting {service_name} renderer discovery...")

500

rd = vlc.RendererDiscoverer(instance, service_name)

501

502

# Attach events

503

em = rd.event_manager()

504

em.event_attach(vlc.EventType.RendererDiscovererItemAdded, on_renderer_added)

505

em.event_attach(vlc.EventType.RendererDiscovererItemDeleted, on_renderer_deleted)

506

507

rd.start()

508

discoverers.append(rd)

509

510

except Exception as e:

511

print(f"Failed to start {service_name}: {e}")

512

513

# Wait for renderer discovery

514

print("\nDiscovering renderers...")

515

time.sleep(10)

516

517

# Create a media player for casting test

518

player = vlc.MediaPlayer('/path/to/video.mp4')

519

520

# Example: Cast to first discovered renderer (if any)

521

# Note: This is conceptual - actual renderer objects would come from events

522

print("\nTesting casting (conceptual example):")

523

print("To cast to a renderer, you would:")

524

print("1. Get renderer from discovery events")

525

print("2. Use player.set_renderer(renderer)")

526

print("3. Start playback with player.play()")

527

528

# Stop all discoverers

529

print("\nStopping renderer discovery...")

530

for rd in discoverers:

531

rd.stop()

532

rd.release()

533

534

# Clean up

535

vlc.RendererDiscoverer.renderer_discoverer_list_release(services)

536

```

537

538

### Advanced Renderer Discovery with Event Handling

539

540

```python

541

import vlc

542

import time

543

544

class RendererManager:

545

def __init__(self, instance):

546

self.instance = instance

547

self.discoverers = []

548

self.available_renderers = {}

549

550

def start_discovery(self):

551

"""Start discovery for all available renderer services."""

552

services = vlc.RendererDiscoverer.renderer_discoverer_list_get(self.instance)

553

554

print("Starting renderer discovery...")

555

for service_name, long_name in services:

556

try:

557

rd = vlc.RendererDiscoverer(self.instance, service_name)

558

em = rd.event_manager()

559

560

# Bind events with service context

561

em.event_attach(

562

vlc.EventType.RendererDiscovererItemAdded,

563

lambda e, sn=service_name: self.on_renderer_added(e, sn)

564

)

565

em.event_attach(

566

vlc.EventType.RendererDiscovererItemDeleted,

567

lambda e, sn=service_name: self.on_renderer_deleted(e, sn)

568

)

569

570

rd.start()

571

self.discoverers.append((service_name, rd))

572

print(f" Started {service_name}: {long_name}")

573

574

except Exception as e:

575

print(f" Failed to start {service_name}: {e}")

576

577

vlc.RendererDiscoverer.renderer_discoverer_list_release(services)

578

579

def on_renderer_added(self, event, service_name):

580

"""Handle renderer discovered."""

581

renderer = event.u.item

582

renderer_id = f"{service_name}:{renderer.name()}"

583

584

# Store renderer info

585

flags = renderer.flags()

586

self.available_renderers[renderer_id] = {

587

'name': renderer.name(),

588

'type': renderer.type(),

589

'service': service_name,

590

'can_audio': (flags & vlc.RendererFlags.Audio) != 0,

591

'can_video': (flags & vlc.RendererFlags.Video) != 0,

592

'icon_uri': renderer.icon_uri(),

593

'renderer_obj': renderer.hold() # Keep reference

594

}

595

596

print(f"πŸ“Ί Found renderer: {renderer.name()}")

597

print(f" Type: {renderer.type()}")

598

print(f" Audio: {'βœ“' if (flags & vlc.RendererFlags.Audio) else 'βœ—'}")

599

print(f" Video: {'βœ“' if (flags & vlc.RendererFlags.Video) else 'βœ—'}")

600

if renderer.icon_uri():

601

print(f" Icon: {renderer.icon_uri()}")

602

603

def on_renderer_deleted(self, event, service_name):

604

"""Handle renderer removed."""

605

renderer = event.u.item

606

renderer_id = f"{service_name}:{renderer.name()}"

607

608

if renderer_id in self.available_renderers:

609

# Release held reference

610

self.available_renderers[renderer_id]['renderer_obj'].release()

611

del self.available_renderers[renderer_id]

612

print(f"πŸ“Ί Renderer removed: {renderer.name()}")

613

614

def list_renderers(self):

615

"""List all currently available renderers."""

616

print(f"\nAvailable renderers ({len(self.available_renderers)}):")

617

for renderer_id, info in self.available_renderers.items():

618

print(f" {renderer_id}")

619

print(f" Type: {info['type']}")

620

print(f" Capabilities: Audio={info['can_audio']}, Video={info['can_video']}")

621

622

def cast_to_renderer(self, renderer_id, media_path):

623

"""Cast media to a specific renderer."""

624

if renderer_id not in self.available_renderers:

625

print(f"Renderer {renderer_id} not available")

626

return None

627

628

info = self.available_renderers[renderer_id]

629

renderer_obj = info['renderer_obj']

630

631

print(f"Casting to {info['name']}...")

632

633

# Create player and set renderer

634

player = vlc.MediaPlayer(media_path)

635

result = player.set_renderer(renderer_obj)

636

637

if result == 0:

638

print("βœ“ Renderer set successfully")

639

player.play()

640

return player

641

else:

642

print("βœ— Failed to set renderer")

643

return None

644

645

def stop_discovery(self):

646

"""Stop all renderer discovery."""

647

print("Stopping renderer discovery...")

648

649

# Release all held renderer references

650

for info in self.available_renderers.values():

651

info['renderer_obj'].release()

652

self.available_renderers.clear()

653

654

# Stop and release discoverers

655

for service_name, rd in self.discoverers:

656

rd.stop()

657

rd.release()

658

self.discoverers.clear()

659

660

# Usage example

661

instance = vlc.Instance()

662

renderer_mgr = RendererManager(instance)

663

664

# Start discovery

665

renderer_mgr.start_discovery()

666

667

# Wait for discovery

668

print("Waiting for renderer discovery...")

669

time.sleep(15)

670

671

# List found renderers

672

renderer_mgr.list_renderers()

673

674

# Example casting (if renderers found)

675

if renderer_mgr.available_renderers:

676

first_renderer = list(renderer_mgr.available_renderers.keys())[0]

677

print(f"\nAttempting to cast to: {first_renderer}")

678

679

# Cast to first available renderer

680

player = renderer_mgr.cast_to_renderer(first_renderer, '/path/to/video.mp4')

681

682

if player:

683

print("Casting for 10 seconds...")

684

time.sleep(10)

685

player.stop()

686

687

# Stop casting by clearing renderer

688

player.set_renderer(None)

689

print("Stopped casting")

690

691

# Clean up

692

renderer_mgr.stop_discovery()

693

```

694

695

### Media Discovery with Playback

696

697

```python

698

import vlc

699

import time

700

701

# Discover and play network media

702

instance = vlc.Instance()

703

704

# Get UPnP discovery service

705

services = vlc.MediaDiscoverer.media_discoverer_list_get(

706

instance, vlc.MediaDiscovererCategory.Lan

707

)

708

709

upnp_service = None

710

for service_name, long_name in services:

711

if 'upnp' in service_name.lower():

712

upnp_service = service_name

713

break

714

715

if upnp_service:

716

print(f"Using UPnP discovery service: {upnp_service}")

717

718

# Create discoverer

719

discoverer = vlc.MediaDiscoverer(instance, upnp_service)

720

discoverer.start()

721

722

# Wait for discovery

723

print("Discovering UPnP media servers...")

724

time.sleep(8)

725

726

# Get discovered media

727

media_list = discoverer.media_list()

728

if media_list and media_list.count() > 0:

729

print(f"Found {media_list.count()} UPnP media sources")

730

731

# Play first discovered media

732

first_media = media_list.item_at_index(0)

733

if first_media:

734

print(f"Playing: {first_media.get_mrl()}")

735

736

player = vlc.MediaPlayer()

737

player.set_media(first_media)

738

player.play()

739

740

# Play for a while

741

time.sleep(30)

742

player.stop()

743

else:

744

print("No UPnP media servers found")

745

746

# Clean up

747

discoverer.stop()

748

discoverer.release()

749

else:

750

print("No UPnP discovery service available")

751

752

vlc.MediaDiscoverer.media_discoverer_list_release(services)

753

```