or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buttons.mddialog-notification.mddisplay-widgets.mdindex.mdinput-controls.mdlayout-animation.mdlist-view-widgets.mdmaterial-effects.mdmenu-command.mdmultimedia.mdsettings-config.mdtheme-styling.mdwindow-navigation.md

multimedia.mddocs/

0

# Multimedia Components

1

2

Media player widgets, video display, and audio/video control components with modern playback interfaces. These components provide comprehensive multimedia functionality with fluent design integration.

3

4

## Capabilities

5

6

### Media Player

7

8

Core media player widget with comprehensive playback controls and modern interface design.

9

10

```python { .api }

11

class MediaPlayer(QWidget):

12

def __init__(self, parent=None): ...

13

def setMedia(self, media: Union[str, QUrl, QMediaContent]): ...

14

def media(self) -> QMediaContent: ...

15

def play(self): ...

16

def pause(self): ...

17

def stop(self): ...

18

def setPosition(self, position: int): ...

19

def position(self) -> int: ...

20

def setVolume(self, volume: int): ...

21

def volume(self) -> int: ...

22

def duration(self) -> int: ...

23

def state(self) -> QMediaPlayer.State: ...

24

25

# Signals

26

positionChanged = pyqtSignal(int)

27

durationChanged = pyqtSignal(int)

28

stateChanged = pyqtSignal(QMediaPlayer.State)

29

volumeChanged = pyqtSignal(int)

30

31

class MediaPlayerBase(QWidget):

32

def __init__(self, parent=None): ...

33

def setMediaPlayer(self, player: QMediaPlayer): ...

34

def mediaPlayer(self) -> QMediaPlayer: ...

35

```

36

37

**Usage Example:**

38

```python

39

from qfluentwidgets import MediaPlayer

40

from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent

41

from PyQt5.QtCore import QUrl

42

43

# Create media player

44

media_player = MediaPlayer(self)

45

media_player.setFixedSize(600, 400)

46

47

# Load media file

48

media_file = "path/to/video.mp4"

49

media_player.setMedia(media_file)

50

51

# Connect to signals

52

media_player.positionChanged.connect(self.on_position_changed)

53

media_player.durationChanged.connect(self.on_duration_changed)

54

media_player.stateChanged.connect(self.on_state_changed)

55

56

def on_position_changed(self, position):

57

# Update progress slider

58

progress_slider.setValue(position)

59

60

def on_duration_changed(self, duration):

61

# Set slider range

62

progress_slider.setRange(0, duration)

63

duration_label.setText(self.format_time(duration))

64

65

def on_state_changed(self, state):

66

if state == QMediaPlayer.PlayingState:

67

play_button.setText("Pause")

68

else:

69

play_button.setText("Play")

70

71

# Control playback

72

play_button.clicked.connect(media_player.play)

73

pause_button.clicked.connect(media_player.pause)

74

stop_button.clicked.connect(media_player.stop)

75

```

76

77

### Video Display

78

79

Dedicated video display widget for rendering video content with proper aspect ratio handling.

80

81

```python { .api }

82

class VideoWidget(QVideoWidget):

83

def __init__(self, parent=None): ...

84

def setAspectRatioMode(self, mode: Qt.AspectRatioMode): ...

85

def aspectRatioMode(self) -> Qt.AspectRatioMode: ...

86

def setFullScreen(self, fullScreen: bool): ...

87

def isFullScreen(self) -> bool: ...

88

def sizeHint(self) -> QSize: ...

89

```

90

91

**Usage Example:**

92

