or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio-system.mdbackend-system.mdconfiguration.mdcore-controllers.mdextension-system.mdindex.mdmodels.md

core-controllers.mddocs/

0

# Core Controllers

1

2

Mopidy's core system provides centralized business logic controllers for managing all aspects of music playback, library access, playlist management, and audio control. These controllers form the main API surface for interacting with Mopidy programmatically.

3

4

## Capabilities

5

6

### Core Actor System

7

8

The main Core actor coordinates all system components and provides the primary interface for Mopidy functionality.

9

10

```python { .api }

11

class Core(pykka.ThreadingActor):

12

"""

13

Main core actor that coordinates all Mopidy functionality.

14

15

Parameters:

16

- config: Mopidy configuration

17

- mixer: Audio mixer instance

18

- backends: List of configured backends

19

- audio: Audio actor instance

20

"""

21

def __init__(self, config, mixer, backends, audio): ...

22

23

# Controller properties

24

@property

25

def playback(self) -> PlaybackController: ...

26

27

@property

28

def library(self) -> LibraryController: ...

29

30

@property

31

def tracklist(self) -> TracklistController: ...

32

33

@property

34

def playlists(self) -> PlaylistsController: ...

35

36

@property

37

def mixer(self) -> MixerController: ...

38

39

@property

40

def history(self) -> HistoryController: ...

41

```

42

43

### Playback Control

44

45

Comprehensive playback control including play/pause/stop, seeking, volume, and playback state management.

46

47

```python { .api }

48

class PlaybackController:

49

"""Controls music playback including play, pause, stop, and seeking."""

50

51

def play(self, tl_track=None, tlid=None):

52

"""

53

Start playback.

54

55

Parameters:

56

- tl_track (TlTrack, optional): Track to play (deprecated, use tlid)

57

- tlid (int, optional): TLID of track to play, or None for current

58

59

Returns:

60

- TlTrack or None: The track that was played

61

"""

62

...

63

64

def pause(self):

65

"""

66

Pause playback.

67

68

Returns:

69

- bool: True if successful

70

"""

71

...

72

73

def stop(self):

74

"""

75

Stop playback and clear current track.

76

77

Returns:

78

- bool: True if successful

79

"""

80

...

81

82

def resume(self):

83

"""

84

Resume playback from paused state.

85

86

Returns:

87

- bool: True if successful

88

"""

89

...

90

91

def seek(self, time_position):

92

"""

93

Seek to specific position in current track.

94

95

Parameters:

96

- time_position (int): Position in milliseconds

97

98

Returns:

99

- bool: True if successful

100

"""

101

...

102

103

def get_time_position(self):

104

"""

105

Get current playback position.

106

107

Returns:

108

- int: Position in milliseconds

109

"""

110

...

111

112

def get_state(self):

113

"""

114

Get current playback state.

115

116

Returns:

117

- PlaybackState: Current state (playing, paused, stopped)

118

"""

119

...

120

121

def set_state(self, new_state):

122

"""

123

Set the playback state.

124

125

Parameters:

126

- new_state (PlaybackState): Must be PLAYING, PAUSED, or STOPPED

127

128

Note: This is primarily for internal use and testing

129

"""

130

...

131

132

def next(self):

133

"""

134

Change to next track in tracklist.

135

136

Returns:

137

- TlTrack or None: Next track that was switched to

138

"""

139

...

140

141

def previous(self):

142

"""

143

Change to previous track in tracklist.

144

145

Returns:

146

- TlTrack or None: Previous track that was switched to

147

"""

148

...

149

150

def get_current_tl_track(self):

151

"""

152

Get currently playing or paused track.

153

154

Returns:

155

- TlTrack or None: Current track

156

"""

157

...

158

159

def get_current_track(self):

160

"""

161

Get currently playing or paused track.

162

163

Returns:

164

- Track or None: Current track

165

"""

166

...

167

168

def get_current_tlid(self):

169

"""

170

Get TLID of currently playing or paused track.

171

172

Returns:

173

- int or None: Current track TLID

174

"""

175

...

176

177

def get_stream_title(self):

178

"""

179

Get stream title for radio streams.

180

181

Returns:

182

- str or None: Stream title if available

183

"""

184

...

185

186

class PlaybackState:

187

"""Playback state constants."""

188

STOPPED = "stopped"

189

PLAYING = "playing"

190

PAUSED = "paused"

191

```

