aboutsummaryrefslogtreecommitdiffstats
path: root/mediaplayer
diff options
context:
space:
mode:
Diffstat (limited to 'mediaplayer')
-rw-r--r--mediaplayer/.DS_Storebin0 -> 6148 bytes
-rw-r--r--mediaplayer/MainWindow.py141
-rw-r--r--mediaplayer/README.md20
-rw-r--r--mediaplayer/images/.DS_Storebin0 -> 6148 bytes
-rwxr-xr-xmediaplayer/images/application-image.pngbin0 -> 544 bytes
-rwxr-xr-xmediaplayer/images/control-pause.pngbin0 -> 427 bytes
-rwxr-xr-xmediaplayer/images/control-skip-180.pngbin0 -> 577 bytes
-rwxr-xr-xmediaplayer/images/control-skip.pngbin0 -> 572 bytes
-rwxr-xr-xmediaplayer/images/control-stop-square.pngbin0 -> 411 bytes
-rwxr-xr-xmediaplayer/images/control.pngbin0 -> 470 bytes
-rwxr-xr-xmediaplayer/images/speaker-volume.pngbin0 -> 566 bytes
-rw-r--r--mediaplayer/mainwindow.ui227
-rw-r--r--mediaplayer/mediaplayer.py185
-rw-r--r--mediaplayer/requirements.txt2
-rw-r--r--mediaplayer/screenshot-mediaplayer1.jpgbin0 -> 51397 bytes
-rw-r--r--mediaplayer/screenshot-mediaplayer2.jpgbin0 -> 83906 bytes
-rw-r--r--mediaplayer/test.py15
17 files changed, 590 insertions, 0 deletions
diff --git a/mediaplayer/.DS_Store b/mediaplayer/.DS_Store
new file mode 100644
index 0000000..beea7ac
--- /dev/null
+++ b/mediaplayer/.DS_Store
Binary files differ
diff --git a/mediaplayer/MainWindow.py b/mediaplayer/MainWindow.py
new file mode 100644
index 0000000..09df321
--- /dev/null
+++ b/mediaplayer/MainWindow.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'mainwindow.ui'
+#
+# Created by: PyQt5 UI code generator 5.10
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(484, 371)
+ self.centralWidget = QtWidgets.QWidget(MainWindow)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.centralWidget.sizePolicy().hasHeightForWidth())
+ self.centralWidget.setSizePolicy(sizePolicy)
+ self.centralWidget.setObjectName("centralWidget")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralWidget)
+ self.horizontalLayout.setContentsMargins(11, 11, 11, 11)
+ self.horizontalLayout.setSpacing(6)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setSpacing(6)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.playlistView = QtWidgets.QListView(self.centralWidget)
+ self.playlistView.setAcceptDrops(True)
+ self.playlistView.setProperty("showDropIndicator", True)
+ self.playlistView.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
+ self.playlistView.setAlternatingRowColors(True)
+ self.playlistView.setUniformItemSizes(True)
+ self.playlistView.setObjectName("playlistView")
+ self.verticalLayout.addWidget(self.playlistView)
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_4.setSpacing(6)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.currentTimeLabel = QtWidgets.QLabel(self.centralWidget)
+ self.currentTimeLabel.setMinimumSize(QtCore.QSize(80, 0))
+ self.currentTimeLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.currentTimeLabel.setObjectName("currentTimeLabel")
+ self.horizontalLayout_4.addWidget(self.currentTimeLabel)
+ self.timeSlider = QtWidgets.QSlider(self.centralWidget)
+ self.timeSlider.setOrientation(QtCore.Qt.Horizontal)
+ self.timeSlider.setObjectName("timeSlider")
+ self.horizontalLayout_4.addWidget(self.timeSlider)
+ self.totalTimeLabel = QtWidgets.QLabel(self.centralWidget)
+ self.totalTimeLabel.setMinimumSize(QtCore.QSize(80, 0))
+ self.totalTimeLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.totalTimeLabel.setObjectName("totalTimeLabel")
+ self.horizontalLayout_4.addWidget(self.totalTimeLabel)
+ self.verticalLayout.addLayout(self.horizontalLayout_4)
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_5.setSpacing(6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.previousButton = QtWidgets.QPushButton(self.centralWidget)
+ self.previousButton.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap("images/control-skip-180.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.previousButton.setIcon(icon)
+ self.previousButton.setObjectName("previousButton")
+ self.horizontalLayout_5.addWidget(self.previousButton)
+ self.playButton = QtWidgets.QPushButton(self.centralWidget)
+ self.playButton.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap("images/control.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.playButton.setIcon(icon1)
+ self.playButton.setObjectName("playButton")
+ self.horizontalLayout_5.addWidget(self.playButton)
+ self.pauseButton = QtWidgets.QPushButton(self.centralWidget)
+ self.pauseButton.setText("")
+ icon2 = QtGui.QIcon()
+ icon2.addPixmap(QtGui.QPixmap("images/control-pause.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.pauseButton.setIcon(icon2)
+ self.pauseButton.setObjectName("pauseButton")
+ self.horizontalLayout_5.addWidget(self.pauseButton)
+ self.stopButton = QtWidgets.QPushButton(self.centralWidget)
+ self.stopButton.setText("")
+ icon3 = QtGui.QIcon()
+ icon3.addPixmap(QtGui.QPixmap("images/control-stop-square.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.stopButton.setIcon(icon3)
+ self.stopButton.setObjectName("stopButton")
+ self.horizontalLayout_5.addWidget(self.stopButton)
+ self.nextButton = QtWidgets.QPushButton(self.centralWidget)
+ self.nextButton.setText("")
+ icon4 = QtGui.QIcon()
+ icon4.addPixmap(QtGui.QPixmap("images/control-skip.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.nextButton.setIcon(icon4)
+ self.nextButton.setObjectName("nextButton")
+ self.horizontalLayout_5.addWidget(self.nextButton)
+ self.viewButton = QtWidgets.QPushButton(self.centralWidget)
+ self.viewButton.setText("")
+ icon5 = QtGui.QIcon()
+ icon5.addPixmap(QtGui.QPixmap("images/application-image.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.viewButton.setIcon(icon5)
+ self.viewButton.setCheckable(True)
+ self.viewButton.setObjectName("viewButton")
+ self.horizontalLayout_5.addWidget(self.viewButton)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem)
+ self.label = QtWidgets.QLabel(self.centralWidget)
+ self.label.setText("")
+ self.label.setPixmap(QtGui.QPixmap("images/speaker-volume.png"))
+ self.label.setObjectName("label")
+ self.horizontalLayout_5.addWidget(self.label)
+ self.volumeSlider = QtWidgets.QSlider(self.centralWidget)
+ self.volumeSlider.setMaximum(100)
+ self.volumeSlider.setProperty("value", 100)
+ self.volumeSlider.setOrientation(QtCore.Qt.Horizontal)
+ self.volumeSlider.setObjectName("volumeSlider")
+ self.horizontalLayout_5.addWidget(self.volumeSlider)
+ self.verticalLayout.addLayout(self.horizontalLayout_5)
+ self.horizontalLayout.addLayout(self.verticalLayout)
+ MainWindow.setCentralWidget(self.centralWidget)
+ self.menuBar = QtWidgets.QMenuBar(MainWindow)
+ self.menuBar.setGeometry(QtCore.QRect(0, 0, 484, 22))
+ self.menuBar.setObjectName("menuBar")
+ self.menuFIle = QtWidgets.QMenu(self.menuBar)
+ self.menuFIle.setObjectName("menuFIle")
+ MainWindow.setMenuBar(self.menuBar)
+ self.statusBar = QtWidgets.QStatusBar(MainWindow)
+ self.statusBar.setObjectName("statusBar")
+ MainWindow.setStatusBar(self.statusBar)
+ self.open_file_action = QtWidgets.QAction(MainWindow)
+ self.open_file_action.setObjectName("open_file_action")
+ self.menuFIle.addAction(self.open_file_action)
+ self.menuBar.addAction(self.menuFIle.menuAction())
+
+ self.retranslateUi(MainWindow)
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+ def retranslateUi(self, MainWindow):
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "Failamp"))
+ self.currentTimeLabel.setText(_translate("MainWindow", "0:00"))
+ self.totalTimeLabel.setText(_translate("MainWindow", "0:00"))
+ self.menuFIle.setTitle(_translate("MainWindow", "FIle"))
+ self.open_file_action.setText(_translate("MainWindow", "Open file..."))
+
diff --git a/mediaplayer/README.md b/mediaplayer/README.md
new file mode 100644
index 0000000..5bd24f7
--- /dev/null
+++ b/mediaplayer/README.md
@@ -0,0 +1,20 @@
+# Failamp — Simple mediaplayer build in PyQt
+
+Simple app to listen to and watch videos and audio files,
+with built in playlist. Uses QtMultimedia and QtMultimediaWidgets
+to handle playback and manage the playlist.
+
+The main interface offers a playlist window in which you can drag-drop
+media files to be played. Standard media controls are provided, along
+with a timeline scrub widget and a volume control.
+
+![Mediaplayer](screenshot-mediaplayer1.jpg)
+
+For video playback you can pop out an external video viewer window
+which floats on top.
+
+![Mediaplayer](screenshot-mediaplayer2.jpg)
+
+> If you think this app is neat and want to learn more about
+PyQt in general, take a look at my [free PyQt tutorials](https://www.learnpyqt.com)
+which cover everything you need to know to start building your own applications with PyQt. \ No newline at end of file
diff --git a/mediaplayer/images/.DS_Store b/mediaplayer/images/.DS_Store
new file mode 100644
index 0000000..a2cca49
--- /dev/null
+++ b/mediaplayer/images/.DS_Store
Binary files differ
diff --git a/mediaplayer/images/application-image.png b/mediaplayer/images/application-image.png
new file mode 100755
index 0000000..915d63f
--- /dev/null
+++ b/mediaplayer/images/application-image.png
Binary files differ
diff --git a/mediaplayer/images/control-pause.png b/mediaplayer/images/control-pause.png
new file mode 100755
index 0000000..af57b25
--- /dev/null
+++ b/mediaplayer/images/control-pause.png
Binary files differ
diff --git a/mediaplayer/images/control-skip-180.png b/mediaplayer/images/control-skip-180.png
new file mode 100755
index 0000000..62daa7a
--- /dev/null
+++ b/mediaplayer/images/control-skip-180.png
Binary files differ
diff --git a/mediaplayer/images/control-skip.png b/mediaplayer/images/control-skip.png
new file mode 100755
index 0000000..e4a4930
--- /dev/null
+++ b/mediaplayer/images/control-skip.png
Binary files differ
diff --git a/mediaplayer/images/control-stop-square.png b/mediaplayer/images/control-stop-square.png
new file mode 100755
index 0000000..7c6af7f
--- /dev/null
+++ b/mediaplayer/images/control-stop-square.png
Binary files differ
diff --git a/mediaplayer/images/control.png b/mediaplayer/images/control.png
new file mode 100755
index 0000000..2dfaef5
--- /dev/null
+++ b/mediaplayer/images/control.png
Binary files differ
diff --git a/mediaplayer/images/speaker-volume.png b/mediaplayer/images/speaker-volume.png
new file mode 100755
index 0000000..62fcfc6
--- /dev/null
+++ b/mediaplayer/images/speaker-volume.png
Binary files differ
diff --git a/mediaplayer/mainwindow.ui b/mediaplayer/mainwindow.ui
new file mode 100644
index 0000000..2d8a4ba
--- /dev/null
+++ b/mediaplayer/mainwindow.ui
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>371</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Failamp</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QListView" name="playlistView">
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::DropOnly</enum>
+ </property>
+ <property name="defaultDropAction">
+ <enum>Qt::CopyAction</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="uniformItemSizes">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="currentTimeLabel">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0:00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="timeSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="totalTimeLabel">
+ <property name="minimumSize">
+ <size>
+ <width>80</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>0:00</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QPushButton" name="previousButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/control-skip-180.png</normaloff>images/control-skip-180.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="playButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/control.png</normaloff>images/control.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pauseButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/control-pause.png</normaloff>images/control-pause.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stopButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/control-stop-square.png</normaloff>images/control-stop-square.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="nextButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/control-skip.png</normaloff>images/control-skip.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="viewButton">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="icon">
+ <iconset>
+ <normaloff>images/application-image.png</normaloff>images/application-image.png</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap>images/speaker-volume.png</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="volumeSlider">
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFIle">
+ <property name="title">
+ <string>FIle</string>
+ </property>
+ <addaction name="open_file_action"/>
+ </widget>
+ <addaction name="menuFIle"/>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ <action name="open_file_action">
+ <property name="text">
+ <string>Open file...</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
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_()
diff --git a/mediaplayer/requirements.txt b/mediaplayer/requirements.txt
new file mode 100644
index 0000000..8cb824a
--- /dev/null
+++ b/mediaplayer/requirements.txt
@@ -0,0 +1,2 @@
+PyQt5>=5.6
+sip
diff --git a/mediaplayer/screenshot-mediaplayer1.jpg b/mediaplayer/screenshot-mediaplayer1.jpg
new file mode 100644
index 0000000..86090a2
--- /dev/null
+++ b/mediaplayer/screenshot-mediaplayer1.jpg
Binary files differ
diff --git a/mediaplayer/screenshot-mediaplayer2.jpg b/mediaplayer/screenshot-mediaplayer2.jpg
new file mode 100644
index 0000000..053ff56
--- /dev/null
+++ b/mediaplayer/screenshot-mediaplayer2.jpg
Binary files differ
diff --git a/mediaplayer/test.py b/mediaplayer/test.py
new file mode 100644
index 0000000..afdd625
--- /dev/null
+++ b/mediaplayer/test.py
@@ -0,0 +1,15 @@
+import sys
+from PySide2 import QtWidgets
+from MainWindow2 import Ui_MainWindow
+
+class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.setupUi(self)
+
+
+app = QtWidgets.QApplication(sys.argv)
+window = MainWindow()
+window.show()
+app.exec_() \ No newline at end of file