aboutsummaryrefslogtreecommitdiffstats
path: root/mediaplayer/mediaplayer.py
diff options
context:
space:
mode:
authorEddy Pedroni <eddy@0xf7.com>2020-11-01 19:47:29 +0100
committerEddy Pedroni <eddy@0xf7.com>2020-11-01 19:47:29 +0100
commit6a74b090b13a9e1ff37338332627eb5f16ed7d40 (patch)
tree7d1fe56906effaa9655855902da436e71a569d27 /mediaplayer/mediaplayer.py
Initial commit
Diffstat (limited to 'mediaplayer/mediaplayer.py')
-rw-r--r--mediaplayer/mediaplayer.py185
1 files changed, 185 insertions, 0 deletions
diff --git a/mediaplayer/mediaplayer.py b/mediaplayer/mediaplayer.py
new file mode 100644
index 0000000..fe4cc50
--- /dev/null
+++ b/mediaplayer/mediaplayer.py
@@ -0,0 +1,185 @@
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import *
+from PyQt5.QtMultimedia import *
+from PyQt5.QtMultimediaWidgets import *
+
+from MainWindow import Ui_MainWindow
+
+def hhmmss(ms):
+ # s = 1000
+ # m = 60000
+ # h = 360000
+ h, r = divmod(ms, 36000)
+ m, r = divmod(r, 60000)
+ s, _ = divmod(r, 1000)
+ return ("%d:%02d:%02d" % (h,m,s)) if h else ("%d:%02d" % (m,s))
+
+class ViewerWindow(QMainWindow):
+ state = pyqtSignal(bool)
+
+ def closeEvent(self, e):
+ # Emit the window state, to update the viewer toggle button.
+ self.state.emit(False)
+
+
+class PlaylistModel(QAbstractListModel):
+ def __init__(self, playlist, *args, **kwargs):
+ super(PlaylistModel, self).__init__(*args, **kwargs)
+ self.playlist = playlist
+
+ def data(self, index, role):
+ if role == Qt.DisplayRole:
+ media = self.playlist.media(index.row())
+ return media.canonicalUrl().fileName()
+
+ def rowCount(self, index):
+ return self.playlist.mediaCount()
+
+
+class MainWindow(QMainWindow, Ui_MainWindow):
+ def __init__(self, *args, **kwargs):
+ super(MainWindow, self).__init__(*args, **kwargs)
+ self.setupUi(self)
+
+ self.player = QMediaPlayer()
+
+ self.player.error.connect(self.erroralert)
+ self.player.play()
+
+ # Setup the playlist.
+ self.playlist = QMediaPlaylist()
+ self.player.setPlaylist(self.playlist)
+
+ # Add viewer for video playback, separate floating window.
+ self.viewer = ViewerWindow(self)
+ self.viewer.setWindowFlags(self.viewer.windowFlags() | Qt.WindowStaysOnTopHint)
+ self.viewer.setMinimumSize(QSize(480,360))
+
+ videoWidget = QVideoWidget()
+ self.viewer.setCentralWidget(videoWidget)
+ self.player.setVideoOutput(videoWidget)
+
+ # Connect control buttons/slides for media player.
+ self.playButton.pressed.connect(self.player.play)
+ self.pauseButton.pressed.connect(self.player.pause)
+ self.stopButton.pressed.connect(self.player.stop)
+ self.volumeSlider.valueChanged.connect(self.player.setVolume)
+
+ self.viewButton.toggled.connect(self.toggle_viewer)
+ self.viewer.state.connect(self.viewButton.setChecked)
+
+ self.previousButton.pressed.connect(self.playlist.previous)
+ self.nextButton.pressed.connect(self.playlist.next)
+
+ self.model = PlaylistModel(self.playlist)
+ self.playlistView.setModel(self.model)
+ self.playlist.currentIndexChanged.connect(self.playlist_position_changed)
+ selection_model = self.playlistView.selectionModel()
+ selection_model.selectionChanged.connect(self.playlist_selection_changed)
+
+ self.player.durationChanged.connect(self.update_duration)
+ self.player.positionChanged.connect(self.update_position)
+ self.timeSlider.valueChanged.connect(self.player.setPosition)
+
+ self.open_file_action.triggered.connect(self.open_file)
+
+ self.setAcceptDrops(True)
+
+ self.show()
+
+ def dragEnterEvent(self, e):
+ if e.mimeData().hasUrls():
+ e.acceptProposedAction()
+
+ def dropEvent(self, e):
+ for url in e.mimeData().urls():
+ self.playlist.addMedia(
+ QMediaContent(url)
+ )
+
+ self.model.layoutChanged.emit()
+
+ # If not playing, seeking to first of newly added + play.
+ if self.player.state() != QMediaPlayer.PlayingState:
+ i = self.playlist.mediaCount() - len(e.mimeData().urls())
+ self.playlist.setCurrentIndex(i)
+ self.player.play()
+
+ def open_file(self):
+ path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "mp3 Audio (*.mp3);mp4 Video (*.mp4);Movie files (*.mov);All files (*.*)")
+
+ if path:
+ self.playlist.addMedia(
+ QMediaContent(
+ QUrl.fromLocalFile(path)
+ )
+ )
+
+ self.model.layoutChanged.emit()
+
+ def update_duration(self, duration):
+ print("!", duration)
+ print("?", self.player.duration())
+
+ self.timeSlider.setMaximum(duration)
+
+ if duration >= 0:
+ self.totalTimeLabel.setText(hhmmss(duration))
+
+ def update_position(self, position):
+ if position >= 0:
+ self.currentTimeLabel.setText(hhmmss(position))
+
+ # Disable the events to prevent updating triggering a setPosition event (can cause stuttering).
+ self.timeSlider.blockSignals(True)
+ self.timeSlider.setValue(position)
+ self.timeSlider.blockSignals(False)
+
+ def playlist_selection_changed(self, ix):
+ # We receive a QItemSelection from selectionChanged.
+ i = ix.indexes()[0].row()
+ self.playlist.setCurrentIndex(i)
+
+ def playlist_position_changed(self, i):
+ if i > -1:
+ ix = self.model.index(i)
+ self.playlistView.setCurrentIndex(ix)
+
+ def toggle_viewer(self, state):
+ if state:
+ self.viewer.show()
+ else:
+ self.viewer.hide()
+
+ def erroralert(self, *args):
+ print(args)
+
+
+
+
+if __name__ == '__main__':
+ app = QApplication([])
+ app.setApplicationName("Failamp")
+ app.setStyle("Fusion")
+
+ # Fusion dark palette from https://gist.github.com/QuantumCD/6245215.
+ palette = QPalette()
+ palette.setColor(QPalette.Window, QColor(53, 53, 53))
+ palette.setColor(QPalette.WindowText, Qt.white)
+ palette.setColor(QPalette.Base, QColor(25, 25, 25))
+ palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
+ palette.setColor(QPalette.ToolTipBase, Qt.white)
+ palette.setColor(QPalette.ToolTipText, Qt.white)
+ palette.setColor(QPalette.Text, Qt.white)
+ palette.setColor(QPalette.Button, QColor(53, 53, 53))
+ palette.setColor(QPalette.ButtonText, Qt.white)
+ palette.setColor(QPalette.BrightText, Qt.red)
+ palette.setColor(QPalette.Link, QColor(42, 130, 218))
+ palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
+ palette.setColor(QPalette.HighlightedText, Qt.black)
+ app.setPalette(palette)
+ app.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }")
+
+ window = MainWindow()
+ app.exec_()