```python

93

from qfluentwidgets import VideoWidget, MediaPlayer

94

from PyQt5.QtCore import Qt

95

96

# Create video display

97

video_widget = VideoWidget(self)

98

video_widget.setAspectRatioMode(Qt.KeepAspectRatio)

99

video_widget.setMinimumSize(320, 240)

100

101

# Create media player and connect to video widget

102

player = QMediaPlayer(self)

103

player.setVideoOutput(video_widget)

104

105

# Create media player UI

106

media_player = MediaPlayer(self)

107

media_player.setMediaPlayer(player)

108

109

# Layout video and controls

110

layout = QVBoxLayout(self)

111

layout.addWidget(video_widget, 1) # Video takes most space

112

layout.addWidget(media_player, 0) # Controls at bottom

113

114

# Fullscreen toggle

115

def toggle_fullscreen():

116

video_widget.setFullScreen(not video_widget.isFullScreen())

117

118

fullscreen_btn.clicked.connect(toggle_fullscreen)

119

120

# Handle escape key to exit fullscreen

121

def keyPressEvent(self, event):

122

if event.key() == Qt.Key_Escape and video_widget.isFullScreen():

123

video_widget.setFullScreen(False)

124

super().keyPressEvent(event)

125

```

126

127

### Media Control Bars

128

129

Specialized control bars with playback buttons, progress tracking, and volume controls.

130

131

```python { .api }

132

class StandardMediaPlayBar(QWidget):

133

def __init__(self, parent=None): ...

134

def setMediaPlayer(self, player: QMediaPlayer): ...

135

def setPlayButtonVisible(self, visible: bool): ...

136

def setVolumeButtonVisible(self, visible: bool): ...

137

def setProgressSliderVisible(self, visible: bool): ...

138

def setTimeLabelsVisible(self, visible: bool): ...

139

140

class SimpleMediaPlayBar(QWidget):

141

def __init__(self, parent=None): ...

142

def setMediaPlayer(self, player: QMediaPlayer): ...

143

def setCompactMode(self, compact: bool): ...

144

145

class MediaPlayBarButton(QToolButton):

146

def __init__(self, parent=None): ...

147

def __init__(self, icon: Union[FluentIconBase, QIcon, str], parent=None): ...

148

def setPlayIcon(self, icon: Union[FluentIconBase, QIcon, str]): ...

149

def setPauseIcon(self, icon: Union[FluentIconBase, QIcon, str]): ...

150

def setPlaying(self, playing: bool): ...

151

```

152

153

**Usage Example:**

154

```python

155

from qfluentwidgets import (StandardMediaPlayBar, SimpleMediaPlayBar,

156

MediaPlayBarButton, FluentIcon as FIF)

157

158

# Standard media control bar

159

standard_bar = StandardMediaPlayBar(self)

160

standard_bar.setMediaPlayer(player)

161

162

# Customize visibility

163

standard_bar.setPlayButtonVisible(True)

164

standard_bar.setVolumeButtonVisible(True)

165

standard_bar.setProgressSliderVisible(True)

166

standard_bar.setTimeLabelsVisible(True)

167

168

# Simple media control bar

169

simple_bar = SimpleMediaPlayBar(self)

170

simple_bar.setMediaPlayer(player)

171

simple_bar.setCompactMode(True)

172

173

# Custom media buttons

174

play_pause_btn = MediaPlayBarButton(self)

175

play_pause_btn.setPlayIcon(FIF.PLAY)

176

play_pause_btn.setPauseIcon(FIF.PAUSE)

177

178

stop_btn = MediaPlayBarButton(FIF.STOP, self)

179

next_btn = MediaPlayBarButton(FIF.NEXT, self)

180

prev_btn = MediaPlayBarButton(FIF.PREVIOUS, self)

181

182

# Connect custom buttons

183

play_pause_btn.clicked.connect(self.toggle_playback)

184

stop_btn.clicked.connect(player.stop)

185

next_btn.clicked.connect(self.next_track)

186

prev_btn.clicked.connect(self.previous_track)

187

188

def toggle_playback(self):

189

if player.state() == QMediaPlayer.PlayingState:

190

player.pause()

191

play_pause_btn.setPlaying(False)

192

else:

193

player.play()

194

play_pause_btn.setPlaying(True)

195

```

196

197

## Complete Media Player Example

