From de1324a6a75eb2a9f97d8a6b416077cfc73b2bc9 Mon Sep 17 00:00:00 2001 From: tassaron Date: Thu, 27 Jul 2017 17:49:08 -0400 Subject: fixed video component eating stdout + made height/width into properties to simplify render methods --- src/components/color.py | 12 +++------ src/components/image.py | 12 +++------ src/components/original.py | 10 +++---- src/components/sound.py | 10 ------- src/components/text.py | 13 +++------ src/components/video.py | 67 +++++++++++++++++++++------------------------- 6 files changed, 46 insertions(+), 78 deletions(-) (limited to 'src/components') diff --git a/src/components/color.py b/src/components/color.py index 8257ed9..2abd79a 100644 --- a/src/components/color.py +++ b/src/components/color.py @@ -96,18 +96,14 @@ class Component(Component): super().update() - def previewRender(self, previewWorker): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.drawFrame(width, height) + def previewRender(self): + return self.drawFrame(self.width, self.height) def properties(self): return ['static'] - def frameRender(self, layerNo, frameNo): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.drawFrame(width, height) + def frameRender(self, frameNo): + return self.drawFrame(self.width, self.height) def drawFrame(self, width, height): r, g, b = self.color1 diff --git a/src/components/image.py b/src/components/image.py index a705904..a96f127 100644 --- a/src/components/image.py +++ b/src/components/image.py @@ -31,10 +31,8 @@ class Component(Component): }, ) - def previewRender(self, previewWorker): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.drawFrame(width, height) + def previewRender(self): + return self.drawFrame(self.width, self.height) def properties(self): props = ['static'] @@ -48,10 +46,8 @@ class Component(Component): if not os.path.exists(self.imagePath): return "The image selected does not exist!" - def frameRender(self, layerNo, frameNo): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.drawFrame(width, height) + def frameRender(self, frameNo): + return self.drawFrame(self.width, self.height) def drawFrame(self, width, height): frame = BlankFrame(width, height) diff --git a/src/components/original.py b/src/components/original.py index 570465d..3d1a574 100644 --- a/src/components/original.py +++ b/src/components/original.py @@ -59,13 +59,11 @@ class Component(Component): saveValueStore['visColor'] = self.visColor return saveValueStore - def previewRender(self, previewWorker): + def previewRender(self): spectrum = numpy.fromfunction( lambda x: float(self.scale)/2500*(x-128)**2, (255,), dtype="int16") - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) return self.drawBars( - width, height, spectrum, self.visColor, self.layout + self.width, self.height, spectrum, self.visColor, self.layout ) def preFrameRender(self, **kwargs): @@ -74,8 +72,6 @@ class Component(Component): self.smoothConstantUp = 0.8 self.lastSpectrum = None self.spectrumArray = {} - self.width = int(self.settings.value('outputWidth')) - self.height = int(self.settings.value('outputHeight')) for i in range(0, len(self.completeAudioArray), self.sampleSize): if self.canceled: @@ -93,7 +89,7 @@ class Component(Component): self.progressBarSetText.emit(pStr) self.progressBarUpdate.emit(int(progress)) - def frameRender(self, layerNo, frameNo): + def frameRender(self, frameNo): arrayNo = frameNo * self.sampleSize return self.drawBars( self.width, self.height, diff --git a/src/components/sound.py b/src/components/sound.py index fcd9e4e..aff43d3 100644 --- a/src/components/sound.py +++ b/src/components/sound.py @@ -21,11 +21,6 @@ class Component(Component): 'sound': None, }) - def previewRender(self, previewWorker): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return BlankFrame(width, height) - def preFrameRender(self, **kwargs): pass @@ -63,11 +58,6 @@ class Component(Component): self.page.lineEdit_sound.setText(filename) self.update() - def frameRender(self, layerNo, frameNo): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return BlankFrame(width, height) - def commandHelp(self): print('Path to audio file:\n path=/filepath/to/sound.ogg') diff --git a/src/components/text.py b/src/components/text.py index 1d64617..8a302ff 100644 --- a/src/components/text.py +++ b/src/components/text.py @@ -97,10 +97,8 @@ class Component(Component): saveValueStore['textColor'] = self.textColor return saveValueStore - def previewRender(self, previewWorker): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.addText(width, height) + def previewRender(self): + return self.addText(self.width, self.height) def properties(self): props = ['static'] @@ -111,13 +109,10 @@ class Component(Component): def error(self): return "No text provided." - def frameRender(self, layerNo, frameNo): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - return self.addText(width, height) + def frameRender(self, frameNo): + return self.addText(self.width, self.height) def addText(self, width, height): - image = FramePainter(width, height) self.titleFont.setPixelSize(self.fontSize) image.setFont(self.titleFont) diff --git a/src/components/video.py b/src/components/video.py index 8872fbf..48ac557 100644 --- a/src/components/video.py +++ b/src/components/video.py @@ -3,10 +3,11 @@ from PyQt5 import QtGui, QtCore, QtWidgets import os import math import subprocess +import signal import threading from queue import PriorityQueue -from component import Component +from component import Component, ComponentError from toolkit.frame import BlankFrame from toolkit.ffmpeg import testAudioStream from toolkit import openPipe, checkOutput @@ -14,6 +15,10 @@ from toolkit import openPipe, checkOutput class Video: '''Opens a pipe to ffmpeg and stores a buffer of raw video frames.''' + + # error from the thread used to fill the buffer + threadError = None + def __init__(self, **kwargs): mandatoryArgs = [ 'ffmpeg', # path to ffmpeg, usually self.core.FFMPEG_BIN @@ -71,8 +76,8 @@ class Video: self.frameBuffer.task_done() def fillBuffer(self): - pipe = openPipe( - self.command, stdout=subprocess.PIPE, + self.pipe = openPipe( + self.command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8 ) while True: @@ -85,19 +90,11 @@ class Video: if len(self.currentFrame) == 0: self.frameBuffer.put((self.frameNo-1, self.lastFrame)) continue - except AttributeError as e: - self.parent.showMessage( - msg='%s couldn\'t be loaded. ' - 'This is a fatal error.' % os.path.basename( - self.videoPath - ), - detail=str(e), - icon='Warning' - ) - self.parent.stopVideo() + except AttributeError: + Video.threadError = ComponentError(self.component, 'video') break - self.currentFrame = pipe.stdout.read(self.chunkSize) + self.currentFrame = self.pipe.stdout.read(self.chunkSize) if len(self.currentFrame) != 0: self.frameBuffer.put((self.frameNo, self.currentFrame)) self.lastFrame = self.currentFrame @@ -143,13 +140,11 @@ class Component(Component): self.page.spinBox_volume.setEnabled(False) super().update() - def previewRender(self, previewWorker): - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - self.updateChunksize(width, height) - frame = self.getPreviewFrame(width, height) + def previewRender(self): + self.updateChunksize() + frame = self.getPreviewFrame(self.width, self.height) if not frame: - return BlankFrame(width, height) + return BlankFrame(self.width, self.height) else: return frame @@ -184,23 +179,23 @@ class Component(Component): def preFrameRender(self, **kwargs): super().preFrameRender(**kwargs) - width = int(self.settings.value('outputWidth')) - height = int(self.settings.value('outputHeight')) - self.blankFrame_ = BlankFrame(width, height) - self.updateChunksize(width, height) + self.updateChunksize() self.video = Video( ffmpeg=self.core.FFMPEG_BIN, videoPath=self.videoPath, - width=width, height=height, chunkSize=self.chunkSize, + width=self.width, height=self.height, chunkSize=self.chunkSize, frameRate=int(self.settings.value("outputFrameRate")), parent=self.parent, loopVideo=self.loopVideo, component=self, scale=self.scale ) if os.path.exists(self.videoPath) else None - def frameRender(self, layerNo, frameNo): - if self.video: - return self.video.frame(frameNo) - else: - return self.blankFrame_ + def frameRender(self, frameNo): + if Video.threadError is not None: + raise Video.threadError + return self.video.frame(frameNo) + + def renderFinished(self): + self.video.pipe.stdout.close() + self.video.pipe.send_signal(signal.SIGINT) def pickVideo(self): imgDir = self.settings.value("componentDir", os.path.expanduser("~")) @@ -230,20 +225,20 @@ class Component(Component): '-vframes', '1', ] pipe = openPipe( - command, stdout=subprocess.PIPE, + command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8 ) byteFrame = pipe.stdout.read(self.chunkSize) - frame = finalizeFrame(self, byteFrame, width, height) pipe.stdout.close() - pipe.kill() + pipe.send_signal(signal.SIGINT) + frame = finalizeFrame(self, byteFrame, width, height) return frame - def updateChunksize(self, width, height): + def updateChunksize(self): if self.scale != 100 and not self.distort: - width, height = scale(self.scale, width, height, int) - self.chunkSize = 4*width*height + width, height = scale(self.scale, self.width, self.height, int) + self.chunkSize = 4 * width * height def command(self, arg): if '=' in arg: -- cgit v1.2.3