import platform import sys import vlc from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5.QtCore import pyqtSignal from PyQt5.QtGui import QIcon from ui.qt.widgets.vlcframe_ui import Ui_VlcFrame class VlcFrame(QtWidgets.QFrame): DEFAULT_VOLUME = 50 playStarted = pyqtSignal(object) playEnded = pyqtSignal(object) def __init__(self, parent=None): super().__init__(parent) self.currentTrack = None self._media = None self._is_paused = True self._is_muted = False self.volume = self.DEFAULT_VOLUME # Create a basic vlc instance self._instance = vlc.Instance() # Create an empty vlc media player self._mediaplayer = self._instance.media_player_new() self.createWidgets() def createWidgets(self): self.ui = Ui_VlcFrame() self.ui.setupUi(self) self.ui.progressionSlider.sliderMoved.connect(self.set_position) self.ui.progressionSlider.sliderPressed.connect(self.set_position) self.ui.progressionSlider.positionClicked.connect(self.set_position) self.ui.btnPlayPause.clicked.connect(self.play_pause) self.ui.volumeSlider.setValue(self.volume) self._mediaplayer.audio_set_volume(self.volume) self.ui.volumeSlider.valueChanged.connect(self.set_volume) self.ui.volumeSlider.positionClicked.connect(self.set_volume) self.ui.btnMute.clicked.connect(self.toggle_muted) self.timer = QtCore.QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.update_ui) self.setEnabled(False) def play_track(self, track): self._media = self._instance.media_new(track.path) # Put the media in the media player self._mediaplayer.set_media(self._media) # Parse the metadata of the file self._media.parse() # Set the title of the track self.ui.lblTrack.setText(f"{track.artist or '(artiste inconnu)'} - {track.title}") self.play_pause() self.currentTrack = track self.setEnabled(True) self.playStarted.emit(self.currentTrack) def play_pause(self): """Toggle play/pause status """ if self._mediaplayer.is_playing(): self._mediaplayer.pause() self.ui.btnPlayPause.setIcon(QIcon(":/img/rsc/play.png")) self._is_paused = True self.timer.stop() else: if self._mediaplayer.play() == -1: return self._mediaplayer.play() self.ui.btnPlayPause.setIcon(QIcon(":/img/rsc/pause.png")) self.timer.start() self._is_paused = False def stop(self): """Stop player """ self._mediaplayer.stop() self.ui.btnPlayPause.setIcon(QIcon(":/img/rsc/play.png")) self.ui.progressionSlider.setSliderPosition(0) self.playEnded.emit(self.currentTrack) def update_ui(self): """Updates the user interface""" # Set the slider's position to its corresponding media position # Note that the setValue function only takes values of type int, # so we must first convert the corresponding media position. media_pos = int(self._mediaplayer.get_position() * 1000) self.ui.progressionSlider.setValue(media_pos) # No need to call this function if nothing is played if not self._mediaplayer.is_playing(): self.timer.stop() # After the video finished, the play button stills shows "Pause", # which is not the desired behavior of a media player. # This fixes that "bug". if not self._is_paused: self.stop() def set_volume(self, volume): """Set the volume """ self._mediaplayer.audio_set_volume(volume) self.volume = volume def set_position(self, position=None): """Set the movie position according to the position slider. """ # The vlc MediaPlayer needs a float value between 0 and 1, Qt uses # integer variables, so you need a factor; the higher the factor, the # more precise are the results (1000 should suffice). # if paused: resume if self._is_paused: self.play_pause() # Set the media position to where the slider was dragged self.timer.stop() pos = self.ui.progressionSlider.value() self._mediaplayer.set_position(pos / 1000.0) self.timer.start() def toggle_muted(self): if not self._is_muted: self._mediaplayer.audio_set_volume(0) self.ui.btnMute.setIcon(QIcon(":/img/rsc/mute.png")) self._is_muted = True else: self._mediaplayer.audio_set_volume(self.volume) self.ui.btnMute.setIcon(QIcon(":/img/rsc/volume.png")) self._is_muted = False