Improved embedded Audio player and commented code

This commit is contained in:
Dilan Boskan 2021-02-11 12:03:22 +01:00
parent c7544761cc
commit 4bb0e154fe
13 changed files with 168 additions and 59 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

View File

@ -1,3 +0,0 @@
*
!.gitignore

View File

@ -45,6 +45,8 @@ class ResourcePaths:
audio_play = os.path.join(abs_path, IMAGE_FOLDER, 'audio_play.png')
audio_pause = os.path.join(abs_path, IMAGE_FOLDER, 'audio_pause.png')
save = os.path.join(abs_path, IMAGE_FOLDER, 'save.png')
menu = os.path.join(abs_path, IMAGE_FOLDER, 'menu.png')
playpause_gif = os.path.join(abs_path, IMAGE_FOLDER, 'playpause.gif')
class flags:
_FLAG_FOLDER = 'flags'
@ -187,4 +189,4 @@ if __name__ == "__main__":
print('-- Images --')
for img, img_path in vars(ResourcePaths.images).items():
if os.path.isfile(str(img_path)):
print(f'{img} -> {img_path}')
print(f'{img} -> {img_path}')

View File

@ -86,7 +86,7 @@ class Ui_MainWindow(object):
"}\n"
"QSlider[audioPlayer=\"true\"]::groove:horizontal { \n"
" background-color: rgb(66, 72, 83);\n"
" height: 6px; \n"
" height: 4px; \n"
" border-radius: 2px;\n"
"}\n"
"\n"
@ -94,8 +94,8 @@ class Ui_MainWindow(object):
" background-color: rgb(109, 213, 237); \n"
" border: 2px solid rgb(109, 213, 237); \n"
" width: 10px; \n"
" margin-top: -4px; \n"
" margin-bottom: -4px; \n"
" margin-top: -5px; \n"
" margin-bottom: -5px; \n"
" border-radius: 5px; \n"
"}\n"
"\n"
@ -266,14 +266,14 @@ class Ui_MainWindow(object):
self.horizontalLayout_3.addWidget(self.horizontalSlider_vocals)
self.pushButton_save_vocals = QPushButton(self.frame_4)
self.pushButton_save_vocals.setObjectName(u"pushButton_save_vocals")
self.pushButton_save_vocals.setMaximumSize(QSize(30, 30))
self.pushButton_save_vocals.setCursor(QCursor(Qt.PointingHandCursor))
self.pushButton_save_vocals.setStyleSheet(u"")
self.pushButton_save_vocals.setProperty("audioPlayer", True)
self.pushButton_menu_vocals = QPushButton(self.frame_4)
self.pushButton_menu_vocals.setObjectName(u"pushButton_menu_vocals")
self.pushButton_menu_vocals.setMaximumSize(QSize(30, 30))
self.pushButton_menu_vocals.setCursor(QCursor(Qt.PointingHandCursor))
self.pushButton_menu_vocals.setStyleSheet(u"")
self.pushButton_menu_vocals.setProperty("audioPlayer", True)
self.horizontalLayout_3.addWidget(self.pushButton_save_vocals)
self.horizontalLayout_3.addWidget(self.pushButton_menu_vocals)
self.verticalLayout_7.addWidget(self.frame_4)
@ -331,16 +331,16 @@ class Ui_MainWindow(object):
self.horizontalLayout_4.addWidget(self.horizontalSlider_instrumentals)
self.pushButton_save_instrumentals = QPushButton(self.frame_6)
self.pushButton_save_instrumentals.setObjectName(
u"pushButton_save_instrumentals")
self.pushButton_save_instrumentals.setMaximumSize(QSize(30, 30))
self.pushButton_save_instrumentals.setCursor(
self.pushButton_menu_instrumentals = QPushButton(self.frame_6)
self.pushButton_menu_instrumentals.setObjectName(
u"pushButton_menu_instrumentals")
self.pushButton_menu_instrumentals.setMaximumSize(QSize(30, 30))
self.pushButton_menu_instrumentals.setCursor(
QCursor(Qt.PointingHandCursor))
self.pushButton_save_instrumentals.setStyleSheet(u"")
self.pushButton_save_instrumentals.setProperty("audioPlayer", True)
self.pushButton_menu_instrumentals.setStyleSheet(u"")
self.pushButton_menu_instrumentals.setProperty("audioPlayer", True)
self.horizontalLayout_4.addWidget(self.pushButton_save_instrumentals)
self.horizontalLayout_4.addWidget(self.pushButton_menu_instrumentals)
self.verticalLayout_8.addWidget(self.frame_6)
@ -468,8 +468,8 @@ class Ui_MainWindow(object):
self.retranslateUi(MainWindow)
self.stackedWidget_musicFiles.setCurrentIndex(0)
self.stackedWidget_vocals.setCurrentIndex(0)
self.stackedWidget_instrumentals.setCurrentIndex(0)
self.stackedWidget_vocals.setCurrentIndex(1)
self.stackedWidget_instrumentals.setCurrentIndex(1)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
@ -495,11 +495,11 @@ class Ui_MainWindow(object):
self.label_vocalsFile.setText(
QCoreApplication.translate("MainWindow", u"Audio File", None))
self.pushButton_play_vocals.setText("")
self.pushButton_save_vocals.setText("")
self.pushButton_menu_vocals.setText("")
self.label_instrumentalFiles.setText(
QCoreApplication.translate("MainWindow", u"Audio File", None))
self.pushButton_play_instrumentals.setText("")
self.pushButton_save_instrumentals.setText("")
self.pushButton_menu_instrumentals.setText("")
self.label_instrumental.setText(
QCoreApplication.translate("MainWindow", u"Instrumentals", None))
self.label_vocals.setText(

View File

@ -7,7 +7,7 @@ from PySide2.QtGui import Qt
from PySide2.QtWinExtras import (QWinTaskbarButton)
from PySide2 import QtMultimedia
# -Root imports-
from ..resources.resources_manager import ResourcePaths
from ..resources.resources_manager import (ResourcePaths)
from ..inference import converter_v4
from .. import constants as const
from .design import mainwindow_ui
@ -44,39 +44,98 @@ def dict_to_HTMLtable(x: dict, header: str) -> str:
class AudioPlayer(QtMultimedia.QMediaPlayer):
def __init__(self, parent, wig_play_pause: QtWidgets.QPushButton, wig_slider: QtWidgets.QSlider):
"""
Custom Audio Player for playing seperated instrumentals and vocals embedded into the GUI
"""
# Frames to stop on to display given image (key)
PLAYPAUSE_STEPS = {
'play': 0,
'pause': 33
}
def __init__(self, parent, wig_play_pause: QtWidgets.QPushButton, wig_slider: QtWidgets.QSlider, wig_menu: QtWidgets.QPushButton):
super().__init__(parent=parent)
self.parent = parent
self.logger = parent.logger
self.wig_play_pause = wig_play_pause
self.wig_slider = wig_slider
self.wig_menu = wig_menu
self.last_state = self.state()
self.sliderPressed = False
# -Images-
self.playpause_gif = QtGui.QMovie(self.parent)
self.playpause_gif.setSpeed(110)
self.playpause_gif.setFileName(ResourcePaths.images.playpause_gif)
self.playpause_gif.frameChanged.connect(lambda: self.frameChanged())
self.playpause_gif.jumpToFrame(1)
self.playpause_gif.setPaused(True)
# Play/Pause
self.play_img = QtGui.QPixmap(ResourcePaths.images.audio_play)
self.pause_img = QtGui.QPixmap(ResourcePaths.images.audio_pause)
self.wig_play_pause.setIconSize(QtCore.QSize(23, 23))
self.wig_play_pause.setIconSize(QtCore.QSize(26, 26))
self.pause()
# Menu
self.menu_img = QtGui.QPixmap(ResourcePaths.images.menu)
self.wig_menu.setIcon(self.menu_img)
self.wig_menu.setIconSize(QtCore.QSize(15, 15))
# -Binds-
# Player
# Music Player
self.setNotifyInterval(50) # Smooth slider
self.error.connect(self.error_occurred)
self.durationChanged.connect(self.update_slider_max)
self.positionChanged.connect(self.update_slider)
# Widgets
self.wig_play_pause.pressed.connect(self.play_or_pause)
self.wig_slider.sliderPressed.connect(self.sliderPressed)
self.wig_slider.sliderReleased.connect(self.sliderReleased)
self.wig_slider.sliderPressed.connect(self.event_sliderPressed)
self.wig_slider.sliderReleased.connect(self.event_sliderReleased)
def frameChanged(self):
cur_frame = self.playpause_gif.currentFrameNumber()
if self.sliderPressed:
# Just finish gif
for frame in self.PLAYPAUSE_STEPS.values():
if cur_frame == frame:
# Pause frame
self.playpause_gif.setPaused(True)
else:
if self.state() == QtMultimedia.QMediaPlayer.PlayingState:
# Song is currently playing so finish aniamtion at pause img
pause_frame = self.PLAYPAUSE_STEPS['pause']
else:
# Song is currently paused so finish aniamtion at play img
pause_frame = self.PLAYPAUSE_STEPS['play']
if cur_frame == pause_frame:
# Current frame matches the pause frame so stop gif
self.playpause_gif.setPaused(True)
# Set Frame
self.wig_play_pause.setIcon(self.playpause_gif.currentPixmap())
def play(self):
self.wig_play_pause.setIcon(self.pause_img)
"""
Resume playing the song and update image to pause
"""
# Start gif
self.playpause_gif.setPaused(False)
# Play audio
super().play()
def pause(self):
self.wig_play_pause.setIcon(self.play_img)
"""
Pause output and update image to play
"""
# Start gif
self.playpause_gif.setPaused(False)
# Play audio
super().pause()
def play_or_pause(self):
"""
Switch play or pause based on QMusicPlayer's state
"""
if self.state() != QtMultimedia.QMediaPlayer.PlayingState:
# Not playing -> Play
self.play()
@ -84,32 +143,58 @@ class AudioPlayer(QtMultimedia.QMediaPlayer):
# Playing -> Pause
self.pause()
def sliderPressed(self):
def event_sliderPressed(self):
"""
Pause song and save last playing state so that if the song was
playing previously the song will continue as soon as slider is taken off
"""
self.last_state = self.state()
self.pause()
self.sliderPressed = True
super().pause()
def sliderReleased(self):
def event_sliderReleased(self):
"""
Update QMediaPlayer position and play song if has been playing before sliderPressed
"""
if self.last_state == QtMultimedia.QMediaPlayer.PlayingState:
self.play()
super().play()
self.sliderPressed = False
self.setPosition(self.wig_slider.value())
def set_song(self, path: str):
self.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))
def updateMedia(self, path: str):
"""
Update Audio file that is currently playing
"""
assert os.path.isfile(path), f'Path is invalid\nPath: "{path}"'
super().setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))
def update_slider_max(self, duration):
"""
Update sliders maximum value to the songs duration in ms
"""
self.wig_slider.setMaximum(duration)
def update_slider(self, position):
"""
Sync sliders position based on current progress of QMediaPlayer
"""
# Disable the events to prevent updating triggering a setPosition event (can cause stuttering).
self.wig_slider.blockSignals(True)
self.wig_slider.setValue(position)
self.wig_slider.blockSignals(False)
def error_occurred(self, *args):
self.logger.info(args)
"""
Log error
"""
self.logger.error(args)
class MainWindow(QtWidgets.QWidget):
"""
Main Window of UVR where seperation, progress and embedded seperated song-playing takes place
"""
def __init__(self, app: QtWidgets.QApplication):
# -Window setup-
super(MainWindow, self).__init__()
@ -128,12 +213,15 @@ class MainWindow(QtWidgets.QWidget):
self.instrumentals_audioPlayer = AudioPlayer(self,
self.ui.pushButton_play_instrumentals,
self.ui.horizontalSlider_instrumentals,)
self.ui.horizontalSlider_instrumentals,
self.ui.pushButton_menu_instrumentals)
self.vocals_audioPlayer = AudioPlayer(self,
self.ui.pushButton_play_vocals,
self.ui.horizontalSlider_vocals)
self.ui.horizontalSlider_vocals,
self.ui.pushButton_menu_vocals)
self._activate_audio_players()
# -Initialization methods-
def setup_window(self):
"""
Set up the window with binds, images, saved settings
@ -322,7 +410,7 @@ class MainWindow(QtWidgets.QWidget):
self.winTaskbar.setOverlayIcon(QtGui.QIcon(ResourcePaths.images.folder))
self.winTaskbar_progress.setVisible(True)
# Media player
self.deactivate_audio_players()
self._deactivate_audio_players()
def seperation_write(self, text: str):
"""
@ -384,6 +472,9 @@ class MainWindow(QtWidgets.QWidget):
# Error message was already displayed in the seperation_error function
self.logger.warn(msg=f'----- The seperation has failed! -----')
else:
# -Activate Audio Players-
self._activate_audio_players()
self.logger.info(msg=f'----- The seperation has finished! (in {elapsed_time}) -----')
if self.app.windows['settings'].ui.checkBox_notifiyOnFinish.isChecked():
msg = QtWidgets.QMessageBox()
@ -403,18 +494,29 @@ class MainWindow(QtWidgets.QWidget):
# -Reset progress-
seperation_reset()
# -Activate Audio Players-
QtCore.QTimer.singleShot(1000, lambda: self.activate_audio_players())
# -Enable Seperation Button
self.ui.pushButton_seperate.setEnabled(True)
def activate_audio_players(self):
def _activate_audio_players(self):
"""
Run after successful seperation
Switches to audio player page and updates media with recently saved temp files
"""
self.logger.info('Activating audio player mode...')
self.ui.stackedWidget_instrumentals.setCurrentIndex(1)
self.ui.stackedWidget_vocals.setCurrentIndex(1)
self.instrumentals_audioPlayer.set_song(ResourcePaths.temp_instrumental)
self.vocals_audioPlayer.set_song(ResourcePaths.temp_vocal)
self.instrumentals_audioPlayer.updateMedia(ResourcePaths.temp_instrumental)
self.vocals_audioPlayer.updateMedia(ResourcePaths.temp_vocal)
def deactivate_audio_players(self):
def _deactivate_audio_players(self):
"""
Run on start of seperation or when wanting to discard
Switches to basic page and updates media with empty objects to delete
any I/O connections that prevent the seperator to save the temporary files
"""
self.logger.info('Deactivating audio player mode...')
self.ui.stackedWidget_instrumentals.setCurrentIndex(0)
self.ui.stackedWidget_vocals.setCurrentIndex(0)
self.instrumentals_audioPlayer.stop()