192

193

Usage example:

194

```python

195

from mopidy.core import Core

196

197

# Assume core is a Core instance

198

core.playback.play() # Start playback

199

core.playback.pause() # Pause

200

core.playback.seek(30000) # Seek to 30 seconds

201

state = core.playback.get_state() # Get current state

202

```

203

204

### Library Access

205

206

Library browsing, searching, and track lookup across all configured backends.

207

208

```python { .api }

209

class LibraryController:

210

"""Provides library browsing and searching across backends."""

211

212

def browse(self, uri, **kwargs):

213

"""

214

Browse library at given URI.

215

216

Parameters:

217

- uri (str): URI to browse

218

- **kwargs: Backend-specific options

219

220

Returns:

221

- list[Ref]: List of references at the URI

222

"""

223

...

224

225

def search(self, query=None, uris=None, exact=False):

226

"""

227

Search library across backends.

228

229

Parameters:

230

- query (dict, optional): Search query by field

231

- uris (list[str], optional): URIs to search within

232

- exact (bool): Whether to match exactly

233

234

Returns:

235

- list[SearchResult]: Search results from backends

236

"""

237

...

238

239

def lookup(self, uris=None):

240

"""

241

Lookup tracks by URI.

242

243

Parameters:

244

- uris (list[str]): URIs to lookup

245

246

Returns:

247

- dict[str, list[Track]]: Mapping of URI to tracks

248

"""

249

...

250

251

def refresh(self, uri=None):

252

"""

253

Refresh library cache.

254

255

Parameters:

256

- uri (str, optional): Specific URI to refresh

257

258

Returns:

259

- bool: True if successful

260

"""

261

...

262

263

def get_distinct(self, field, query=None):

264

"""

265

Get distinct values for a field.

266

267

Parameters:

268

- field (str): Field name ('artist', 'album', etc.)

269

- query (dict, optional): Query to filter by

270

271

Returns:

272

- set[str]: Distinct values

273

"""

274

...

275

276

def get_images(self, uris):

277

"""

278

Get images for given URIs.

279

280

Parameters:

281

- uris (list[str]): URIs to get images for

282

283

Returns:

284

- dict[str, list[Image]]: Mapping of URI to images

285

"""

286

...

287

```

288

289

Usage example:

290

```python

291

# Browse root directory

292

refs = core.library.browse("file:///")

293

294

# Search for tracks

295

results = core.library.search({"artist": ["Beatles"], "album": ["Abbey Road"]})

296

297

# Lookup specific tracks

298

tracks = core.library.lookup(["spotify:track:123", "local:track:song.mp3"])

299

```

300

301

### Tracklist Management

302

303

Manage the current tracklist including adding, removing, and reordering tracks.

304

305