198

199

```python

200

from qfluentwidgets import *

201

from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QMediaPlaylist

202

from PyQt5.QtCore import QUrl, QTimer

203

204

class FluentMediaPlayer(QWidget):

205

def __init__(self, parent=None):

206

super().__init__(parent)

207

self.setupUi()

208

self.setupMediaPlayer()

209

self.setupConnections()

210

211

def setupUi(self):

212

# Main layout

213

layout = QVBoxLayout(self)

214

215

# Title bar

216

title_bar = QHBoxLayout()

217

self.title_label = TitleLabel("Media Player")

218

self.minimize_btn = TransparentToolButton(FIF.MINIMIZE)

219

self.close_btn = TransparentToolButton(FIF.CLOSE)

220

221

title_bar.addWidget(self.title_label)

222

title_bar.addStretch()

223

title_bar.addWidget(self.minimize_btn)

224

title_bar.addWidget(self.close_btn)

225

226

# Video display area

227

self.video_widget = VideoWidget(self)

228

self.video_widget.setAspectRatioMode(Qt.KeepAspectRatio)

229

self.video_widget.setMinimumSize(640, 360)

230

231

# Control panel

232

control_layout = QHBoxLayout()

233

234

# Playback controls

235

self.prev_btn = MediaPlayBarButton(FIF.PREVIOUS, self)

236

self.play_pause_btn = MediaPlayBarButton(FIF.PLAY, self)

237

self.stop_btn = MediaPlayBarButton(FIF.STOP, self)

238

self.next_btn = MediaPlayBarButton(FIF.NEXT, self)

239

240

# Progress controls

241

self.position_slider = Slider(Qt.Horizontal, self)

242

self.position_slider.setFixedHeight(20)

243

244

# Time labels

245

self.current_time_label = CaptionLabel("00:00")

246

self.duration_label = CaptionLabel("00:00")

247

248

# Volume controls

249

self.volume_btn = MediaPlayBarButton(FIF.VOLUME, self)

250

self.volume_slider = Slider(Qt.Horizontal, self)

251

self.volume_slider.setRange(0, 100)

252

self.volume_slider.setValue(70)

253

self.volume_slider.setFixedWidth(100)

254

255

# Add to control layout

256

control_layout.addWidget(self.prev_btn)

257

control_layout.addWidget(self.play_pause_btn)

258

control_layout.addWidget(self.stop_btn)

259

control_layout.addWidget(self.next_btn)

260

control_layout.addStretch()

261

control_layout.addWidget(self.current_time_label)

262

control_layout.addWidget(self.position_slider, 1)

263

control_layout.addWidget(self.duration_label)

264

control_layout.addStretch()

265

control_layout.addWidget(self.volume_btn)

266

control_layout.addWidget(self.volume_slider)

267

268

# Playlist area

269

self.playlist_widget = ListWidget(self)

270

self.playlist_widget.setMaximumHeight(150)

271

272

# Add to main layout

273

layout.addLayout(title_bar)

274

layout.addWidget(self.video_widget, 1)

275

layout.addLayout(control_layout)

276

layout.addWidget(self.playlist_widget)

277

278

def setupMediaPlayer(self):

279

# Media player

280

self.player = QMediaPlayer(self)

281

self.player.setVideoOutput(self.video_widget)

282

283

# Playlist

284

self.playlist = QMediaPlaylist(self)

285

self.player.setPlaylist(self.playlist)

286

287

# Position update timer

288

self.position_timer = QTimer(self)

289

self.position_timer.timeout.connect(self.update_position)

290

self.position_timer.start(100) # Update every 100ms

291

292

def setupConnections(self):

293

# Player signals

294

self.player.stateChanged.connect(self.on_state_changed)

295

self.player.positionChanged.connect(self.on_position_changed)

296

self.player.durationChanged.connect(self.on_duration_changed)

297

self.player.volumeChanged.connect(self.on_volume_changed)

298

299

# Control connections

300

self.play_pause_btn.clicked.connect(self.toggle_playback)

301

self.stop_btn.clicked.connect(self.player.stop)

302

self.prev_btn.clicked.connect(self.playlist.previous)

303

self.next_btn.clicked.connect(self.playlist.next)

304

305

# Slider connections

306

self.position_slider.sliderPressed.connect(self.on_position_slider_pressed)

307

self.position_slider.sliderReleased.connect(self.on_position_slider_released)

308

self.volume_slider.valueChanged.connect(self.player.setVolume)

309

310

# Playlist connections

311

self.playlist_widget.itemDoubleClicked.connect(self.play_selected_item)

312

313

def add_media_file(self, file_path: str):

314

"""Add media file to playlist"""

315

media_content = QMediaContent(QUrl.fromLocalFile(file_path))

316

self.playlist.addMedia(media_content)

317

318

# Add to playlist widget

319

file_name = os.path.basename(file_path)

320

self.playlist_widget.addItem(file_name)

321

322

def toggle_playback(self):

323

"""Toggle between play and pause"""

324

if self.player.state() == QMediaPlayer.PlayingState:

325

self.player.pause()

326

else:

327

self.player.play()

328

329

def on_state_changed(self, state):

330

"""Handle player state changes"""

331

if state == QMediaPlayer.PlayingState:

332

self.play_pause_btn.setIcon(FIF.PAUSE.icon())

333

else:

334

self.play_pause_btn.setIcon(FIF.PLAY.icon())

335

336

def on_position_changed(self, position):

337

"""Handle position changes"""

338

if not self.position_slider.isSliderDown():

339

self.position_slider.setValue(position)

340

341

self.current_time_label.setText(self.format_time(position))

342

343

def on_duration_changed(self, duration):

344

"""Handle duration changes"""

345

self.position_slider.setRange(0, duration)

346

self.duration_label.setText(self.format_time(duration))

347

348

def on_volume_changed(self, volume):

349

"""Handle volume changes"""

350

self.volume_slider.setValue(volume)

351

352

# Update volume icon

353

if volume == 0:

354

self.volume_btn.setIcon(FIF.MUTE.icon())

355

elif volume < 50:

356

self.volume_btn.setIcon(FIF.VOLUME.icon())

357

else:

358

self.volume_btn.setIcon(FIF.VOLUME.icon())

359

360

def on_position_slider_pressed(self):

361

"""Handle position slider press"""

362

self.position_timer.stop()

363

364

def on_position_slider_released(self):

365

"""Handle position slider release"""

366

self.player.setPosition(self.position_slider.value())

367

self.position_timer.start()

368

369

def play_selected_item(self, item):

370

"""Play selected playlist item"""

371

row = self.playlist_widget.row(item)

372

self.playlist.setCurrentIndex(row)

373

self.player.play()

374

375

def format_time(self, milliseconds):

376

"""Format time in MM:SS format"""

377

seconds = milliseconds // 1000

378

minutes = seconds // 60

379

seconds = seconds % 60

380

return f"{minutes:02d}:{seconds:02d}"

381

382

def update_position(self):

383

"""Update position display"""

384

if self.player.state() == QMediaPlayer.PlayingState:

385

position = self.player.position()

386

if not self.position_slider.isSliderDown():

387

self.position_slider.setValue(position)

388

389

# Usage

390

media_player = FluentMediaPlayer()

391

media_player.add_media_file("video1.mp4")

392

media_player.add_media_file("audio1.mp3")

393

media_player.show()

394

```