View File

@ -17,6 +17,14 @@ import os
from typing import (Dict, )
class SettingsWindow(QtWidgets.QWidget):
"""
Settings window for UVR, available sections are:
- Seperation Settings: Modify settings, like model and ai engine for the seperation of audio files
- Shortcuts: Set shortcuts to quickly change settings or select other music files/new export directory
- Customization: Select from different themes for the application
- Preferences: Change personalised settings like language, export directory,
and whether to show the command line
"""
def __init__(self, app: QtWidgets.QApplication):
super(SettingsWindow, self).__init__()
self.ui = settingswindow_ui.Ui_SettingsWindow()

View File

@ -86,7 +86,7 @@ QPushButton[audioPlayer="true"] {
}
QSlider[audioPlayer="true"]::groove:horizontal {
background-color: rgb(66, 72, 83);
height: 6px;
height: 4px;
border-radius: 2px;
}
@ -94,8 +94,8 @@ QSlider[audioPlayer="true"]::handle:horizontal {
background-color: rgb(109, 213, 237);
border: 2px solid rgb(109, 213, 237);
width: 10px;
margin-top: -4px;
margin-bottom: -4px;
margin-top: -5px;
margin-bottom: -5px;
border-radius: 5px;
}
@ -378,7 +378,7 @@ QSlider[audioPlayer="true"]::handle:horizontal:hover {
<item row="1" column="2">
<widget class="QStackedWidget" name="stackedWidget_vocals">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="page_3">
<layout class="QVBoxLayout" name="verticalLayout_6">
@ -489,7 +489,7 @@ QSlider[audioPlayer=&quot;true&quot;]::handle:horizontal:hover {
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_save_vocals">
<widget class="QPushButton" name="pushButton_menu_vocals">
<property name="maximumSize">
<size>
<width>30</width>
@ -520,7 +520,7 @@ QSlider[audioPlayer=&quot;true&quot;]::handle:horizontal:hover {
<item row="0" column="2">
<widget class="QStackedWidget" name="stackedWidget_instrumentals">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_5">
@ -631,7 +631,7 @@ QSlider[audioPlayer=&quot;true&quot;]::handle:horizontal:hover {
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_save_instrumentals">
<widget class="QPushButton" name="pushButton_menu_instrumentals">
<property name="maximumSize">
<size>
<width>30</width>