aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--freeze.py4
-rw-r--r--setup.py4
-rw-r--r--src/__init__.py1
-rw-r--r--src/components/video.py4
-rw-r--r--src/core.py10
-rw-r--r--src/mainwindow.py135
-rw-r--r--src/presetmanager.py23
-rw-r--r--src/toolkit/ffmpeg.py9
8 files changed, 122 insertions, 68 deletions
diff --git a/freeze.py b/freeze.py
index 3281cad..520b445 100644
--- a/freeze.py
+++ b/freeze.py
@@ -2,7 +2,7 @@ from cx_Freeze import setup, Executable
import sys
import os
-from setup import VERSION
+from setup import __version__
deps = [os.path.join('src', p) for p in os.listdir('src') if p]
@@ -52,7 +52,7 @@ executables = [
setup(
name='audio-visualizer-python',
- version=VERSION,
+ version=__version__,
description='GUI tool to render visualization videos of audio files',
options=dict(build_exe=buildOptions),
executables=executables
diff --git a/setup.py b/setup.py
index 5abb976..a2d8495 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup
import os
-VERSION = '2.0.0.rc1'
+__version__ = '2.0.0.rc1'
def package_files(directory):
@@ -15,7 +15,7 @@ def package_files(directory):
setup(
name='audio_visualizer_python',
- version=VERSION,
+ version=__version__,
url='https://github.com/djfun/audio-visualizer-python/tree/feature-newgui',
license='MIT',
description='Create audio visualization videos from a GUI or commandline',
diff --git a/src/__init__.py b/src/__init__.py
index e69de29..8b13789 100644
--- a/src/__init__.py
+++ b/src/__init__.py
@@ -0,0 +1 @@
+
diff --git a/src/components/video.py b/src/components/video.py
index b35c2e5..8758b12 100644
--- a/src/components/video.py
+++ b/src/components/video.py
@@ -16,7 +16,7 @@ class Video:
'''Video Component Frame-Fetcher'''
def __init__(self, **kwargs):
mandatoryArgs = [
- 'ffmpeg', # path to ffmpeg, usually core.FFMPEG_BIN
+ 'ffmpeg', # path to ffmpeg, usually Core.FFMPEG_BIN
'videoPath',
'width',
'height',
@@ -28,7 +28,7 @@ class Video:
]
for arg in mandatoryArgs:
try:
- exec('self.%s = kwargs[arg]' % arg)
+ setattr(self, arg, kwargs[arg])
except KeyError:
raise BadComponentInit(arg, self.__doc__)
diff --git a/src/core.py b/src/core.py
index dd2ef18..f6cf5eb 100644
--- a/src/core.py
+++ b/src/core.py
@@ -15,16 +15,14 @@ import video_thread
class Core:
'''
MainWindow and Command module both use an instance of this class
- to store the main program state. This object tracks the components
- as an instance, has methods for managing the components and for
- opening/creating project files and presets.
+ to store the core program state. This object tracks the components,
+ talks to the components and handles opening/creating project files
+ and presets. The class also stores constants as class variables.
'''
@classmethod
def storeSettings(cls):
- '''
- Stores settings/paths to directories as class variables
- '''
+ '''Store settings/paths to directories as class variables.'''
if getattr(sys, 'frozen', False):
# frozen
wd = os.path.dirname(sys.executable)
diff --git a/src/mainwindow.py b/src/mainwindow.py
index 9944d1a..2d598ae 100644
--- a/src/mainwindow.py
+++ b/src/mainwindow.py
@@ -178,7 +178,6 @@ class MainWindow(QtWidgets.QMainWindow):
# Make component buttons
self.compMenu = QMenu()
- self.compActions = []
for i, comp in enumerate(self.core.modules):
action = self.compMenu.addAction(comp.Component.name)
action.triggered.connect(
@@ -191,6 +190,9 @@ class MainWindow(QtWidgets.QMainWindow):
componentList.itemSelectionChanged.connect(
self.changeComponentWidget
)
+ componentList.itemSelectionChanged.connect(
+ self.presetManager.clearPresetListSelection
+ )
self.window.pushButton_removeComponent.clicked.connect(
lambda: self.removeComponent()
)
@@ -313,22 +315,23 @@ class MainWindow(QtWidgets.QMainWindow):
)
self.settings.setValue("ffmpegMsgShown", True)
- # Setup Hotkeys
+ # Hotkeys for projects
QtWidgets.QShortcut("Ctrl+S", self.window, self.saveCurrentProject)
QtWidgets.QShortcut("Ctrl+A", self.window, self.openSaveProjectDialog)
QtWidgets.QShortcut("Ctrl+O", self.window, self.openOpenProjectDialog)
QtWidgets.QShortcut("Ctrl+N", self.window, self.createNewProject)
- QtWidgets.QShortcut(
- "Ctrl+Alt+Shift+R", self.window, self.drawPreview
- )
- QtWidgets.QShortcut(
- "Ctrl+Alt+Shift+F", self.window, self.showFfmpegCommand
- )
- QtWidgets.QShortcut(
- "Ctrl+T", self.window,
- activated=lambda: self.window.pushButton_addComponent.click()
- )
+ # Hotkeys for component list
+ for inskey in ("Ctrl+T", QtCore.Qt.Key_Insert):
+ QtWidgets.QShortcut(
+ inskey, self.window,
+ activated=lambda: self.window.pushButton_addComponent.click()
+ )
+ for delkey in ("Ctrl+R", QtCore.Qt.Key_Delete):
+ QtWidgets.QShortcut(
+ delkey, self.window.listWidget_componentList,
+ self.removeComponent
+ )
QtWidgets.QShortcut(
"Ctrl+Space", self.window,
activated=lambda: self.window.listWidget_componentList.setFocus()
@@ -342,22 +345,29 @@ class MainWindow(QtWidgets.QMainWindow):
)
QtWidgets.QShortcut(
- "Ctrl+Up", self.window,
+ "Ctrl+Up", self.window.listWidget_componentList,
activated=lambda: self.moveComponent(-1)
)
QtWidgets.QShortcut(
- "Ctrl+Down", self.window,
+ "Ctrl+Down", self.window.listWidget_componentList,
activated=lambda: self.moveComponent(1)
)
QtWidgets.QShortcut(
- "Ctrl+Home", self.window,
+ "Ctrl+Home", self.window.listWidget_componentList,
activated=lambda: self.moveComponent('top')
)
QtWidgets.QShortcut(
- "Ctrl+End", self.window,
+ "Ctrl+End", self.window.listWidget_componentList,
activated=lambda: self.moveComponent('bottom')
)
- QtWidgets.QShortcut("Ctrl+r", self.window, self.removeComponent)
+
+ # Debug Hotkeys
+ QtWidgets.QShortcut(
+ "Ctrl+Alt+Shift+R", self.window, self.drawPreview
+ )
+ QtWidgets.QShortcut(
+ "Ctrl+Alt+Shift+F", self.window, self.showFfmpegCommand
+ )
@QtCore.pyqtSlot()
def cleanUp(self):
@@ -677,9 +687,7 @@ class MainWindow(QtWidgets.QMainWindow):
stackedWidget.setCurrentIndex(newRow)
self.drawPreview()
- @disableWhenEncoding
- def dragComponent(self, event):
- '''Used as Qt drop event for the component listwidget'''
+ def getComponentListRects(self):
componentList = self.window.listWidget_componentList
modelIndexes = [
@@ -690,6 +698,13 @@ class MainWindow(QtWidgets.QMainWindow):
componentList.visualRect(modelIndex)
for modelIndex in modelIndexes
]
+ return rects
+
+ @disableWhenEncoding
+ def dragComponent(self, event):
+ '''Used as Qt drop event for the component listwidget'''
+ componentList = self.window.listWidget_componentList
+ rects = self.getComponentListRects()
rowPos = [rect.contains(event.pos()) for rect in rects]
if not any(rowPos):
@@ -826,47 +841,63 @@ class MainWindow(QtWidgets.QMainWindow):
@disableWhenEncoding
def componentContextMenu(self, QPos):
- '''Appears when right-clicking a component in the list'''
+ '''Appears when right-clicking the component list'''
componentList = self.window.listWidget_componentList
- if not componentList.selectedItems():
- return
-
- # don't show menu if clicking empty space
- parentPosition = componentList.mapToGlobal(QtCore.QPoint(0, 0))
index = componentList.currentRow()
- modelIndex = componentList.model().index(index)
- if not componentList.visualRect(modelIndex).contains(QPos):
- return
- self.presetManager.findPresets()
self.menu = QMenu()
- menuItem = self.menu.addAction("Save Preset")
- menuItem.triggered.connect(
- self.presetManager.openSavePresetDialog
- )
+ parentPosition = componentList.mapToGlobal(QtCore.QPoint(0, 0))
- # submenu for opening presets
- try:
- presets = self.presetManager.presets[
- str(self.core.selectedComponents[index])
- ]
- self.submenu = QMenu("Open Preset")
- self.menu.addMenu(self.submenu)
-
- for version, presetName in presets:
- menuItem = self.submenu.addAction(presetName)
+ rects = self.getComponentListRects()
+ rowPos = [rect.contains(QPos) for rect in rects]
+ if not any(rowPos):
+ # Insert components at the top if clicking nothing
+ rowPos = 0
+ else:
+ rowPos = rowPos.index(True)
+
+ if index == rowPos:
+ # Show preset menu if clicking a component
+ self.presetManager.findPresets()
+ menuItem = self.menu.addAction("Save Preset")
+ menuItem.triggered.connect(
+ self.presetManager.openSavePresetDialog
+ )
+
+ # submenu for opening presets
+ try:
+ presets = self.presetManager.presets[
+ str(self.core.selectedComponents[index])
+ ]
+ self.presetSubmenu = QMenu("Open Preset")
+ self.menu.addMenu(self.presetSubmenu)
+
+ for version, presetName in presets:
+ menuItem = self.presetSubmenu.addAction(presetName)
+ menuItem.triggered.connect(
+ lambda _, presetName=presetName:
+ self.presetManager.openPreset(presetName)
+ )
+ except KeyError:
+ pass
+
+ if self.core.selectedComponents[index].currentPreset:
+ menuItem = self.menu.addAction("Clear Preset")
menuItem.triggered.connect(
- lambda _, presetName=presetName:
- self.presetManager.openPreset(presetName)
+ self.presetManager.clearPreset
)
- except KeyError:
- pass
+ self.menu.addSeparator()
- if self.core.selectedComponents[index].currentPreset:
- menuItem = self.menu.addAction("Clear Preset")
+ # "Add Component" submenu
+ self.submenu = QMenu("Add")
+ self.menu.addMenu(self.submenu)
+ for i, comp in enumerate(self.core.modules):
+ menuItem = self.submenu.addAction(comp.Component.name)
menuItem.triggered.connect(
- self.presetManager.clearPreset
- )
+ lambda _, item=i: self.core.insertComponent(
+ rowPos, item, self
+ )
+ )
self.menu.move(parentPosition + QPos)
self.menu.show()
diff --git a/src/presetmanager.py b/src/presetmanager.py
index 825fdee..64e2203 100644
--- a/src/presetmanager.py
+++ b/src/presetmanager.py
@@ -245,11 +245,25 @@ class PresetManager(QtWidgets.QDialog):
def openRenamePresetDialog(self):
# TODO: maintain consistency by changing this to call createNewPreset()
presetList = self.window.listWidget_presets
- if presetList.currentRow() == -1:
- return
+ index = presetList.currentRow()
+ if index == -1:
+ # check if component selected in MainWindow has preset loaded
+ componentList = self.parent.window.listWidget_componentList
+ compIndex = componentList.currentRow()
+ if compIndex == -1:
+ return
+ preset = self.core.selectedComponents[compIndex].currentPreset
+ if not preset:
+ return
+ else:
+ for i, tup in enumerate(self.presetRows):
+ if preset == tup[2]:
+ index = i
+ break
+ else:
+ return
while True:
- index = presetList.currentRow()
newName, OK = QtWidgets.QInputDialog.getText(
self.window,
'Preset Manager',
@@ -321,3 +335,6 @@ class PresetManager(QtWidgets.QDialog):
parent=self.window
)
self.settings.setValue("presetDir", os.path.dirname(filename))
+
+ def clearPresetListSelection(self):
+ self.window.listWidget_presets.setCurrentRow(-1)
diff --git a/src/toolkit/ffmpeg.py b/src/toolkit/ffmpeg.py
index 89d4e9d..cc59a6c 100644
--- a/src/toolkit/ffmpeg.py
+++ b/src/toolkit/ffmpeg.py
@@ -113,7 +113,7 @@ def createFfmpegCommand(inputFile, outputFile, components, duration=-1):
'-t', safeDuration,
# Tell ffmpeg about shorter clips (seemingly not needed)
# streamDuration = getAudioDuration(extraInputFile)
- # if streamDuration > float(safeDuration)
+ # if streamDuration and streamDuration > float(safeDuration)
# else "{0:.3f}".format(streamDuration),
'-i', extraInputFile
])
@@ -228,11 +228,18 @@ def getAudioDuration(filename):
d = d.split(' ')[3]
d = d.split(':')
duration = float(d[0])*3600 + float(d[1])*60 + float(d[2])
+ break
+ else:
+ # String not found in output
+ return False
return duration
def readAudioFile(filename, parent):
duration = getAudioDuration(filename)
+ if not duration:
+ print('Audio file doesn\'t exist or unreadable.')
+ return
command = [
Core.FFMPEG_BIN,