395

396

## Advanced Features

397

398

### Custom Media Controls

399

400

```python

401

class CustomMediaControls(QWidget):

402

def __init__(self, player: QMediaPlayer, parent=None):

403

super().__init__(parent)

404

self.player = player

405

self.setupUi()

406

407

def setupUi(self):

408

layout = QHBoxLayout(self)

409

410

# Playback speed control

411

speed_combo = ComboBox(self)

412

speed_combo.addItems(["0.5x", "0.75x", "1.0x", "1.25x", "1.5x", "2.0x"])

413

speed_combo.setCurrentText("1.0x")

414

speed_combo.currentTextChanged.connect(self.change_playback_speed)

415

416

# Quality selection

417

quality_combo = ComboBox(self)

418

quality_combo.addItems(["Auto", "1080p", "720p", "480p", "360p"])

419

420

# Fullscreen button

421

fullscreen_btn = ToolButton(FIF.FULL_SCREEN, self)

422

fullscreen_btn.clicked.connect(self.toggle_fullscreen)

423

424

layout.addWidget(QLabel("Speed:"))

425

layout.addWidget(speed_combo)

426

layout.addWidget(QLabel("Quality:"))

427

layout.addWidget(quality_combo)

428

layout.addStretch()

429

layout.addWidget(fullscreen_btn)

430

431

def change_playback_speed(self, speed_text):

432

speed = float(speed_text.replace('x', ''))

433

self.player.setPlaybackRate(speed)

434

```