```python { .api }

306

class TracklistController:

307

"""Manages the current tracklist of tracks to be played."""

308

309

def add(self, tracks=None, at_position=None, uris=None):

310

"""

311

Add tracks to tracklist.

312

313

Parameters:

314

- tracks (list[Track], optional): Tracks to add

315

- at_position (int, optional): Position to insert at

316

- uris (list[str], optional): URIs to add (alternative to tracks)

317

318

Returns:

319

- list[TlTrack]: Added tracklist tracks

320

"""

321

...

322

323

def remove(self, criteria):

324

"""

325

Remove tracks from tracklist.

326

327

Parameters:

328

- criteria (dict): Removal criteria (tlid, uri, etc.)

329

330

Returns:

331

- list[TlTrack]: Removed tracks

332

"""

333

...

334

335

def clear(self):

336

"""

337

Clear all tracks from tracklist.

338

339

Returns:

340

- bool: True if successful

341

"""

342

...

343

344

def move(self, start, end, to_position):

345

"""

346

Move tracks within tracklist.

347

348

Parameters:

349

- start (int): Start position

350

- end (int): End position

351

- to_position (int): Destination position

352

353

Returns:

354

- bool: True if successful

355

"""

356

...

357

358

def shuffle(self, start=None, end=None):

359

"""

360

Shuffle tracks in tracklist.

361

362

Parameters:

363

- start (int, optional): Start position

364

- end (int, optional): End position

365

366

Returns:

367

- bool: True if successful

368

"""

369

...

370

371

def get_tl_tracks(self):

372

"""

373

Get all tracklist tracks.

374

375

Returns:

376

- list[TlTrack]: All tracklist tracks

377

"""

378

...

379

380

def get_tracks(self):

381

"""

382

Get all tracks.

383

384

Returns:

385

- list[Track]: All tracks

386

"""

387

...

388

389

def get_length(self):

390

"""

391

Get tracklist length.

392

393

Returns:

394

- int: Number of tracks

395

"""

396

...

397

398

def get_version(self):

399

"""

400

Get tracklist version (increments on changes).

401

402

Returns:

403

- int: Version number

404

"""

405

...

406

407

def index(self, tl_track=None, tlid=None):

408

"""

409

Get index of tracklist track.

410

411

Parameters:

412

- tl_track (TlTrack, optional): Track to find

413

- tlid (int, optional): TLID to find (alternative to tl_track)

414

415

Returns:

416

- int or None: Index of track

417

"""

418

...

419

420

def filter(self, criteria):

421

"""

422

Filter the tracklist by the given criteria.

423

424

Each rule in the criteria consists of a model field and a list of

425

values to compare it against. If the model field matches any of the

426

values, it may be returned.

427

428

Parameters:

429

- criteria (dict): Filter criteria (uri, name, etc.)

430

431

Returns:

432

- list[TlTrack]: Filtered tracks

433

"""

434

...

435

436

def get_consume(self):

437

"""

438

Get consume mode status.

439

440

Returns:

441

- bool: True if consume mode is enabled

442

"""

443

...

444

445

def set_consume(self, value):

446

"""

447

Set consume mode.

448

449

Parameters:

450

- value (bool): Enable/disable consume mode

451

452

Returns:

453

- bool: True if successful

454

"""

455

...

456

457

def get_random(self):

458

"""

459

Get random mode status.

460

461

Returns:

462

- bool: True if random mode is enabled

463

"""

464

...

465

466

def set_random(self, value):

467

"""

468

Set random mode.

469

470

Parameters:

471

- value (bool): Enable/disable random mode

472

473

Returns:

474

- bool: True if successful

475

"""

476

...

477

478

def get_repeat(self):

479

"""

480

Get repeat mode status.

481

482

Returns:

483

- bool: True if repeat mode is enabled

484

"""

485

...

486

487

def set_repeat(self, value):

488

"""

489

Set repeat mode.

490

491

Parameters:

492

- value (bool): Enable/disable repeat mode

493

494

Returns:

495

- bool: True if successful

496

"""

497

...

498

499

def get_single(self):

500

"""

501

Get single mode status.

502

503

Returns:

504

- bool: True if single mode is enabled

505

"""

506

...

507

508

def set_single(self, value):

509

"""

510

Set single mode.

511

512

Parameters:

513

- value (bool): Enable/disable single mode

514

515

Returns:

516

- bool: True if successful

517

"""

518

...

519

520

def get_eot_tlid(self):

521

"""

522

The TLID of the track that will be played after the current track.

523

524

Not necessarily the same TLID as returned by get_next_tlid.

525

526

Returns:

527

- int or None: TLID of end-of-track track

528

"""

529

...

530

531

def eot_track(self, tl_track):

532

"""

533

The track that will be played after the given track.

534

535

Not necessarily the same track as next_track.

536

537

Note: This method is deprecated in favor of get_eot_tlid.

538

539

Parameters:

540

- tl_track (TlTrack or None): The reference track

541

542

Returns:

543

- TlTrack or None: End-of-track track

544

"""

545

...

546

547

def get_next_tlid(self):

548

"""

549

The TLID of the track that will be played if calling next().

550

551

For normal playback this is the next track in the tracklist. If repeat

552

is enabled the next track can loop around the tracklist. When random is

553

enabled this should be a random track.

554

555

Returns:

556

- int or None: TLID of next track

557

"""

558

...

559

560

def next_track(self, tl_track):

561

"""

562

The track that will be played if calling next().

563

564

Note: This method is deprecated in favor of get_next_tlid.

565

566

Parameters:

567

- tl_track (TlTrack or None): The reference track

568

569

Returns:

570

- TlTrack or None: Next track

571

"""

572

...

573

574

def get_previous_tlid(self):

575

"""

576

Returns the TLID of the track that will be played if calling previous().

577

578

For normal playback this is the previous track in the tracklist. If

579

random and/or consume is enabled it should return the current track.

580

581

Returns:

582

- int or None: TLID of previous track

583

"""

584

...

585

586

def previous_track(self, tl_track):

587

"""

588

Returns the track that will be played if calling previous().

589

590

Note: This method is deprecated in favor of get_previous_tlid.

591

592

Parameters:

593

- tl_track (TlTrack or None): The reference track

594

595

Returns:

596

- TlTrack or None: Previous track

597

"""

598

...

599

600

def slice(self, start, end):

601

"""

602

Get slice of tracklist.

603

604

Parameters:

605

- start (int): Start index

606

- end (int): End index

607

608

Returns:

609

- list[TlTrack]: Slice of tracks

610

"""

611

...

612

613

# Playback options

614

def get_consume(self):

615

"""Get consume mode state."""

616

...

617

618

def set_consume(self, value):

619

"""Set consume mode."""

620

...

621

622

def get_random(self):

623

"""Get random mode state."""

624

...

625

626

def set_random(self, value):

627

"""Set random mode."""

628

...

629

630

def get_repeat(self):

631

"""Get repeat mode state."""

632

...

633

634

def set_repeat(self, value):

635

"""Set repeat mode."""

636

...

637

638

def get_single(self):

639

"""Get single mode state."""

640

...

641

642

def set_single(self, value):

643

"""Set single mode."""

644

...

645

```

