using the builtin logging module
This commit is contained in:
parent
8baa24e878
commit
1c4afc96d6
|
@ -8,6 +8,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
from toolkit.frame import BlankFrame
|
from toolkit.frame import BlankFrame
|
||||||
from toolkit import (
|
from toolkit import (
|
||||||
|
@ -15,6 +16,9 @@ from toolkit import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.ComponentHandler')
|
||||||
|
|
||||||
|
|
||||||
class ComponentMetaclass(type(QtCore.QObject)):
|
class ComponentMetaclass(type(QtCore.QObject)):
|
||||||
'''
|
'''
|
||||||
Checks the validity of each Component class and mutates some attrs.
|
Checks the validity of each Component class and mutates some attrs.
|
||||||
|
@ -135,17 +139,17 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
||||||
# Turn version string into a number
|
# Turn version string into a number
|
||||||
try:
|
try:
|
||||||
if 'version' not in attrs:
|
if 'version' not in attrs:
|
||||||
print(
|
log.error(
|
||||||
'No version attribute in %s. Defaulting to 1' %
|
'No version attribute in %s. Defaulting to 1' %
|
||||||
attrs['name'])
|
attrs['name'])
|
||||||
attrs['version'] = 1
|
attrs['version'] = 1
|
||||||
else:
|
else:
|
||||||
attrs['version'] = int(attrs['version'].split('.')[0])
|
attrs['version'] = int(attrs['version'].split('.')[0])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print('%s component has an invalid version string:\n%s' % (
|
log.critical('%s component has an invalid version string:\n%s' % (
|
||||||
attrs['name'], str(attrs['version'])))
|
attrs['name'], str(attrs['version'])))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print('%s component has no version string.' % attrs['name'])
|
log.critical('%s component has no version string.' % attrs['name'])
|
||||||
else:
|
else:
|
||||||
return super().__new__(cls, name, parents, attrs)
|
return super().__new__(cls, name, parents, attrs)
|
||||||
quit(1)
|
quit(1)
|
||||||
|
@ -546,6 +550,8 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
||||||
and oldRelativeVal != newRelativeVal:
|
and oldRelativeVal != newRelativeVal:
|
||||||
# Float changed without pixel value changing, which
|
# Float changed without pixel value changing, which
|
||||||
# means the pixel value needs to be updated
|
# means the pixel value needs to be updated
|
||||||
|
log.debug('Updating %s #%s\'s relative widget: %s' % (
|
||||||
|
self.name, self.compPos, attr))
|
||||||
self._trackedWidgets[attr].blockSignals(True)
|
self._trackedWidgets[attr].blockSignals(True)
|
||||||
self.updateRelativeWidgetMaximum(attr)
|
self.updateRelativeWidgetMaximum(attr)
|
||||||
pixelVal = self.pixelValForAttr(attr, oldRelativeVal)
|
pixelVal = self.pixelValForAttr(attr, oldRelativeVal)
|
||||||
|
@ -576,7 +582,7 @@ class ComponentError(RuntimeError):
|
||||||
msg = str(sys.exc_info()[1])
|
msg = str(sys.exc_info()[1])
|
||||||
else:
|
else:
|
||||||
msg = 'Unknown error.'
|
msg = 'Unknown error.'
|
||||||
print("##### ComponentError by %s's %s: %s" % (
|
log.error("ComponentError by %s's %s: %s" % (
|
||||||
caller.name, name, msg))
|
caller.name, name, msg))
|
||||||
|
|
||||||
# Don't create multiple windows for quickly repeated messages
|
# Don't create multiple windows for quickly repeated messages
|
||||||
|
|
|
@ -4,6 +4,7 @@ import os
|
||||||
import math
|
import math
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
from component import Component
|
from component import Component
|
||||||
from toolkit.frame import BlankFrame, scale
|
from toolkit.frame import BlankFrame, scale
|
||||||
|
@ -13,6 +14,9 @@ from toolkit.ffmpeg import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Components.Spectrum')
|
||||||
|
|
||||||
|
|
||||||
class Component(Component):
|
class Component(Component):
|
||||||
name = 'Spectrum'
|
name = 'Spectrum'
|
||||||
version = '1.0.0'
|
version = '1.0.0'
|
||||||
|
@ -68,6 +72,7 @@ class Component(Component):
|
||||||
if not changedSize \
|
if not changedSize \
|
||||||
and not self.changedOptions \
|
and not self.changedOptions \
|
||||||
and self.previewFrame is not None:
|
and self.previewFrame is not None:
|
||||||
|
log.debug('Comp #%s is reusing old preview frame' % self.compPos)
|
||||||
return self.previewFrame
|
return self.previewFrame
|
||||||
|
|
||||||
frame = self.getPreviewFrame()
|
frame = self.getPreviewFrame()
|
||||||
|
@ -131,13 +136,14 @@ class Component(Component):
|
||||||
'-frames:v', '1',
|
'-frames:v', '1',
|
||||||
])
|
])
|
||||||
logFilename = os.path.join(
|
logFilename = os.path.join(
|
||||||
self.core.dataDir, 'preview_%s.log' % str(self.compPos))
|
self.core.logDir, 'preview_%s.log' % str(self.compPos))
|
||||||
with open(logFilename, 'w') as log:
|
log.debug('Creating ffmpeg process (log at %s)' % logFilename)
|
||||||
log.write(" ".join(command) + '\n\n')
|
with open(logFilename, 'w') as logf:
|
||||||
with open(logFilename, 'a') as log:
|
logf.write(" ".join(command) + '\n\n')
|
||||||
|
with open(logFilename, 'a') as logf:
|
||||||
pipe = openPipe(
|
pipe = openPipe(
|
||||||
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||||
stderr=log, bufsize=10**8
|
stderr=logf, bufsize=10**8
|
||||||
)
|
)
|
||||||
byteFrame = pipe.stdout.read(self.chunkSize)
|
byteFrame = pipe.stdout.read(self.chunkSize)
|
||||||
closePipe(pipe)
|
closePipe(pipe)
|
||||||
|
|
|
@ -3,6 +3,7 @@ from PyQt5 import QtGui, QtCore, QtWidgets
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import logging
|
||||||
|
|
||||||
from component import Component
|
from component import Component
|
||||||
from toolkit.frame import BlankFrame, scale
|
from toolkit.frame import BlankFrame, scale
|
||||||
|
@ -10,6 +11,9 @@ from toolkit.ffmpeg import openPipe, closePipe, testAudioStream, FfmpegVideo
|
||||||
from toolkit import checkOutput
|
from toolkit import checkOutput
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Components.Video')
|
||||||
|
|
||||||
|
|
||||||
class Component(Component):
|
class Component(Component):
|
||||||
name = 'Video'
|
name = 'Video'
|
||||||
version = '1.0.0'
|
version = '1.0.0'
|
||||||
|
@ -134,10 +138,17 @@ class Component(Component):
|
||||||
'-ss', '90',
|
'-ss', '90',
|
||||||
'-frames:v', '1',
|
'-frames:v', '1',
|
||||||
])
|
])
|
||||||
pipe = openPipe(
|
|
||||||
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
logFilename = os.path.join(
|
||||||
stderr=subprocess.DEVNULL, bufsize=10**8
|
self.core.logDir, 'preview_%s.log' % str(self.compPos))
|
||||||
)
|
log.debug('Creating ffmpeg process (log at %s)' % logFilename)
|
||||||
|
with open(logFilename, 'w') as logf:
|
||||||
|
logf.write(" ".join(command) + '\n\n')
|
||||||
|
with open(logFilename, 'a') as logf:
|
||||||
|
pipe = openPipe(
|
||||||
|
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||||
|
stderr=logf, bufsize=10**8
|
||||||
|
)
|
||||||
byteFrame = pipe.stdout.read(self.chunkSize)
|
byteFrame = pipe.stdout.read(self.chunkSize)
|
||||||
closePipe(pipe)
|
closePipe(pipe)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from PyQt5.QtGui import QColor
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import logging
|
||||||
|
|
||||||
from component import Component
|
from component import Component
|
||||||
from toolkit.frame import BlankFrame, scale
|
from toolkit.frame import BlankFrame, scale
|
||||||
|
@ -13,6 +14,9 @@ from toolkit.ffmpeg import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Components.Waveform')
|
||||||
|
|
||||||
|
|
||||||
class Component(Component):
|
class Component(Component):
|
||||||
name = 'Waveform'
|
name = 'Waveform'
|
||||||
version = '1.0.0'
|
version = '1.0.0'
|
||||||
|
@ -106,10 +110,16 @@ class Component(Component):
|
||||||
'-codec:v', 'rawvideo', '-',
|
'-codec:v', 'rawvideo', '-',
|
||||||
'-frames:v', '1',
|
'-frames:v', '1',
|
||||||
])
|
])
|
||||||
pipe = openPipe(
|
logFilename = os.path.join(
|
||||||
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
self.core.logDir, 'preview_%s.log' % str(self.compPos))
|
||||||
stderr=subprocess.DEVNULL, bufsize=10**8
|
log.debug('Creating ffmpeg process (log at %s)' % logFilename)
|
||||||
)
|
with open(logFilename, 'w') as logf:
|
||||||
|
logf.write(" ".join(command) + '\n\n')
|
||||||
|
with open(logFilename, 'a') as logf:
|
||||||
|
pipe = openPipe(
|
||||||
|
command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||||
|
stderr=logf, bufsize=10**8
|
||||||
|
)
|
||||||
byteFrame = pipe.stdout.read(self.chunkSize)
|
byteFrame = pipe.stdout.read(self.chunkSize)
|
||||||
closePipe(pipe)
|
closePipe(pipe)
|
||||||
|
|
||||||
|
|
73
src/core.py
73
src/core.py
|
@ -7,11 +7,17 @@ import sys
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
import logging
|
||||||
|
|
||||||
import toolkit
|
import toolkit
|
||||||
import video_thread
|
import video_thread
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Core')
|
||||||
|
STDOUT_LOGLVL = logging.WARNING
|
||||||
|
FILE_LOGLVL = logging.DEBUG
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
'''
|
'''
|
||||||
MainWindow and Command module both use an instance of this class
|
MainWindow and Command module both use an instance of this class
|
||||||
|
@ -35,6 +41,7 @@ class Core:
|
||||||
continue
|
continue
|
||||||
elif ext == '.py':
|
elif ext == '.py':
|
||||||
yield name
|
yield name
|
||||||
|
log.debug('Importing component modules')
|
||||||
self.modules = [
|
self.modules = [
|
||||||
import_module('components.%s' % name)
|
import_module('components.%s' % name)
|
||||||
for name in findComponents()
|
for name in findComponents()
|
||||||
|
@ -67,7 +74,7 @@ class Core:
|
||||||
compPos = len(self.selectedComponents)
|
compPos = len(self.selectedComponents)
|
||||||
if len(self.selectedComponents) > 50:
|
if len(self.selectedComponents) > 50:
|
||||||
return None
|
return None
|
||||||
|
log.debug('Inserting Component from module #%s' % moduleIndex)
|
||||||
component = self.modules[moduleIndex].Component(
|
component = self.modules[moduleIndex].Component(
|
||||||
moduleIndex, compPos, self
|
moduleIndex, compPos, self
|
||||||
)
|
)
|
||||||
|
@ -104,7 +111,7 @@ class Core:
|
||||||
self.componentListChanged()
|
self.componentListChanged()
|
||||||
|
|
||||||
def updateComponent(self, i):
|
def updateComponent(self, i):
|
||||||
# print('updating %s' % self.selectedComponents[i])
|
log.debug('Updating %s #%s' % (self.selectedComponents[i], str(i)))
|
||||||
self.selectedComponents[i].update()
|
self.selectedComponents[i].update()
|
||||||
|
|
||||||
def moduleIndexFor(self, compName):
|
def moduleIndexFor(self, compName):
|
||||||
|
@ -125,12 +132,17 @@ class Core:
|
||||||
if not saveValueStore:
|
if not saveValueStore:
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
self.selectedComponents[compIndex].loadPreset(
|
comp = self.selectedComponents[compIndex]
|
||||||
|
comp.loadPreset(
|
||||||
saveValueStore,
|
saveValueStore,
|
||||||
presetName
|
presetName
|
||||||
)
|
)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print('preset missing value: %s' % e)
|
log.warning(
|
||||||
|
'%s #%s\'s preset is missing value: %s' % (
|
||||||
|
comp.name, str(compIndex), str(e)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.savedPresets[presetName] = dict(saveValueStore)
|
self.savedPresets[presetName] = dict(saveValueStore)
|
||||||
return True
|
return True
|
||||||
|
@ -206,7 +218,7 @@ class Core:
|
||||||
preset['preset']
|
preset['preset']
|
||||||
)
|
)
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
print('%s missing value: %s' % (
|
log.warning('%s missing value: %s' % (
|
||||||
self.selectedComponents[i], e)
|
self.selectedComponents[i], e)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -224,7 +236,7 @@ class Core:
|
||||||
typ, value, tb = data
|
typ, value, tb = data
|
||||||
if typ.__name__ == 'KeyError':
|
if typ.__name__ == 'KeyError':
|
||||||
# probably just an old version, still loadable
|
# probably just an old version, still loadable
|
||||||
print('file missing value: %s' % value)
|
log.warning('Project file missing value: %s' % value)
|
||||||
return
|
return
|
||||||
if hasattr(loader, 'createNewProject'):
|
if hasattr(loader, 'createNewProject'):
|
||||||
loader.createNewProject(prompt=False)
|
loader.createNewProject(prompt=False)
|
||||||
|
@ -244,6 +256,7 @@ class Core:
|
||||||
Returns dictionary with section names as the keys, each one
|
Returns dictionary with section names as the keys, each one
|
||||||
contains a list of tuples: (compName, version, compPresetDict)
|
contains a list of tuples: (compName, version, compPresetDict)
|
||||||
'''
|
'''
|
||||||
|
log.debug('Parsing av file: %s' % filepath)
|
||||||
validSections = (
|
validSections = (
|
||||||
'Components',
|
'Components',
|
||||||
'Settings',
|
'Settings',
|
||||||
|
@ -362,6 +375,7 @@ class Core:
|
||||||
|
|
||||||
def createProjectFile(self, filepath, window=None):
|
def createProjectFile(self, filepath, window=None):
|
||||||
'''Create a project file (.avp) using the current program state'''
|
'''Create a project file (.avp) using the current program state'''
|
||||||
|
log.info('Creating %s' % filepath)
|
||||||
settingsKeys = [
|
settingsKeys = [
|
||||||
'componentDir',
|
'componentDir',
|
||||||
'inputDir',
|
'inputDir',
|
||||||
|
@ -374,9 +388,8 @@ class Core:
|
||||||
filepath += '.avp'
|
filepath += '.avp'
|
||||||
if os.path.exists(filepath):
|
if os.path.exists(filepath):
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
with open(filepath, 'w') as f:
|
|
||||||
print('creating %s' % filepath)
|
|
||||||
|
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
f.write('[Components]\n')
|
f.write('[Components]\n')
|
||||||
for comp in self.selectedComponents:
|
for comp in self.selectedComponents:
|
||||||
saveValueStore = comp.savePreset()
|
saveValueStore = comp.savePreset()
|
||||||
|
@ -443,6 +456,7 @@ class Core:
|
||||||
'settings': QtCore.QSettings(
|
'settings': QtCore.QSettings(
|
||||||
os.path.join(dataDir, 'settings.ini'),
|
os.path.join(dataDir, 'settings.ini'),
|
||||||
QtCore.QSettings.IniFormat),
|
QtCore.QSettings.IniFormat),
|
||||||
|
'logDir': os.path.join(dataDir, 'log'),
|
||||||
'presetDir': os.path.join(dataDir, 'presets'),
|
'presetDir': os.path.join(dataDir, 'presets'),
|
||||||
'componentsPath': os.path.join(wd, 'components'),
|
'componentsPath': os.path.join(wd, 'components'),
|
||||||
'encoderOptions': encoderOptions,
|
'encoderOptions': encoderOptions,
|
||||||
|
@ -489,6 +503,13 @@ class Core:
|
||||||
setattr(cls, classvar, val)
|
setattr(cls, classvar, val)
|
||||||
|
|
||||||
cls.loadDefaultSettings()
|
cls.loadDefaultSettings()
|
||||||
|
if not os.path.exists(cls.dataDir):
|
||||||
|
os.makedirs(cls.dataDir)
|
||||||
|
for neededDirectory in (
|
||||||
|
cls.presetDir, cls.logDir, cls.settings.value("projectDir")):
|
||||||
|
if not os.path.exists(neededDirectory):
|
||||||
|
os.mkdir(neededDirectory)
|
||||||
|
cls.makeLogger()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def loadDefaultSettings(cls):
|
def loadDefaultSettings(cls):
|
||||||
|
@ -522,6 +543,42 @@ class Core:
|
||||||
if val in ('true', 'false'):
|
if val in ('true', 'false'):
|
||||||
cls.settings.setValue(key, True if val == 'true' else False)
|
cls.settings.setValue(key, True if val == 'true' else False)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def makeLogger():
|
||||||
|
logFilename = os.path.join(Core.logDir, 'avp_debug.log')
|
||||||
|
libLogFilename = os.path.join(Core.logDir, 'global_debug.log')
|
||||||
|
# delete old logs
|
||||||
|
for log in (logFilename, libLogFilename):
|
||||||
|
if os.path.exists(log):
|
||||||
|
os.remove(log)
|
||||||
|
|
||||||
|
# create file handlers to capture every log message somewhere
|
||||||
|
logFile = logging.FileHandler(logFilename)
|
||||||
|
logFile.setLevel(FILE_LOGLVL)
|
||||||
|
libLogFile = logging.FileHandler(libLogFilename)
|
||||||
|
libLogFile.setLevel(FILE_LOGLVL)
|
||||||
|
|
||||||
|
# send some critical log messages to stdout as well
|
||||||
|
logStream = logging.StreamHandler()
|
||||||
|
logStream.setLevel(STDOUT_LOGLVL)
|
||||||
|
|
||||||
|
# create formatters and put everything together
|
||||||
|
fileFormatter = logging.Formatter(
|
||||||
|
'[%(asctime)s] <%(name)s> %(levelname)s: %(message)s'
|
||||||
|
)
|
||||||
|
streamFormatter = logging.Formatter(
|
||||||
|
'<%(name)s> %(message)s'
|
||||||
|
)
|
||||||
|
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)
|
||||||
|
|
||||||
# always store settings in class variables even if a Core object is not created
|
# always store settings in class variables even if a Core object is not created
|
||||||
Core.storeSettings()
|
Core.storeSettings()
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
from PyQt5 import uic, QtWidgets
|
from PyQt5 import uic, QtWidgets
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
from __init__ import wd
|
from __init__ import wd
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Entrypoint')
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
app.setApplicationName("audio-visualizer")
|
app.setApplicationName("audio-visualizer")
|
||||||
|
@ -28,6 +32,7 @@ def main():
|
||||||
from command import Command
|
from command import Command
|
||||||
|
|
||||||
main = Command()
|
main = Command()
|
||||||
|
log.debug("Finished creating command object")
|
||||||
|
|
||||||
elif mode == 'GUI':
|
elif mode == 'GUI':
|
||||||
from mainwindow import MainWindow
|
from mainwindow import MainWindow
|
||||||
|
@ -48,6 +53,7 @@ def main():
|
||||||
# window.verticalLayout_2.setContentsMargins(0, topMargin, 0, 0)
|
# window.verticalLayout_2.setContentsMargins(0, topMargin, 0, 0)
|
||||||
|
|
||||||
main = MainWindow(window, proj)
|
main = MainWindow(window, proj)
|
||||||
|
log.debug("Finished creating main window")
|
||||||
window.raise_()
|
window.raise_()
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, main.cleanUp)
|
signal.signal(signal.SIGINT, main.cleanUp)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import os
|
||||||
import signal
|
import signal
|
||||||
import filecmp
|
import filecmp
|
||||||
import time
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
from core import Core
|
from core import Core
|
||||||
import preview_thread
|
import preview_thread
|
||||||
|
@ -20,11 +21,15 @@ from presetmanager import PresetManager
|
||||||
from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput
|
from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.MainWindow')
|
||||||
|
|
||||||
|
|
||||||
class PreviewWindow(QtWidgets.QLabel):
|
class PreviewWindow(QtWidgets.QLabel):
|
||||||
'''
|
'''
|
||||||
Paints the preview QLabel and maintains the aspect ratio when the
|
Paints the preview QLabel and maintains the aspect ratio when the
|
||||||
window is resized.
|
window is resized.
|
||||||
'''
|
'''
|
||||||
|
log = logging.getLogger('AVP.MainWindow.Preview')
|
||||||
|
|
||||||
def __init__(self, parent, img):
|
def __init__(self, parent, img):
|
||||||
super(PreviewWindow, self).__init__()
|
super(PreviewWindow, self).__init__()
|
||||||
|
@ -58,11 +63,15 @@ class PreviewWindow(QtWidgets.QLabel):
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
component = self.parent.core.selectedComponents[i]
|
component = self.parent.core.selectedComponents[i]
|
||||||
if not hasattr(component, 'previewClickEvent'):
|
if not hasattr(component, 'previewClickEvent'):
|
||||||
|
self.log.info('Ignored click event')
|
||||||
return
|
return
|
||||||
pos = (event.x(), event.y())
|
pos = (event.x(), event.y())
|
||||||
size = (self.width(), self.height())
|
size = (self.width(), self.height())
|
||||||
|
butt = event.button()
|
||||||
|
self.log.info('Click event for #%s: %s button %s' % (
|
||||||
|
i, pos, butt))
|
||||||
component.previewClickEvent(
|
component.previewClickEvent(
|
||||||
pos, size, event.button()
|
pos, size, butt
|
||||||
)
|
)
|
||||||
self.parent.core.updateComponent(i)
|
self.parent.core.updateComponent(i)
|
||||||
|
|
||||||
|
@ -91,9 +100,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
def __init__(self, window, project):
|
def __init__(self, window, project):
|
||||||
QtWidgets.QMainWindow.__init__(self)
|
QtWidgets.QMainWindow.__init__(self)
|
||||||
# print('main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
|
||||||
self.window = window
|
self.window = window
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
|
log.debug(
|
||||||
|
'Main thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
||||||
|
|
||||||
# widgets of component settings
|
# widgets of component settings
|
||||||
self.pages = []
|
self.pages = []
|
||||||
|
@ -103,27 +113,23 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.autosaveCooldown = 0.2
|
self.autosaveCooldown = 0.2
|
||||||
self.encoding = False
|
self.encoding = False
|
||||||
|
|
||||||
# Create data directory, load/create settings
|
# Find settings created by Core object
|
||||||
self.dataDir = Core.dataDir
|
self.dataDir = Core.dataDir
|
||||||
self.presetDir = Core.presetDir
|
self.presetDir = Core.presetDir
|
||||||
self.autosavePath = os.path.join(self.dataDir, 'autosave.avp')
|
self.autosavePath = os.path.join(self.dataDir, 'autosave.avp')
|
||||||
self.settings = Core.settings
|
self.settings = Core.settings
|
||||||
|
|
||||||
self.presetManager = PresetManager(
|
self.presetManager = PresetManager(
|
||||||
uic.loadUi(
|
uic.loadUi(
|
||||||
os.path.join(Core.wd, 'presetmanager.ui')), self)
|
os.path.join(Core.wd, 'presetmanager.ui')), self)
|
||||||
|
|
||||||
if not os.path.exists(self.dataDir):
|
|
||||||
os.makedirs(self.dataDir)
|
|
||||||
for neededDirectory in (
|
|
||||||
self.presetDir, self.settings.value("projectDir")):
|
|
||||||
if not os.path.exists(neededDirectory):
|
|
||||||
os.mkdir(neededDirectory)
|
|
||||||
|
|
||||||
# Create the preview window and its thread, queues, and timers
|
# Create the preview window and its thread, queues, and timers
|
||||||
|
log.debug('Creating preview window')
|
||||||
self.previewWindow = PreviewWindow(self, os.path.join(
|
self.previewWindow = PreviewWindow(self, os.path.join(
|
||||||
Core.wd, "background.png"))
|
Core.wd, "background.png"))
|
||||||
window.verticalLayout_previewWrapper.addWidget(self.previewWindow)
|
window.verticalLayout_previewWrapper.addWidget(self.previewWindow)
|
||||||
|
|
||||||
|
log.debug('Starting preview thread')
|
||||||
self.previewQueue = Queue()
|
self.previewQueue = Queue()
|
||||||
self.previewThread = QtCore.QThread(self)
|
self.previewThread = QtCore.QThread(self)
|
||||||
self.previewWorker = preview_thread.Worker(self, self.previewQueue)
|
self.previewWorker = preview_thread.Worker(self, self.previewQueue)
|
||||||
|
@ -132,6 +138,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.previewWorker.imageCreated.connect(self.showPreviewImage)
|
self.previewWorker.imageCreated.connect(self.showPreviewImage)
|
||||||
self.previewThread.start()
|
self.previewThread.start()
|
||||||
|
|
||||||
|
log.debug('Starting preview timer')
|
||||||
self.timer = QtCore.QTimer(self)
|
self.timer = QtCore.QTimer(self)
|
||||||
self.timer.timeout.connect(self.processTask.emit)
|
self.timer.timeout.connect(self.processTask.emit)
|
||||||
self.timer.start(500)
|
self.timer.start(500)
|
||||||
|
@ -141,6 +148,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
componentList = self.window.listWidget_componentList
|
componentList = self.window.listWidget_componentList
|
||||||
|
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
|
log.debug(
|
||||||
|
'Darwin detected: showing progress label below progress bar')
|
||||||
window.progressBar_createVideo.setTextVisible(False)
|
window.progressBar_createVideo.setTextVisible(False)
|
||||||
else:
|
else:
|
||||||
window.progressLabel.setHidden(True)
|
window.progressLabel.setHidden(True)
|
||||||
|
@ -276,6 +285,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
)
|
)
|
||||||
|
|
||||||
self.updateWindowTitle()
|
self.updateWindowTitle()
|
||||||
|
log.debug('Showing main window')
|
||||||
window.show()
|
window.show()
|
||||||
|
|
||||||
if project and project != self.autosavePath:
|
if project and project != self.autosavePath:
|
||||||
|
@ -398,6 +408,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def cleanUp(self, *args):
|
def cleanUp(self, *args):
|
||||||
|
log.info('Ending the preview thread')
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
self.previewThread.quit()
|
self.previewThread.quit()
|
||||||
self.previewThread.wait()
|
self.previewThread.wait()
|
||||||
|
@ -414,11 +425,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
appName += '*'
|
appName += '*'
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
log.debug('Setting window title to %s' % appName)
|
||||||
self.window.setWindowTitle(appName)
|
self.window.setWindowTitle(appName)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(int, dict)
|
@QtCore.pyqtSlot(int, dict)
|
||||||
def updateComponentTitle(self, pos, presetStore=False):
|
def updateComponentTitle(self, pos, presetStore=False):
|
||||||
if type(presetStore) == dict:
|
if type(presetStore) is dict:
|
||||||
name = presetStore['preset']
|
name = presetStore['preset']
|
||||||
if name is None or name not in self.core.savedPresets:
|
if name is None or name not in self.core.savedPresets:
|
||||||
modified = False
|
modified = False
|
||||||
|
@ -428,11 +440,20 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
modified = bool(presetStore)
|
modified = bool(presetStore)
|
||||||
if pos < 0:
|
if pos < 0:
|
||||||
pos = len(self.core.selectedComponents)-1
|
pos = len(self.core.selectedComponents)-1
|
||||||
title = str(self.core.selectedComponents[pos])
|
name = str(self.core.selectedComponents[pos])
|
||||||
|
title = str(name)
|
||||||
if self.core.selectedComponents[pos].currentPreset:
|
if self.core.selectedComponents[pos].currentPreset:
|
||||||
title += ' - %s' % self.core.selectedComponents[pos].currentPreset
|
title += ' - %s' % self.core.selectedComponents[pos].currentPreset
|
||||||
if modified:
|
if modified:
|
||||||
title += '*'
|
title += '*'
|
||||||
|
if type(presetStore) is bool:
|
||||||
|
log.debug('Forcing %s #%s\'s modified status to %s: %s' % (
|
||||||
|
name, pos, modified, title
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
log.debug('Setting %s #%s\'s title: %s' % (
|
||||||
|
name, pos, title
|
||||||
|
))
|
||||||
self.window.listWidget_componentList.item(pos).setText(title)
|
self.window.listWidget_componentList.item(pos).setText(title)
|
||||||
|
|
||||||
def updateCodecs(self):
|
def updateCodecs(self):
|
||||||
|
@ -493,6 +514,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
elif force or timeDiff >= self.autosaveCooldown * 5:
|
elif force or timeDiff >= self.autosaveCooldown * 5:
|
||||||
self.autosaveCooldown = 0.2
|
self.autosaveCooldown = 0.2
|
||||||
self.autosaveTimes.insert(0, self.lastAutosave)
|
self.autosaveTimes.insert(0, self.lastAutosave)
|
||||||
|
else:
|
||||||
|
log.debug('Autosave rejected by cooldown')
|
||||||
|
|
||||||
def autosaveExists(self, identical=True):
|
def autosaveExists(self, identical=True):
|
||||||
'''Determines if creating the autosave should be blocked.'''
|
'''Determines if creating the autosave should be blocked.'''
|
||||||
|
@ -500,9 +523,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
if self.currentProject and os.path.exists(self.autosavePath) \
|
if self.currentProject and os.path.exists(self.autosavePath) \
|
||||||
and filecmp.cmp(
|
and filecmp.cmp(
|
||||||
self.autosavePath, self.currentProject) == identical:
|
self.autosavePath, self.currentProject) == identical:
|
||||||
|
log.debug(
|
||||||
|
'Autosave found %s to be identical' % \
|
||||||
|
'not' if not identical else ''
|
||||||
|
)
|
||||||
return True
|
return True
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print('project file couldn\'t be located:', self.currentProject)
|
log.error(
|
||||||
|
'Project file couldn\'t be located:', self.currentProject)
|
||||||
return identical
|
return identical
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -543,7 +571,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.window.lineEdit_outputFile.setText(fileName)
|
self.window.lineEdit_outputFile.setText(fileName)
|
||||||
|
|
||||||
def stopVideo(self):
|
def stopVideo(self):
|
||||||
print('stop')
|
log.info('Export cancelled')
|
||||||
self.videoWorker.cancel()
|
self.videoWorker.cancel()
|
||||||
self.canceled = True
|
self.canceled = True
|
||||||
|
|
||||||
|
@ -773,6 +801,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
mousePos = -1
|
mousePos = -1
|
||||||
else:
|
else:
|
||||||
mousePos = mousePos.index(True)
|
mousePos = mousePos.index(True)
|
||||||
|
log.debug('Click component list row %s' % mousePos)
|
||||||
return mousePos
|
return mousePos
|
||||||
|
|
||||||
@disableWhenEncoding
|
@disableWhenEncoding
|
||||||
|
|
|
@ -8,11 +8,15 @@ from PIL import Image
|
||||||
from PIL.ImageQt import ImageQt
|
from PIL.ImageQt import ImageQt
|
||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
from toolkit.frame import Checkerboard
|
from toolkit.frame import Checkerboard
|
||||||
from toolkit import disableWhenOpeningProject
|
from toolkit import disableWhenOpeningProject
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger("AVP.PreviewThread")
|
||||||
|
|
||||||
|
|
||||||
class Worker(QtCore.QObject):
|
class Worker(QtCore.QObject):
|
||||||
|
|
||||||
imageCreated = pyqtSignal(QtGui.QImage)
|
imageCreated = pyqtSignal(QtGui.QImage)
|
||||||
|
@ -55,7 +59,7 @@ class Worker(QtCore.QObject):
|
||||||
self.background = Checkerboard(width, height)
|
self.background = Checkerboard(width, height)
|
||||||
|
|
||||||
frame = self.background.copy()
|
frame = self.background.copy()
|
||||||
|
log.debug('Creating new preview frame')
|
||||||
components = nextPreviewInformation["components"]
|
components = nextPreviewInformation["components"]
|
||||||
for component in reversed(components):
|
for component in reversed(components):
|
||||||
try:
|
try:
|
||||||
|
@ -73,10 +77,11 @@ class Worker(QtCore.QObject):
|
||||||
newFrame.width, newFrame.height,
|
newFrame.width, newFrame.height,
|
||||||
width, height
|
width, height
|
||||||
)
|
)
|
||||||
|
log.critical(errMsg)
|
||||||
self.error.emit(errMsg)
|
self.error.emit(errMsg)
|
||||||
break
|
break
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
print(e)
|
log.error(str(e))
|
||||||
else:
|
else:
|
||||||
self.frame = ImageQt(frame)
|
self.frame = ImageQt(frame)
|
||||||
self.imageCreated.emit(QtGui.QImage(self.frame))
|
self.imageCreated.emit(QtGui.QImage(self.frame))
|
||||||
|
|
|
@ -8,12 +8,16 @@ import subprocess
|
||||||
import threading
|
import threading
|
||||||
import signal
|
import signal
|
||||||
from queue import PriorityQueue
|
from queue import PriorityQueue
|
||||||
|
import logging
|
||||||
|
|
||||||
import core
|
import core
|
||||||
from toolkit.common import checkOutput, pipeWrapper
|
from toolkit.common import checkOutput, pipeWrapper
|
||||||
from component import ComponentError
|
from component import ComponentError
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Toolkit.Ffmpeg')
|
||||||
|
|
||||||
|
|
||||||
class FfmpegVideo:
|
class FfmpegVideo:
|
||||||
'''Opens a pipe to ffmpeg and stores a buffer of raw video frames.'''
|
'''Opens a pipe to ffmpeg and stores a buffer of raw video frames.'''
|
||||||
|
|
||||||
|
@ -88,13 +92,14 @@ class FfmpegVideo:
|
||||||
|
|
||||||
def fillBuffer(self):
|
def fillBuffer(self):
|
||||||
logFilename = os.path.join(
|
logFilename = os.path.join(
|
||||||
core.Core.dataDir, 'extra_%s.log' % str(self.component.compPos))
|
core.Core.logDir, 'render_%s.log' % str(self.component.compPos))
|
||||||
with open(logFilename, 'w') as log:
|
log.debug('Creating ffmpeg process (log at %s)' % logFilename)
|
||||||
log.write(" ".join(self.command) + '\n\n')
|
with open(logFilename, 'w') as logf:
|
||||||
with open(logFilename, 'a') as log:
|
logf.write(" ".join(self.command) + '\n\n')
|
||||||
|
with open(logFilename, 'a') as logf:
|
||||||
self.pipe = openPipe(
|
self.pipe = openPipe(
|
||||||
self.command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
self.command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE,
|
||||||
stderr=log, bufsize=10**8
|
stderr=logf, bufsize=10**8
|
||||||
)
|
)
|
||||||
while True:
|
while True:
|
||||||
if self.parent.canceled:
|
if self.parent.canceled:
|
||||||
|
@ -375,7 +380,7 @@ def getAudioDuration(filename):
|
||||||
try:
|
try:
|
||||||
info = fileInfo.decode("utf-8").split('\n')
|
info = fileInfo.decode("utf-8").split('\n')
|
||||||
except UnicodeDecodeError as e:
|
except UnicodeDecodeError as e:
|
||||||
print('Unicode error:', str(e))
|
log.error('Unicode error:', str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for line in info:
|
for line in info:
|
||||||
|
@ -398,7 +403,7 @@ def readAudioFile(filename, videoWorker):
|
||||||
'''
|
'''
|
||||||
duration = getAudioDuration(filename)
|
duration = getAudioDuration(filename)
|
||||||
if not duration:
|
if not duration:
|
||||||
print('Audio file doesn\'t exist or unreadable.')
|
log.error('Audio file doesn\'t exist or unreadable.')
|
||||||
return
|
return
|
||||||
|
|
||||||
command = [
|
command = [
|
||||||
|
|
|
@ -7,10 +7,14 @@ from PIL.ImageQt import ImageQt
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import math
|
import math
|
||||||
|
import logging
|
||||||
|
|
||||||
import core
|
import core
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger('AVP.Toolkit.Frame')
|
||||||
|
|
||||||
|
|
||||||
class FramePainter(QtGui.QPainter):
|
class FramePainter(QtGui.QPainter):
|
||||||
'''
|
'''
|
||||||
A QPainter for a blank frame, which can be converted into a
|
A QPainter for a blank frame, which can be converted into a
|
||||||
|
@ -79,6 +83,7 @@ def FloodFrame(width, height, RgbaTuple):
|
||||||
@defaultSize
|
@defaultSize
|
||||||
def BlankFrame(width, height):
|
def BlankFrame(width, height):
|
||||||
'''The base frame used by each component to start drawing.'''
|
'''The base frame used by each component to start drawing.'''
|
||||||
|
log.debug('Creating new %s*%s blank frame' % (width, height))
|
||||||
return FloodFrame(width, height, (0, 0, 0, 0))
|
return FloodFrame(width, height, (0, 0, 0, 0))
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,6 +93,7 @@ def Checkerboard(width, height):
|
||||||
A checkerboard to represent transparency to the user.
|
A checkerboard to represent transparency to the user.
|
||||||
TODO: Would be cool to generate this image with numpy instead.
|
TODO: Would be cool to generate this image with numpy instead.
|
||||||
'''
|
'''
|
||||||
|
log.debug('Creating new %s*%s checkerboard' % (width, height))
|
||||||
image = FloodFrame(1920, 1080, (0, 0, 0, 0))
|
image = FloodFrame(1920, 1080, (0, 0, 0, 0))
|
||||||
image.paste(Image.open(
|
image.paste(Image.open(
|
||||||
os.path.join(core.Core.wd, "background.png")),
|
os.path.join(core.Core.wd, "background.png")),
|
||||||
|
|
|
@ -17,6 +17,7 @@ from queue import Queue, PriorityQueue
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
import time
|
import time
|
||||||
import signal
|
import signal
|
||||||
|
import logging
|
||||||
|
|
||||||
from component import ComponentError
|
from component import ComponentError
|
||||||
from toolkit.frame import Checkerboard
|
from toolkit.frame import Checkerboard
|
||||||
|
@ -26,6 +27,9 @@ from toolkit.ffmpeg import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger("AVP.VideoThread")
|
||||||
|
|
||||||
|
|
||||||
class Worker(QtCore.QObject):
|
class Worker(QtCore.QObject):
|
||||||
|
|
||||||
imageCreated = pyqtSignal(['QImage'])
|
imageCreated = pyqtSignal(['QImage'])
|
||||||
|
@ -92,7 +96,7 @@ class Worker(QtCore.QObject):
|
||||||
by a renderNode later. All indices are multiples of self.sampleSize
|
by a renderNode later. All indices are multiples of self.sampleSize
|
||||||
sampleSize * frameNo = audioI, AKA audio data starting at frameNo
|
sampleSize * frameNo = audioI, AKA audio data starting at frameNo
|
||||||
'''
|
'''
|
||||||
print('Dispatching Frames for Compositing...')
|
log.debug('Dispatching Frames for Compositing...')
|
||||||
|
|
||||||
for audioI in range(0, len(self.completeAudioArray), self.sampleSize):
|
for audioI in range(0, len(self.completeAudioArray), self.sampleSize):
|
||||||
self.compositeQueue.put(audioI)
|
self.compositeQueue.put(audioI)
|
||||||
|
@ -156,10 +160,12 @@ class Worker(QtCore.QObject):
|
||||||
self.progressBarUpdate.emit(0)
|
self.progressBarUpdate.emit(0)
|
||||||
self.progressBarSetText.emit("Starting components...")
|
self.progressBarSetText.emit("Starting components...")
|
||||||
canceledByComponent = False
|
canceledByComponent = False
|
||||||
print('Loaded Components:', ", ".join([
|
initText = ", ".join([
|
||||||
"%s) %s" % (num, str(component))
|
"%s) %s" % (num, str(component))
|
||||||
for num, component in enumerate(reversed(self.components))
|
for num, component in enumerate(reversed(self.components))
|
||||||
]))
|
])
|
||||||
|
print('Loaded Components:', initText)
|
||||||
|
log.info('Calling preFrameRender for %s' % initText)
|
||||||
self.staticComponents = {}
|
self.staticComponents = {}
|
||||||
for compNo, comp in enumerate(reversed(self.components)):
|
for compNo, comp in enumerate(reversed(self.components)):
|
||||||
try:
|
try:
|
||||||
|
@ -191,6 +197,7 @@ class Worker(QtCore.QObject):
|
||||||
compError[0]
|
compError[0]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
log.critical(errMsg)
|
||||||
comp._error.emit(errMsg, compError[1])
|
comp._error.emit(errMsg, compError[1])
|
||||||
break
|
break
|
||||||
if 'static' in compProps:
|
if 'static' in compProps:
|
||||||
|
@ -199,7 +206,7 @@ class Worker(QtCore.QObject):
|
||||||
|
|
||||||
if self.canceled:
|
if self.canceled:
|
||||||
if canceledByComponent:
|
if canceledByComponent:
|
||||||
print('Export cancelled by component #%s (%s): %s' % (
|
log.critical('Export cancelled by component #%s (%s): %s' % (
|
||||||
compNo,
|
compNo,
|
||||||
comp.name,
|
comp.name,
|
||||||
'No message.' if comp.error() is None else (
|
'No message.' if comp.error() is None else (
|
||||||
|
@ -224,8 +231,11 @@ class Worker(QtCore.QObject):
|
||||||
ffmpegCommand = createFfmpegCommand(
|
ffmpegCommand = createFfmpegCommand(
|
||||||
self.inputFile, self.outputFile, self.components, duration
|
self.inputFile, self.outputFile, self.components, duration
|
||||||
)
|
)
|
||||||
print('###### FFMPEG COMMAND ######\n%s' % " ".join(ffmpegCommand))
|
cmd = " ".join(ffmpegCommand)
|
||||||
|
print('###### FFMPEG COMMAND ######\n%s' % cmd)
|
||||||
print('############################')
|
print('############################')
|
||||||
|
log.info('Opening pipe to ffmpeg')
|
||||||
|
log.info(cmd)
|
||||||
self.out_pipe = openPipe(
|
self.out_pipe = openPipe(
|
||||||
ffmpegCommand, stdin=sp.PIPE, stdout=sys.stdout, stderr=sys.stdout
|
ffmpegCommand, stdin=sp.PIPE, stdout=sys.stdout, stderr=sys.stdout
|
||||||
)
|
)
|
||||||
|
@ -298,9 +308,9 @@ class Worker(QtCore.QObject):
|
||||||
try:
|
try:
|
||||||
self.out_pipe.stdin.close()
|
self.out_pipe.stdin.close()
|
||||||
except BrokenPipeError:
|
except BrokenPipeError:
|
||||||
print('Broken pipe to ffmpeg!')
|
log.error('Broken pipe to ffmpeg!')
|
||||||
if self.out_pipe.stderr is not None:
|
if self.out_pipe.stderr is not None:
|
||||||
print(self.out_pipe.stderr.read())
|
log.error(self.out_pipe.stderr.read())
|
||||||
self.out_pipe.stderr.close()
|
self.out_pipe.stderr.close()
|
||||||
self.error = True
|
self.error = True
|
||||||
self.out_pipe.wait()
|
self.out_pipe.wait()
|
||||||
|
|
Reference in New Issue