error can be locked within properties()
and simplified the componenterrors again
This commit is contained in:
parent
661526b073
commit
15d70474d4
|
@ -19,7 +19,7 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
return func(self, *args, **kwargs)
|
||||
except Exception:
|
||||
try:
|
||||
raise ComponentInitError(self, 'initialization process')
|
||||
raise ComponentError(self, 'initialization process')
|
||||
except ComponentError:
|
||||
return
|
||||
return initializationWrapper
|
||||
|
@ -63,7 +63,13 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
if self._lockedProperties is not None:
|
||||
return self._lockedProperties
|
||||
else:
|
||||
return func(self)
|
||||
try:
|
||||
return func(self)
|
||||
except Exception:
|
||||
try:
|
||||
raise ComponentError(self, 'properties')
|
||||
except ComponentError:
|
||||
return []
|
||||
return propertiesWrapper
|
||||
|
||||
def errorWrapper(func):
|
||||
|
@ -396,18 +402,18 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
'''
|
||||
|
||||
|
||||
class ComponentException(RuntimeError):
|
||||
'''A base class for component errors'''
|
||||
class ComponentError(RuntimeError):
|
||||
'''Gives the MainWindow a traceback to display, and cancels the export.'''
|
||||
|
||||
_prevErrors = []
|
||||
prevErrors = []
|
||||
|
||||
def __init__(self, caller, name, immediate):
|
||||
def __init__(self, caller, name):
|
||||
print('ComponentError by %s: %s' % (caller.name, name))
|
||||
super().__init__()
|
||||
if len(ComponentException._prevErrors) > 1:
|
||||
ComponentException._prevErrors.pop()
|
||||
ComponentException._prevErrors.insert(0, name)
|
||||
if name in ComponentException._prevErrors[1:]:
|
||||
if len(ComponentError.prevErrors) > 1:
|
||||
ComponentError.prevErrors.pop()
|
||||
ComponentError.prevErrors.insert(0, name)
|
||||
if name in ComponentError.prevErrors[1:]:
|
||||
# Don't create multiple windows for repeated messages
|
||||
return
|
||||
|
||||
|
@ -434,28 +440,4 @@ class ComponentException(RuntimeError):
|
|||
)
|
||||
)
|
||||
|
||||
if immediate:
|
||||
caller._error.emit(string, detail)
|
||||
else:
|
||||
caller.lockProperties(['error'])
|
||||
caller.lockError((string, detail))
|
||||
|
||||
|
||||
class ComponentError(ComponentException):
|
||||
'''
|
||||
Use for general Python errors caused by a component at any time.
|
||||
Raising this gives the MainWindow a traceback to display and
|
||||
cancels any export in progress.
|
||||
'''
|
||||
def __init__(self, caller, name):
|
||||
ComponentException.__init__(self, caller, name, True)
|
||||
|
||||
|
||||
class ComponentInitError(ComponentError):
|
||||
'''
|
||||
Use for Python errors in preFrameRender, while the export is starting.
|
||||
This will end the video thread in a clean way by locking the component
|
||||
into an error state so the export definitely won't begin.
|
||||
'''
|
||||
def __init__(self, caller, name):
|
||||
ComponentException.__init__(self, caller, name, False)
|
||||
caller._error.emit(string, detail)
|
||||
|
|
|
@ -154,33 +154,28 @@ class Component(Component):
|
|||
return frame
|
||||
|
||||
def properties(self):
|
||||
# TODO: Disallow selecting the same video you're exporting to
|
||||
props = []
|
||||
if not self.videoPath or self.badVideo \
|
||||
or not os.path.exists(self.videoPath):
|
||||
return ['error']
|
||||
|
||||
if not self.videoPath:
|
||||
self.lockError("There is no video selected.")
|
||||
elif self.badVideo:
|
||||
self.lockError("Could not identify an audio stream in this video.")
|
||||
elif not os.path.exists(self.videoPath):
|
||||
self.lockError("The video selected does not exist!")
|
||||
elif (os.path.realpath(self.videoPath) ==
|
||||
os.path.realpath(
|
||||
self.parent.window.lineEdit_outputFile.text())):
|
||||
self.lockError("Input and output paths match.")
|
||||
|
||||
if self.useAudio:
|
||||
props.append('audio')
|
||||
self.testAudioStream()
|
||||
if self.badAudio:
|
||||
return ['error']
|
||||
if not testAudioStream(self.videoPath) \
|
||||
and self.error() is None:
|
||||
self.lockError(
|
||||
"Could not identify an audio stream in this video.")
|
||||
|
||||
return props
|
||||
|
||||
def error(self):
|
||||
if self.badAudio:
|
||||
return "Could not identify an audio stream in this video."
|
||||
if not self.videoPath:
|
||||
return "There is no video selected."
|
||||
if not os.path.exists(self.videoPath):
|
||||
return "The video selected does not exist!"
|
||||
if self.badVideo:
|
||||
return "The video selected is corrupt!"
|
||||
|
||||
def testAudioStream(self):
|
||||
self.badAudio = testAudioStream(self.videoPath)
|
||||
|
||||
def audio(self):
|
||||
params = {}
|
||||
if self.volume != 1.0:
|
||||
|
|
|
@ -573,16 +573,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
|
||||
@QtCore.pyqtSlot(str, str)
|
||||
def videoThreadError(self, msg, detail):
|
||||
self.showMessage(
|
||||
msg=msg,
|
||||
detail=detail,
|
||||
icon='Warning',
|
||||
)
|
||||
try:
|
||||
self.stopVideo()
|
||||
except AttributeError as e:
|
||||
if 'videoWorker' not in str(e):
|
||||
raise
|
||||
self.showMessage(
|
||||
msg=msg,
|
||||
detail=detail,
|
||||
icon='Warning',
|
||||
)
|
||||
|
||||
def changeEncodingStatus(self, status):
|
||||
self.encoding = status
|
||||
|
|
Binary file not shown.
|
@ -224,9 +224,9 @@ def testAudioStream(filename):
|
|||
try:
|
||||
checkOutput(audioTestCommand, stderr=subprocess.DEVNULL)
|
||||
except subprocess.CalledProcessError:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def getAudioDuration(filename):
|
||||
|
|
|
@ -163,24 +163,27 @@ class Worker(QtCore.QObject):
|
|||
except ComponentError:
|
||||
pass
|
||||
|
||||
if 'error' in comp.properties():
|
||||
compProps = comp.properties()
|
||||
if 'error' in compProps or comp.error() is not None:
|
||||
self.cancel()
|
||||
self.canceled = True
|
||||
canceledByComponent = True
|
||||
compError = comp.error() \
|
||||
if type(comp.error()) is tuple else (comp.error(), '')
|
||||
errMsg = (
|
||||
"Component #%s encountered an error!" % compNo
|
||||
"Component #%s (%s) encountered an error!" % (
|
||||
str(compNo), comp.name
|
||||
)
|
||||
if comp.error() is None else
|
||||
'Export cancelled by component #%s (%s): %s' % (
|
||||
str(compNo),
|
||||
str(comp),
|
||||
comp.name,
|
||||
compError[0]
|
||||
)
|
||||
)
|
||||
comp._error.emit(errMsg, compError[1])
|
||||
break
|
||||
if 'static' in comp.properties():
|
||||
if 'static' in compProps:
|
||||
self.staticComponents[compNo] = \
|
||||
comp.frameRender(compNo, 0).copy()
|
||||
|
||||
|
|
Reference in New Issue