646

647

Usage example:

648

```python

649

# Add tracks to tracklist

650

tl_tracks = core.tracklist.add([track1, track2, track3])

651

652

# Set playback modes

653

core.tracklist.set_random(True)

654

core.tracklist.set_repeat(True)

655

656

# Get current tracklist

657

all_tracks = core.tracklist.get_tl_tracks()

658

```

659

660

### Playlist Management

661

662

Manage stored playlists including creation, modification, and deletion across backends.

663

664

```python { .api }

665

class PlaylistsController:

666

"""Manages stored playlists across backends."""

667

668

def as_list(self):

669

"""

670

Get all playlists.

671

672

Returns:

673

- list[Playlist]: All available playlists

674

"""

675

...

676

677

def get_items(self, uri):

678

"""

679

Get playlist items.

680

681

Parameters:

682

- uri (str): Playlist URI

683

684

Returns:

685

- list[Ref]: Playlist items

686

"""

687

...

688

689

def create(self, name, uri_scheme=None):

690

"""

691

Create new playlist.

692

693

Parameters:

694

- name (str): Playlist name

695

- uri_scheme (str, optional): URI scheme to use

696

697

Returns:

698

- Playlist or None: Created playlist

699

"""

700

...

701

702

def save(self, playlist):

703

"""

704

Save playlist changes.

705

706

Parameters:

707

- playlist (Playlist): Playlist to save

708

709

Returns:

710

- Playlist or None: Saved playlist

711

"""

712

...

713

714

def delete(self, uri):

715

"""

716

Delete playlist.

717

718

Parameters:

719

- uri (str): Playlist URI

720

721

Returns:

722

- bool: True if successful

723

"""

724

...

725

726

def lookup(self, uri):

727

"""

728

Lookup playlist by URI.

729

730

Parameters:

731

- uri (str): Playlist URI

732

733

Returns:

734

- Playlist or None: Found playlist

735

"""

736

...

737

738

def refresh(self, uri_scheme=None):

739

"""

740

Refresh playlists cache.

741

742

Parameters:

743

- uri_scheme (str, optional): Specific scheme to refresh

744

745

Returns:

746

- bool: True if successful

747

"""

748

...

749

750

def get_uri_schemes(self):

751

"""

752

Get available playlist URI schemes.

753

754

Returns:

755

- list[str]: Available URI schemes

756

"""

757

...

758

```