435

436

### Playlist Management

437

438

```python

439

class PlaylistManager:

440

def __init__(self, playlist: QMediaPlaylist, list_widget: ListWidget):

441

self.playlist = playlist

442

self.list_widget = list_widget

443

self.media_files = []

444

445

def add_files(self, file_paths: List[str]):

446

for file_path in file_paths:

447

self.add_file(file_path)

448

449

def add_file(self, file_path: str):

450

media = QMediaContent(QUrl.fromLocalFile(file_path))

451

self.playlist.addMedia(media)

452

self.media_files.append(file_path)

453

454

# Add to UI

455

file_name = os.path.basename(file_path)

456

self.list_widget.addItem(file_name)

457

458

def remove_current(self):

459

current_index = self.playlist.currentIndex()

460

if current_index >= 0:

461

self.playlist.removeMedia(current_index)

462

self.media_files.pop(current_index)

463

self.list_widget.takeItem(current_index)

464

465

def shuffle(self):

466

self.playlist.shuffle()

467

468

def set_repeat_mode(self, mode: QMediaPlaylist.PlaybackMode):

469

self.playlist.setPlaybackMode(mode)

470

```

471

472

## Error Handling and Validation

473

474

```python

475

def handle_media_errors(self):

476

"""Handle media player errors"""

477

self.player.error.connect(self.on_media_error)

478

479

def on_media_error(self, error):

480

"""Handle media playback errors"""

481

error_messages = {

482

QMediaPlayer.NoError: "No error",

483

QMediaPlayer.ResourceError: "Resource error - file not found or corrupted",

484

QMediaPlayer.FormatError: "Format error - unsupported media format",

485

QMediaPlayer.NetworkError: "Network error - connection failed",

486

QMediaPlayer.AccessDeniedError: "Access denied - insufficient permissions",

487

QMediaPlayer.ServiceMissingError: "Service missing - codec not available"

488

}

489

490

message = error_messages.get(error, f"Unknown error: {error}")

491

492

# Show error dialog

493

error_dialog = MessageBox("Media Error", message, self)

494

error_dialog.exec()

495

```

496

497

## Best Practices

498

499

### Performance Optimization

500

501

1. **Use appropriate video resolution** for display size

502

2. **Implement buffering indicators** for network streams

503

3. **Handle large playlists efficiently** with lazy loading

504

4. **Optimize UI updates** during playback

505

506

### User Experience

507

508

1. **Provide keyboard shortcuts** for common actions

509

2. **Remember user preferences** (volume, position, etc.)

510

3. **Support drag-and-drop** for adding media files

511

4. **Implement proper fullscreen handling**

512

513

### Accessibility

514

515

1. **Add tooltips** to all control buttons

516

2. **Support keyboard navigation** through controls

517

3. **Provide audio descriptions** when available

518

4. **Respect system accessibility settings**