disable some hotkeys while encoding, more friendly error messages
This commit is contained in:
parent
45b55d8e2f
commit
a2838a0c38
|
@ -86,12 +86,14 @@ class Video:
|
||||||
continue
|
continue
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
self.parent.showMessage(
|
self.parent.showMessage(
|
||||||
msg='%s couldn\'t be loaded.' % os.path.basename(
|
msg='%s couldn\'t be loaded. '
|
||||||
|
'This is a fatal error.' % os.path.basename(
|
||||||
self.videoPath
|
self.videoPath
|
||||||
),
|
),
|
||||||
detail=str(e)
|
detail=str(e)
|
||||||
)
|
)
|
||||||
self.parent.stopVideo()
|
self.parent.stopVideo()
|
||||||
|
break
|
||||||
|
|
||||||
self.currentFrame = pipe.stdout.read(self.chunkSize)
|
self.currentFrame = pipe.stdout.read(self.chunkSize)
|
||||||
if len(self.currentFrame) != 0:
|
if len(self.currentFrame) != 0:
|
||||||
|
@ -258,21 +260,25 @@ def scale(scale, width, height, returntype=None):
|
||||||
|
|
||||||
|
|
||||||
def finalizeFrame(self, imageData, width, height):
|
def finalizeFrame(self, imageData, width, height):
|
||||||
if self.distort:
|
|
||||||
try:
|
try:
|
||||||
|
if self.distort:
|
||||||
image = Image.frombytes(
|
image = Image.frombytes(
|
||||||
'RGBA',
|
'RGBA',
|
||||||
(width, height),
|
(width, height),
|
||||||
imageData)
|
imageData)
|
||||||
except ValueError:
|
|
||||||
print('#### ignored invalid data caused by distortion ####')
|
|
||||||
image = self.blankFrame(width, height)
|
|
||||||
else:
|
else:
|
||||||
image = Image.frombytes(
|
image = Image.frombytes(
|
||||||
'RGBA',
|
'RGBA',
|
||||||
scale(self.scale, width, height, int),
|
scale(self.scale, width, height, int),
|
||||||
imageData)
|
imageData)
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
print(
|
||||||
|
'### BAD VIDEO SELECTED ###\n'
|
||||||
|
'Video will not export with these settings'
|
||||||
|
)
|
||||||
|
return self.blankFrame(width, height)
|
||||||
|
|
||||||
if self.scale != 100 \
|
if self.scale != 100 \
|
||||||
or self.xPosition != 0 or self.yPosition != 0:
|
or self.xPosition != 0 or self.yPosition != 0:
|
||||||
frame = self.blankFrame(width, height)
|
frame = self.blankFrame(width, height)
|
||||||
|
|
|
@ -7,6 +7,15 @@ import preview_thread
|
||||||
import video_thread
|
import video_thread
|
||||||
|
|
||||||
|
|
||||||
|
def disableWhenEncoding(func):
|
||||||
|
def decorator(*args):
|
||||||
|
if args[0].encoding:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return func(*args)
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def LoadDefaultSettings(self):
|
def LoadDefaultSettings(self):
|
||||||
self.resolutions = [
|
self.resolutions = [
|
||||||
'1920x1080',
|
'1920x1080',
|
||||||
|
|
|
@ -12,7 +12,7 @@ import core
|
||||||
import preview_thread
|
import preview_thread
|
||||||
import video_thread
|
import video_thread
|
||||||
from presetmanager import PresetManager
|
from presetmanager import PresetManager
|
||||||
from main import LoadDefaultSettings
|
from main import LoadDefaultSettings, disableWhenEncoding
|
||||||
|
|
||||||
|
|
||||||
class PreviewWindow(QtWidgets.QLabel):
|
class PreviewWindow(QtWidgets.QLabel):
|
||||||
|
@ -54,6 +54,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
self.pages = [] # widgets of component settings
|
self.pages = [] # widgets of component settings
|
||||||
self.lastAutosave = time.time()
|
self.lastAutosave = time.time()
|
||||||
|
self.encoding = False
|
||||||
|
|
||||||
# Create data directory, load/create settings
|
# Create data directory, load/create settings
|
||||||
self.dataDir = self.core.dataDir
|
self.dataDir = self.core.dataDir
|
||||||
|
@ -149,16 +150,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
for i, comp in enumerate(self.core.modules):
|
for i, comp in enumerate(self.core.modules):
|
||||||
action = self.compMenu.addAction(comp.Component.__doc__)
|
action = self.compMenu.addAction(comp.Component.__doc__)
|
||||||
action.triggered.connect(
|
action.triggered.connect(
|
||||||
lambda _, item=i: self.core.insertComponent(0, item, self))
|
lambda _, item=i: self.core.insertComponent(0, item, self)
|
||||||
|
)
|
||||||
|
|
||||||
self.window.pushButton_addComponent.setMenu(self.compMenu)
|
self.window.pushButton_addComponent.setMenu(self.compMenu)
|
||||||
|
|
||||||
componentList.dropEvent = self.dragComponent
|
componentList.dropEvent = self.dragComponent
|
||||||
componentList.itemSelectionChanged.connect(
|
componentList.itemSelectionChanged.connect(
|
||||||
self.changeComponentWidget)
|
self.changeComponentWidget
|
||||||
|
)
|
||||||
self.window.pushButton_removeComponent.clicked.connect(
|
self.window.pushButton_removeComponent.clicked.connect(
|
||||||
lambda _: self.removeComponent())
|
lambda: self.removeComponent()
|
||||||
|
)
|
||||||
|
|
||||||
componentList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
componentList.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||||
componentList.customContextMenuRequested.connect(
|
componentList.customContextMenuRequested.connect(
|
||||||
|
@ -173,7 +176,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
currentRes = i
|
currentRes = i
|
||||||
window.comboBox_resolution.setCurrentIndex(currentRes)
|
window.comboBox_resolution.setCurrentIndex(currentRes)
|
||||||
window.comboBox_resolution.currentIndexChanged.connect(
|
window.comboBox_resolution.currentIndexChanged.connect(
|
||||||
self.updateResolution)
|
self.updateResolution
|
||||||
|
)
|
||||||
|
|
||||||
self.window.pushButton_listMoveUp.clicked.connect(
|
self.window.pushButton_listMoveUp.clicked.connect(
|
||||||
lambda: self.moveComponent(-1)
|
lambda: self.moveComponent(-1)
|
||||||
|
@ -185,14 +189,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
# Configure the Projects Menu
|
# Configure the Projects Menu
|
||||||
self.projectMenu = QMenu()
|
self.projectMenu = QMenu()
|
||||||
self.window.menuButton_newProject = self.projectMenu.addAction(
|
self.window.menuButton_newProject = self.projectMenu.addAction(
|
||||||
"New Project")
|
"New Project"
|
||||||
|
)
|
||||||
self.window.menuButton_newProject.triggered.connect(
|
self.window.menuButton_newProject.triggered.connect(
|
||||||
self.createNewProject)
|
lambda: self.createNewProject()
|
||||||
|
)
|
||||||
self.window.menuButton_openProject = self.projectMenu.addAction(
|
self.window.menuButton_openProject = self.projectMenu.addAction(
|
||||||
"Open Project")
|
"Open Project"
|
||||||
|
)
|
||||||
self.window.menuButton_openProject.triggered.connect(
|
self.window.menuButton_openProject.triggered.connect(
|
||||||
self.openOpenProjectDialog)
|
lambda: self.openOpenProjectDialog()
|
||||||
|
)
|
||||||
|
|
||||||
action = self.projectMenu.addAction("Save Project")
|
action = self.projectMenu.addAction("Save Project")
|
||||||
action.triggered.connect(self.saveCurrentProject)
|
action.triggered.connect(self.saveCurrentProject)
|
||||||
|
@ -207,6 +214,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.openPresetManager
|
self.openPresetManager
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.updateWindowTitle()
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
if project and project != self.autosavePath:
|
if project and project != self.autosavePath:
|
||||||
|
@ -282,12 +290,15 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
def updateWindowTitle(self):
|
def updateWindowTitle(self):
|
||||||
appName = 'Audio Visualizer'
|
appName = 'Audio Visualizer'
|
||||||
|
try:
|
||||||
if self.currentProject:
|
if self.currentProject:
|
||||||
appName += ' - %s' % \
|
appName += ' - %s' % \
|
||||||
os.path.splitext(
|
os.path.splitext(
|
||||||
os.path.basename(self.currentProject))[0]
|
os.path.basename(self.currentProject))[0]
|
||||||
if self.autosaveExists(identical=False):
|
if self.autosaveExists(identical=False):
|
||||||
appName += '*'
|
appName += '*'
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
self.window.setWindowTitle(appName)
|
self.window.setWindowTitle(appName)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(int, dict)
|
@QtCore.pyqtSlot(int, dict)
|
||||||
|
@ -347,7 +358,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
if not self.currentProject:
|
if not self.currentProject:
|
||||||
if os.path.exists(self.autosavePath):
|
if os.path.exists(self.autosavePath):
|
||||||
os.remove(self.autosavePath)
|
os.remove(self.autosavePath)
|
||||||
elif force or time.time() - self.lastAutosave >= 2.0:
|
elif force or time.time() - self.lastAutosave >= 0.1:
|
||||||
self.core.createProjectFile(self.autosavePath)
|
self.core.createProjectFile(self.autosavePath)
|
||||||
self.lastAutosave = time.time()
|
self.lastAutosave = time.time()
|
||||||
|
|
||||||
|
@ -393,7 +404,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
"Video Files (%s);; All Files (*)" % " ".join(
|
"Video Files (%s);; All Files (*)" % " ".join(
|
||||||
self.core.videoFormats))
|
self.core.videoFormats))
|
||||||
|
|
||||||
if not fileName == "":
|
if fileName:
|
||||||
self.settings.setValue("outputDir", os.path.dirname(fileName))
|
self.settings.setValue("outputDir", os.path.dirname(fileName))
|
||||||
self.window.lineEdit_outputFile.setText(fileName)
|
self.window.lineEdit_outputFile.setText(fileName)
|
||||||
|
|
||||||
|
@ -404,8 +415,31 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
def createAudioVisualisation(self):
|
def createAudioVisualisation(self):
|
||||||
# create output video if mandatory settings are filled in
|
# create output video if mandatory settings are filled in
|
||||||
if self.window.lineEdit_audioFile.text() and \
|
audioFile = self.window.lineEdit_audioFile.text()
|
||||||
self.window.lineEdit_outputFile.text():
|
outputPath = self.window.lineEdit_outputFile.text()
|
||||||
|
|
||||||
|
if audioFile and outputPath and self.core.selectedComponents:
|
||||||
|
if not os.path.dirname(outputPath):
|
||||||
|
outputPath = os.path.join(
|
||||||
|
os.path.expanduser("~"), outputPath)
|
||||||
|
if outputPath and os.path.isdir(outputPath):
|
||||||
|
self.showMessage(
|
||||||
|
msg='Chosen filename matches a directory, which '
|
||||||
|
'cannot be overwritten. Please choose a different '
|
||||||
|
'filename or move the directory.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if not audioFile or not outputPath:
|
||||||
|
self.showMessage(
|
||||||
|
msg="You must select an audio file and output filename."
|
||||||
|
)
|
||||||
|
elif not self.core.selectedComponents:
|
||||||
|
self.showMessage(
|
||||||
|
msg="Not enough components."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
self.canceled = False
|
self.canceled = False
|
||||||
self.progressBarUpdated(-1)
|
self.progressBarUpdated(-1)
|
||||||
self.videoThread = QtCore.QThread(self)
|
self.videoThread = QtCore.QThread(self)
|
||||||
|
@ -418,19 +452,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.videoWorker.imageCreated.connect(self.showPreviewImage)
|
self.videoWorker.imageCreated.connect(self.showPreviewImage)
|
||||||
self.videoWorker.encoding.connect(self.changeEncodingStatus)
|
self.videoWorker.encoding.connect(self.changeEncodingStatus)
|
||||||
self.videoThread.start()
|
self.videoThread.start()
|
||||||
outputPath = self.window.lineEdit_outputFile.text()
|
|
||||||
if not os.path.dirname(outputPath):
|
|
||||||
outputPath = os.path.join(
|
|
||||||
os.path.expanduser("~"), outputPath)
|
|
||||||
self.videoTask.emit(
|
self.videoTask.emit(
|
||||||
self.window.lineEdit_audioFile.text(),
|
audioFile,
|
||||||
outputPath,
|
outputPath,
|
||||||
self.core.selectedComponents)
|
self.core.selectedComponents)
|
||||||
else:
|
|
||||||
self.showMessage(
|
|
||||||
msg="You must select an audio file and output filename.")
|
|
||||||
|
|
||||||
def changeEncodingStatus(self, status):
|
def changeEncodingStatus(self, status):
|
||||||
|
self.encoding = status
|
||||||
if status:
|
if status:
|
||||||
self.window.pushButton_createVideo.setEnabled(False)
|
self.window.pushButton_createVideo.setEnabled(False)
|
||||||
self.window.pushButton_Cancel.setEnabled(True)
|
self.window.pushButton_Cancel.setEnabled(True)
|
||||||
|
@ -598,6 +626,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.window.stackedWidget.removeWidget(widget)
|
self.window.stackedWidget.removeWidget(widget)
|
||||||
self.pages = []
|
self.pages = []
|
||||||
|
|
||||||
|
@disableWhenEncoding
|
||||||
def createNewProject(self):
|
def createNewProject(self):
|
||||||
self.openSaveChangesDialog('starting a new project')
|
self.openSaveChangesDialog('starting a new project')
|
||||||
|
|
||||||
|
@ -644,6 +673,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.core.createProjectFile(filename)
|
self.core.createProjectFile(filename)
|
||||||
self.updateWindowTitle()
|
self.updateWindowTitle()
|
||||||
|
|
||||||
|
@disableWhenEncoding
|
||||||
def openOpenProjectDialog(self):
|
def openOpenProjectDialog(self):
|
||||||
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
|
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
|
||||||
self.window, "Open Project File",
|
self.window, "Open Project File",
|
||||||
|
@ -669,6 +699,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
if self.window.listWidget_componentList.count() == 0:
|
if self.window.listWidget_componentList.count() == 0:
|
||||||
self.drawPreview()
|
self.drawPreview()
|
||||||
self.autosave(True)
|
self.autosave(True)
|
||||||
|
self.updateWindowTitle()
|
||||||
|
|
||||||
def showMessage(self, **kwargs):
|
def showMessage(self, **kwargs):
|
||||||
parent = kwargs['parent'] if 'parent' in kwargs else self.window
|
parent = kwargs['parent'] if 'parent' in kwargs else self.window
|
||||||
|
|
|
@ -50,16 +50,15 @@ class Worker(QtCore.QObject):
|
||||||
components = nextPreviewInformation["components"]
|
components = nextPreviewInformation["components"]
|
||||||
for component in reversed(components):
|
for component in reversed(components):
|
||||||
try:
|
try:
|
||||||
newFrame = component.previewRender(self)
|
|
||||||
frame = Image.alpha_composite(
|
frame = Image.alpha_composite(
|
||||||
frame, newFrame)
|
frame, component.previewRender(self)
|
||||||
except ValueError:
|
)
|
||||||
|
except ValueError as e:
|
||||||
self.parent.showMessage(
|
self.parent.showMessage(
|
||||||
msg="Bad frame returned by %s's previewRender method. "
|
msg="Bad frame returned by %s's previewRender method. "
|
||||||
"This is a fatal error." %
|
"This is a fatal error." %
|
||||||
str(component),
|
str(component),
|
||||||
detail="bad frame: w%s, h%s" % (
|
detail=str(e)
|
||||||
newFrame.width, newFrame.height)
|
|
||||||
)
|
)
|
||||||
quit(1)
|
quit(1)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ from PyQt5 import QtCore, QtGui, uic
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from PIL.ImageQt import ImageQt
|
from PIL.ImageQt import ImageQt
|
||||||
import core
|
|
||||||
import numpy
|
import numpy
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import sys
|
import sys
|
||||||
|
@ -13,6 +12,8 @@ import time
|
||||||
from copy import copy
|
from copy import copy
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
|
import core
|
||||||
|
|
||||||
|
|
||||||
class Worker(QtCore.QObject):
|
class Worker(QtCore.QObject):
|
||||||
|
|
||||||
|
@ -87,8 +88,10 @@ class Worker(QtCore.QObject):
|
||||||
self.encoding.emit(True)
|
self.encoding.emit(True)
|
||||||
self.components = components
|
self.components = components
|
||||||
self.outputFile = outputFile
|
self.outputFile = outputFile
|
||||||
self.bgI = 0 # tracked video frame
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
|
self.bgI = 0 # tracked video frame
|
||||||
self.width = int(self.core.settings.value('outputWidth'))
|
self.width = int(self.core.settings.value('outputWidth'))
|
||||||
self.height = int(self.core.settings.value('outputHeight'))
|
self.height = int(self.core.settings.value('outputHeight'))
|
||||||
progressBarValue = 0
|
progressBarValue = 0
|
||||||
|
@ -171,7 +174,7 @@ class Worker(QtCore.QObject):
|
||||||
self.staticComponents = {}
|
self.staticComponents = {}
|
||||||
numComps = len(self.components)
|
numComps = len(self.components)
|
||||||
for compNo, comp in enumerate(self.components):
|
for compNo, comp in enumerate(self.components):
|
||||||
pStr = "Analyzing audio..."
|
pStr = "Starting components..."
|
||||||
self.progressBarSetText.emit(pStr)
|
self.progressBarSetText.emit(pStr)
|
||||||
properties = None
|
properties = None
|
||||||
properties = comp.preFrameRender(
|
properties = comp.preFrameRender(
|
||||||
|
|
Reference in New Issue