faster Spectrum preview & custom VERBOSE loglvl
This commit is contained in:
parent
9c8792df9b
commit
bed07479f1
|
@ -1,5 +1,28 @@
|
|||
import sys
|
||||
import os
|
||||
import logging
|
||||
|
||||
|
||||
class Logger(logging.getLoggerClass()):
|
||||
'''
|
||||
Custom Logger class to handle custom VERBOSE log level.
|
||||
Levels used in this program are as follows:
|
||||
VERBOSE Annoyingly frequent debug messages (e.g, in loops)
|
||||
DEBUG Ordinary debug information
|
||||
INFO Expected events that are expensive or irreversible
|
||||
WARNING A non-fatal error or suspicious behaviour
|
||||
ERROR Any error that would interrupt the user
|
||||
CRITICAL Things that really shouldn't happen at all
|
||||
'''
|
||||
def __init__(self, name, level=logging.NOTSET):
|
||||
super().__init__(name, level)
|
||||
logging.addLevelName(5, "VERBOSE")
|
||||
|
||||
def verbose(self, msg, *args, **kwargs):
|
||||
if self.isEnabledFor(5):
|
||||
self._log(5, msg, args, **kwargs)
|
||||
logging.setLoggerClass(Logger)
|
||||
logging.VERBOSE = 5
|
||||
|
||||
|
||||
if getattr(sys, 'frozen', False):
|
||||
|
|
|
@ -39,6 +39,11 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
def renderWrapper(func):
|
||||
def renderWrapper(self, *args, **kwargs):
|
||||
try:
|
||||
log.verbose('### %s #%s renders%s frame %s###' % (
|
||||
self.__class__.name, str(self.compPos),
|
||||
'' if args else ' a preview',
|
||||
'' if not args else '%s ' % args[0],
|
||||
))
|
||||
return func(self, *args, **kwargs)
|
||||
except Exception as e:
|
||||
try:
|
||||
|
|
|
@ -27,6 +27,8 @@ class Component(Component):
|
|||
self._image = BlankFrame(self.width, self.height)
|
||||
self.chunkSize = 4 * self.width * self.height
|
||||
self.changedOptions = True
|
||||
self.previewSize = (214, 120)
|
||||
self.previewPipe = None
|
||||
|
||||
if hasattr(self.parent, 'window'):
|
||||
# update preview when audio file changes (if genericPreview is off)
|
||||
|
@ -72,7 +74,8 @@ class Component(Component):
|
|||
if not changedSize \
|
||||
and not self.changedOptions \
|
||||
and self.previewFrame is not None:
|
||||
log.debug('Comp #%s is reusing old preview frame' % self.compPos)
|
||||
log.debug(
|
||||
'Spectrum #%s is reusing old preview frame' % self.compPos)
|
||||
return self.previewFrame
|
||||
|
||||
frame = self.getPreviewFrame()
|
||||
|
@ -86,6 +89,7 @@ class Component(Component):
|
|||
|
||||
def preFrameRender(self, **kwargs):
|
||||
super().preFrameRender(**kwargs)
|
||||
self.previewPipe.wait()
|
||||
self.updateChunksize()
|
||||
w, h = scale(self.scale, self.width, self.height, str)
|
||||
self.video = FfmpegVideo(
|
||||
|
@ -141,18 +145,21 @@ class Component(Component):
|
|||
with open(logFilename, 'w') as logf:
|
||||
logf.write(" ".join(command) + '\n\n')
|
||||
with open(logFilename, 'a') as logf:
|
||||
pipe = openPipe(
|
||||
self.previewPipe = openPipe(
|
||||
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||
stderr=logf, bufsize=10**8
|
||||
)
|
||||
byteFrame = pipe.stdout.read(self.chunkSize)
|
||||
closePipe(pipe)
|
||||
byteFrame = self.previewPipe.stdout.read(self.chunkSize)
|
||||
closePipe(self.previewPipe)
|
||||
|
||||
frame = self.finalizeFrame(byteFrame)
|
||||
return frame
|
||||
|
||||
def makeFfmpegFilter(self, preview=False, startPt=0):
|
||||
w, h = scale(self.scale, self.width, self.height, str)
|
||||
if preview:
|
||||
w, h = self.previewSize
|
||||
else:
|
||||
w, h = (self.width, self.height)
|
||||
color = self.page.comboBox_color.currentText().lower()
|
||||
genericPreview = self.settings.value("pref_genericPreview")
|
||||
|
||||
|
@ -173,8 +180,7 @@ class Component(Component):
|
|||
'showspectrum=s=%sx%s:slide=scroll:win_func=%s:'
|
||||
'color=%s:scale=%s,'
|
||||
'colorkey=color=black:similarity=0.1:blend=0.5' % (
|
||||
self.settings.value("outputWidth"),
|
||||
self.settings.value("outputHeight"),
|
||||
w, h,
|
||||
self.page.comboBox_window.currentText(),
|
||||
color, amplitude,
|
||||
)
|
||||
|
@ -197,8 +203,7 @@ class Component(Component):
|
|||
filter_ = (
|
||||
'ahistogram=r=%s:s=%sx%s:dmode=separate:ascale=%s:scale=%s' % (
|
||||
self.settings.value("outputFrameRate"),
|
||||
self.settings.value("outputWidth"),
|
||||
self.settings.value("outputHeight"),
|
||||
w, h,
|
||||
amplitude, display
|
||||
)
|
||||
)
|
||||
|
@ -214,8 +219,7 @@ class Component(Component):
|
|||
m = self.page.comboBox_mode.currentText()
|
||||
filter_ = (
|
||||
'avectorscope=s=%sx%s:draw=%s:m=%s:scale=%s:zoom=%s' % (
|
||||
self.settings.value("outputWidth"),
|
||||
self.settings.value("outputHeight"),
|
||||
w, h,
|
||||
'line'if self.draw else 'dot',
|
||||
m, amplitude, str(self.zoom),
|
||||
)
|
||||
|
@ -225,8 +229,7 @@ class Component(Component):
|
|||
'showcqt=r=%s:s=%sx%s:count=30:text=0:tc=%s,'
|
||||
'colorkey=color=black:similarity=0.1:blend=0.5 ' % (
|
||||
self.settings.value("outputFrameRate"),
|
||||
self.settings.value("outputWidth"),
|
||||
self.settings.value("outputHeight"),
|
||||
w, h,
|
||||
str(self.tc),
|
||||
)
|
||||
)
|
||||
|
@ -235,28 +238,28 @@ class Component(Component):
|
|||
'aphasemeter=r=%s:s=%sx%s:video=1 [atrash][vtmp1]; '
|
||||
'[atrash] anullsink; '
|
||||
'[vtmp1] colorkey=color=black:similarity=0.1:blend=0.5, '
|
||||
'crop=in_w/8:in_h:(in_w/8)*7:0 '% (
|
||||
'crop=in_w/8:in_h:(in_w/8)*7:0 ' % (
|
||||
self.settings.value("outputFrameRate"),
|
||||
self.settings.value("outputWidth"),
|
||||
self.settings.value("outputHeight"),
|
||||
w, h,
|
||||
)
|
||||
)
|
||||
|
||||
return [
|
||||
'-filter_complex',
|
||||
'%s%s%s%s [v1]; '
|
||||
'[v1] %sscale=%s:%s%s%s%s [v]' % (
|
||||
'[v1] %s%s%s%s%s [v]' % (
|
||||
exampleSound() if preview and genericPreview else '[0:a] ',
|
||||
'compand=gain=4,' if self.compress else '',
|
||||
'aformat=channel_layouts=mono,' if self.mono else '',
|
||||
filter_,
|
||||
'hflip, ' if self.mirror else '',
|
||||
w, h,
|
||||
', hue=h=%s:s=10' % str(self.hue) if self.hue > 0 else '',
|
||||
', trim=start=%s:end=%s' % (
|
||||
'trim=start=%s:end=%s, ' % (
|
||||
"{0:.3f}".format(startPt + 12),
|
||||
"{0:.3f}".format(startPt + 12.5)
|
||||
) if preview else '',
|
||||
'scale=%sx%s' % scale(
|
||||
self.scale, self.width, self.height, str),
|
||||
', hue=h=%s:s=10' % str(self.hue) if self.hue > 0 else '',
|
||||
', convolution=-2 -1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2:-2 '
|
||||
'-1 0 -1 1 1 0 1 2:-2 -1 0 -1 1 1 0 1 2'
|
||||
if self.filterType == 3 else ''
|
||||
|
@ -281,10 +284,7 @@ class Component(Component):
|
|||
self._image = image
|
||||
except ValueError:
|
||||
image = self._image
|
||||
if self.scale != 100 \
|
||||
or self.x != 0 or self.y != 0:
|
||||
frame = BlankFrame(self.width, self.height)
|
||||
frame.paste(image, box=(self.x, self.y))
|
||||
else:
|
||||
frame = image
|
||||
|
||||
frame = BlankFrame(self.width, self.height)
|
||||
frame.paste(image, box=(self.x, self.y))
|
||||
return frame
|
||||
|
|
10
src/core.py
10
src/core.py
|
@ -562,9 +562,10 @@ class Core:
|
|||
logStream = logging.StreamHandler()
|
||||
logStream.setLevel(STDOUT_LOGLVL)
|
||||
|
||||
# create formatters and put everything together
|
||||
# create formatters for each stream
|
||||
fileFormatter = logging.Formatter(
|
||||
'[%(asctime)s] <%(name)s> %(levelname)s: %(message)s'
|
||||
'[%(asctime)s] %(threadName)-10.10s %(name)-23.23s %(levelname)s: '
|
||||
'%(message)s'
|
||||
)
|
||||
streamFormatter = logging.Formatter(
|
||||
'<%(name)s> %(message)s'
|
||||
|
@ -572,13 +573,14 @@ class Core:
|
|||
logFile.setFormatter(fileFormatter)
|
||||
libLogFile.setFormatter(fileFormatter)
|
||||
logStream.setFormatter(streamFormatter)
|
||||
|
||||
log = logging.getLogger('AVP')
|
||||
log.setLevel(FILE_LOGLVL)
|
||||
log.addHandler(logFile)
|
||||
log.addHandler(logStream)
|
||||
libLog = logging.getLogger()
|
||||
libLog.setLevel(FILE_LOGLVL)
|
||||
libLog.addHandler(libLogFile)
|
||||
# lowest level must be explicitly set on the root Logger
|
||||
libLog.setLevel(0)
|
||||
|
||||
# always store settings in class variables even if a Core object is not created
|
||||
Core.storeSettings()
|
||||
|
|
|
@ -44,7 +44,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
self.window = window
|
||||
self.core = Core()
|
||||
log.debug(
|
||||
'Main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
||||
'Main thread id: {}'.format(int(QtCore.QThread.currentThreadId())))
|
||||
|
||||
# widgets of component settings
|
||||
self.pages = []
|
||||
|
@ -465,8 +465,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
and filecmp.cmp(
|
||||
self.autosavePath, self.currentProject) == identical:
|
||||
log.debug(
|
||||
'Autosave found %s to be identical' % \
|
||||
'not' if not identical else ''
|
||||
'Autosave found %s to be identical'
|
||||
% 'not' if not identical else ''
|
||||
)
|
||||
return True
|
||||
except FileNotFoundError:
|
||||
|
|
|
@ -21,6 +21,7 @@ class FramePainter(QtGui.QPainter):
|
|||
Pillow image with finalize()
|
||||
'''
|
||||
def __init__(self, width, height):
|
||||
log.verbose('Creating new FramePainter')
|
||||
image = BlankFrame(width, height)
|
||||
self.image = QtGui.QImage(ImageQt(image))
|
||||
super().__init__(self.image)
|
||||
|
@ -77,7 +78,7 @@ def defaultSize(framefunc):
|
|||
|
||||
|
||||
def FloodFrame(width, height, RgbaTuple):
|
||||
log.debug('Creating new %s*%s %s flood frame' % (
|
||||
log.verbose('Creating new %s*%s %s flood frame' % (
|
||||
width, height, RgbaTuple))
|
||||
return Image.new("RGBA", (width, height), RgbaTuple)
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ class Worker(QtCore.QObject):
|
|||
compError[0]
|
||||
)
|
||||
)
|
||||
log.critical(errMsg)
|
||||
log.error(errMsg)
|
||||
comp._error.emit(errMsg, compError[1])
|
||||
break
|
||||
if 'static' in compProps:
|
||||
|
@ -221,7 +221,7 @@ class Worker(QtCore.QObject):
|
|||
|
||||
if self.canceled:
|
||||
if canceledByComponent:
|
||||
log.critical('Export cancelled by component #%s (%s): %s' % (
|
||||
log.error('Export cancelled by component #%s (%s): %s' % (
|
||||
compNo,
|
||||
comp.name,
|
||||
'No message.' if comp.error() is None else (
|
||||
|
|
Reference in New Issue