759

760

Usage example:

761

```python

762

# List all playlists

763

playlists = core.playlists.as_list()

764

765

# Create new playlist

766

playlist = core.playlists.create("My New Playlist")

767

768

# Add tracks and save

769

updated_playlist = playlist.replace(tracks=(track1, track2))

770

core.playlists.save(updated_playlist)

771

```

772

773

### Audio Mixer Control

774

775

Control audio volume and muting across the system.

776

777

```python { .api }

778

class MixerController:

779

"""Controls audio volume and muting."""

780

781

def get_volume(self):

782

"""

783

Get current volume level.

784

785

Returns:

786

- int or None: Volume level (0-100)

787

"""

788

...

789

790

def set_volume(self, volume):

791

"""

792

Set volume level.

793

794

Parameters:

795

- volume (int): Volume level (0-100)

796

797

Returns:

798

- bool: True if successful

799

"""

800

...

801

802

def get_mute(self):

803

"""

804

Get mute state.

805

806

Returns:

807

- bool or None: True if muted

808

"""

809

...

810

811

def set_mute(self, mute):

812

"""

813

Set mute state.

814

815

Parameters:

816

- mute (bool): True to mute

817

818

Returns:

819

- bool: True if successful

820

"""

821

...

822

```

823

824

### Playback History

825

826

Track and manage playback history for recently played tracks.

827

828

```python { .api }

829

class HistoryController:

830

"""Manages playback history of recently played tracks."""

831

832

def get_length(self):

833

"""

834

Get history length.

835

836

Returns:

837

- int: Number of history entries

838

"""

839

...

840

841

def get_history(self):

842

"""

843

Get playback history.

844

845

Returns:

846

- list[tuple[int, Ref]]: History entries (timestamp, track_ref)

847

"""

848

...

849

```

850

851

### Event Listener

852

853

Base class for receiving notifications about system events and state changes.

854

855

```python { .api }

856

class CoreListener:

857

"""Base class for receiving core system events."""

858

859

def track_playback_paused(self, tl_track, time_position):

860

"""Called when track playback is paused."""

861

...

862

863

def track_playback_resumed(self, tl_track, time_position):

864

"""Called when track playback is resumed."""

865

...

866

867

def track_playback_started(self, tl_track):

868

"""Called when track playback starts."""

869

...

870

871

def track_playback_ended(self, tl_track, time_position):

872

"""Called when track playback ends."""

873

...

874

875

def playback_state_changed(self, old_state, new_state):

876

"""Called when playback state changes."""

877

...

878

879

def tracklist_changed(self):

880

"""Called when tracklist is modified."""

881

...

882

883

def playlists_loaded(self):

884

"""Called when playlists are loaded."""

885

...

886

887

def volume_changed(self, volume):

888

"""Called when volume changes."""

889

...

890

891

def mute_changed(self, mute):

892

"""Called when mute state changes."""

893

...

894

```

895

896

Usage example:

897

```python

898

class MyListener(CoreListener):

899

def track_playback_started(self, tl_track):

900

print(f"Now playing: {tl_track.track.name}")

901

902

def volume_changed(self, volume):

903

print(f"Volume changed to: {volume}")

904

905

# Register listener (implementation depends on setup)

906

listener = MyListener()

907

```