aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrianna Rainey2022-05-02 17:37:11 -0700
committerGitHub2022-05-02 17:37:11 -0700
commitb765295d9790c240473dbdccd5dc730f39c2a763 (patch)
treeaf1776499661cbea87e65b03719fbe722391f23f
parent4c5aa37aa6f41d909153a2b7d522db6d7582659a (diff)
parent6c3410da0b7fc39a9bc613c208b6e6cd3d3c6ed2 (diff)
Merge pull request #71 from djfun/fix-70
Fix #70 - Crash when exporting video in GUI mode
-rw-r--r--src/command.py9
-rw-r--r--src/core.py1
-rw-r--r--src/gui/mainwindow.py4
-rw-r--r--src/gui/preview_thread.py3
-rw-r--r--src/video_thread.py44
5 files changed, 36 insertions, 25 deletions
diff --git a/src/command.py b/src/command.py
index bf7941a..6d76906 100644
--- a/src/command.py
+++ b/src/command.py
@@ -58,12 +58,16 @@ class Command(QtCore.QObject):
)
self.parser.add_argument(
'--test', action='store_true',
- help='run tests, generate logfiles, then exit'
+ help='run tests and create a report full of debugging info'
)
self.parser.add_argument(
'--debug', action='store_true',
help='create bigger logfiles while program is running'
)
+ self.parser.add_argument(
+ '--no-preview', action='store_true',
+ help='disable live preview during export in GUI mode'
+ )
# optional arguments
self.parser.add_argument(
@@ -140,6 +144,9 @@ class Command(QtCore.QObject):
self.createAudioVisualisation(self.args.input, self.args.output)
return "commandline"
+ elif self.args.no_preview:
+ core.Core.previewEnabled = False
+
elif 'help' not in sys.argv and self.args.projpath is None and '--debug' not in sys.argv:
self.parser.print_help()
quit(1)
diff --git a/src/core.py b/src/core.py
index 77b0894..1ad4a67 100644
--- a/src/core.py
+++ b/src/core.py
@@ -487,6 +487,7 @@ class Core:
],
'logDir': os.path.join(dataDir, 'log'),
'logEnabled': False,
+ 'previewEnabled': True,
}
settings['videoFormats'] = toolkit.appendUppercase([
diff --git a/src/gui/mainwindow.py b/src/gui/mainwindow.py
index f6de763..2bfc4e3 100644
--- a/src/gui/mainwindow.py
+++ b/src/gui/mainwindow.py
@@ -4,7 +4,7 @@
This shows a preview of the video being created and allows for saving
projects and exporting the video at a later time.
'''
-from PyQt5 import QtCore, QtGui, QtWidgets, uic
+from PyQt5 import QtCore, QtWidgets, uic
import PyQt5.QtWidgets as QtWidgets
from PIL import Image
from queue import Queue
@@ -754,7 +754,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.autosave()
self.updateWindowTitle()
- @QtCore.pyqtSlot(QtGui.QImage)
+ @QtCore.pyqtSlot('QImage')
def showPreviewImage(self, image):
self.previewWindow.changePixmap(image)
diff --git a/src/gui/preview_thread.py b/src/gui/preview_thread.py
index 137864b..3943a5c 100644
--- a/src/gui/preview_thread.py
+++ b/src/gui/preview_thread.py
@@ -38,6 +38,7 @@ class Worker(QtCore.QObject):
"components": components,
}
self.queue.put(dic)
+ log.debug('Preview thread id: {}'.format(int(QtCore.QThread.currentThreadId())))
@pyqtSlot()
def process(self):
@@ -79,6 +80,8 @@ class Worker(QtCore.QObject):
except RuntimeError as e:
log.error(str(e))
else:
+ # We must store a reference to this QImage
+ # or else Qt will garbage-collect it on the C++ side
self.frame = ImageQt(frame)
self.imageCreated.emit(QtGui.QImage(self.frame))
diff --git a/src/video_thread.py b/src/video_thread.py
index 5a28beb..dc6db89 100644
--- a/src/video_thread.py
+++ b/src/video_thread.py
@@ -44,6 +44,7 @@ class Worker(QtCore.QObject):
self.settings = parent.settings
self.modules = parent.core.modules
parent.createVideo.connect(self.createVideo)
+ self.previewEnabled = type(parent.core).previewEnabled
#self.parent = parent
self.components = components
@@ -114,25 +115,23 @@ class Worker(QtCore.QObject):
for audioI in range(0, self.audioArrayLen, self.sampleSize):
self.compositeQueue.put(audioI)
- def previewDispatch(self):
+ def showPreview(self, frame):
'''
- Grabs frames from the previewQueue, adds them to the checkerboard
- and emits a final QImage to the MainWindow for the live preview
+ Receives a final frame that will be piped to FFmpeg,
+ adds it to the checkerboard and emits a final QImage
+ to the MainWindow for the live preview
'''
- background = Checkerboard(self.width, self.height)
-
- while not self.stopped:
- audioI, frame = self.previewQueue.get()
- if time.time() - self.lastPreview >= 0.06 or audioI == 0:
- image = Image.alpha_composite(background.copy(), frame)
- self.imageCreated.emit(QtGui.QImage(ImageQt(image)))
- self.lastPreview = time.time()
-
- self.previewQueue.task_done()
+ # We must store a reference to this QImage
+ # or else Qt will garbage-collect it on the C++ side
+ self.latestPreview = ImageQt(frame)
+ self.imageCreated.emit(QtGui.QImage(self.latestPreview))
+ self.lastPreview = time.time()
@pyqtSlot()
def createVideo(self):
log.debug("Video worker received signal to createVideo")
+ log.debug(
+ 'Video thread id: {}'.format(int(QtCore.QThread.currentThreadId())))
numpy.seterr(divide='ignore')
self.encoding.emit(True)
self.extraAudio = []
@@ -143,7 +142,6 @@ class Worker(QtCore.QObject):
self.compositeQueue.maxsize = 20
self.renderQueue = PriorityQueue()
self.renderQueue.maxsize = 20
- self.previewQueue = PriorityQueue()
self.reset()
progressBarValue = 0
@@ -305,15 +303,13 @@ class Worker(QtCore.QObject):
self.dispatchThread.daemon = True
self.dispatchThread.start()
- self.lastPreview = 0.0
- self.previewDispatch = Thread(
- target=self.previewDispatch, name="Render Dispatch Thread"
- )
- self.previewDispatch.daemon = True
- self.previewDispatch.start()
+ # Last time preview was drawn
+ self.lastPreview = time.time()
# Begin piping into ffmpeg!
- frameBuffer = {}
+ frameBuffer = {
+ # audioI: bytes ready to be piped
+ }
progressBarValue = 0
self.progressBarUpdate.emit(progressBarValue)
self.progressBarSetText.emit("Exporting video...")
@@ -331,9 +327,12 @@ class Worker(QtCore.QObject):
if self.canceled:
break
+ # Update live preview
+ if self.previewEnabled and time.time() - self.lastPreview > 0.5:
+ self.showPreview(frameBuffer[audioI])
+
try:
self.out_pipe.stdin.write(frameBuffer[audioI].tobytes())
- self.previewQueue.put([audioI, frameBuffer.pop(audioI)])
except Exception:
break
@@ -346,6 +345,7 @@ class Worker(QtCore.QObject):
"Exporting video: %s%%" % str(int(progressBarValue))
)
+
numpy.seterr(all='print')
self.closePipe()