diff options
Diffstat (limited to 'components')
| -rw-r--r-- | components/__base__.py | 44 | ||||
| -rw-r--r-- | components/color.py | 55 | ||||
| -rw-r--r-- | components/image.py | 24 | ||||
| -rw-r--r-- | components/original.py | 78 | ||||
| -rw-r--r-- | components/text.py | 23 | ||||
| -rw-r--r-- | components/video.py | 74 |
6 files changed, 181 insertions, 117 deletions
diff --git a/components/__base__.py b/components/__base__.py index f564aad..94ac6f2 100644 --- a/components/__base__.py +++ b/components/__base__.py @@ -1,5 +1,6 @@ from PyQt4 import QtGui + class Component: def __str__(self): return self.__doc__ @@ -14,7 +15,7 @@ class Component: def reset(self): self.canceled = False - + def preFrameRender(self, **kwargs): for var, value in kwargs.items(): exec('self.%s = value' % var) @@ -22,32 +23,35 @@ class Component: def pickColor(self): color = QtGui.QColorDialog.getColor() if color.isValid(): - RGBstring = '%s,%s,%s' % (str(color.red()), str(color.green()), str(color.blue())) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % color.name() + RGBstring = '%s,%s,%s' % ( + str(color.red()), str(color.green()), str(color.blue())) + btnStyle = "QPushButton{background-color: %s; outline: none;}" \ + % color.name() return RGBstring, btnStyle else: return None, None def RGBFromString(self, string): - ''' turns an RGB string like "255, 255, 255" into a tuple ''' - try: - tup = tuple([int(i) for i in string.split(',')]) - if len(tup) != 3: - raise ValueError - for i in tup: - if i > 255 or i < 0: - raise ValueError - return tup - except: - return (255, 255, 255) + ''' turns an RGB string like "255, 255, 255" into a tuple ''' + try: + tup = tuple([int(i) for i in string.split(',')]) + if len(tup) != 3: + raise ValueError + for i in tup: + if i > 255 or i < 0: + raise ValueError + return tup + except: + return (255, 255, 255) ''' ### Reference methods for creating a new component ### (Inherit from this class and define these) - + def widget(self, parent): self.parent = parent - page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'example.ui')) + page = uic.loadUi(os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'example.ui')) # connect widgets signals self.page = page return page @@ -55,13 +59,13 @@ class Component: def update(self): # read widget values self.parent.drawPreview() - + def previewRender(self, previewWorker): width = int(previewWorker.core.settings.value('outputWidth')) height = int(previewWorker.core.settings.value('outputHeight')) image = Image.new("RGBA", (width, height), (0,0,0,0)) return image - + def frameRender(self, moduleNo, frameNo): width = int(self.worker.core.settings.value('outputWidth')) height = int(self.worker.core.settings.value('outputHeight')) @@ -70,10 +74,10 @@ class Component: def loadPreset(self, presetDict): # update widgets using a preset dict - + def savePreset(self): return {} - + def cancel(self): self.canceled = True diff --git a/components/color.py b/components/color.py index c2a49e2..b050fbd 100644 --- a/components/color.py +++ b/components/color.py @@ -4,31 +4,39 @@ from PyQt4.QtGui import QColor import os from . import __base__ + class Component(__base__.Component): '''Color''' def widget(self, parent): self.parent = parent - page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'color.ui')) - - self.color1 = (0,0,0) - self.color2 = (133,133,133) + page = uic.loadUi(os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'color.ui')) + + self.color1 = (0, 0, 0) + self.color2 = (133, 133, 133) self.x = 0 self.y = 0 - + page.lineEdit_color1.setText('%s,%s,%s' % self.color1) page.lineEdit_color2.setText('%s,%s,%s' % self.color2) - page.pushButton_color1.clicked.connect(lambda: self.pickColor(1)) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*self.color1).name() + + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*self.color1).name() + + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*self.color2).name() + page.pushButton_color1.setStyleSheet(btnStyle) - page.pushButton_color2.clicked.connect(lambda: self.pickColor(2)) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*self.color2).name() page.pushButton_color2.setStyleSheet(btnStyle) + page.pushButton_color1.clicked.connect(lambda: self.pickColor(1)) + page.pushButton_color2.clicked.connect(lambda: self.pickColor(2)) + # disable color #2 until non-default 'fill' option gets changed page.lineEdit_color2.setDisabled(True) page.pushButton_color2.setDisabled(True) page.spinBox_x.setValue(self.x) page.spinBox_x.setValue(self.y) - + page.lineEdit_color1.textChanged.connect(self.update) page.lineEdit_color2.textChanged.connect(self.update) page.spinBox_x.valueChanged.connect(self.update) @@ -42,39 +50,44 @@ class Component(__base__.Component): self.x = self.page.spinBox_x.value() self.y = self.page.spinBox_y.value() self.parent.drawPreview() - + def previewRender(self, previewWorker): width = int(previewWorker.core.settings.value('outputWidth')) height = int(previewWorker.core.settings.value('outputHeight')) return self.drawFrame(width, height) - + def preFrameRender(self, **kwargs): super().preFrameRender(**kwargs) return ['static'] - + def frameRender(self, moduleNo, arrayNo, frameNo): width = int(self.worker.core.settings.value('outputWidth')) height = int(self.worker.core.settings.value('outputHeight')) return self.drawFrame(width, height) - + def drawFrame(self, width, height): - r,g,b = self.color1 + r, g, b = self.color1 return Image.new("RGBA", (width, height), (r, g, b, 255)) def loadPreset(self, pr): self.page.lineEdit_color1.setText('%s,%s,%s' % pr['color1']) self.page.lineEdit_color2.setText('%s,%s,%s' % pr['color2']) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*pr['color1']).name() + + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*pr['color1']).name() + + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*pr['color2']).name() + self.page.pushButton_color1.setStyleSheet(btnStyle) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*pr['color2']).name() self.page.pushButton_color2.setStyleSheet(btnStyle) - + def savePreset(self): return { - 'color1' : self.color1, - 'color2' : self.color2, + 'color1': self.color1, + 'color2': self.color2, } - + def pickColor(self, num): RGBstring, btnStyle = super().pickColor() if not RGBstring: diff --git a/components/image.py b/components/image.py index ffbb117..f9a92ca 100644 --- a/components/image.py +++ b/components/image.py @@ -3,26 +3,28 @@ from PyQt4 import uic, QtGui, QtCore import os from . import __base__ + class Component(__base__.Component): '''Image''' def widget(self, parent): self.parent = parent self.settings = parent.settings - page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'image.ui')) + page = uic.loadUi(os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'image.ui')) self.imagePath = '' self.x = 0 self.y = 0 - + page.lineEdit_image.textChanged.connect(self.update) page.pushButton_image.clicked.connect(self.pickImage) - + self.page = page return page def update(self): self.imagePath = self.page.lineEdit_image.text() self.parent.drawPreview() - + def previewRender(self, previewWorker): width = int(previewWorker.core.settings.value('outputWidth')) height = int(previewWorker.core.settings.value('outputHeight')) @@ -36,9 +38,9 @@ class Component(__base__.Component): width = int(self.worker.core.settings.value('outputWidth')) height = int(self.worker.core.settings.value('outputHeight')) return self.drawFrame(width, height) - + def drawFrame(self, width, height): - frame = Image.new("RGBA", (width, height), (0,0,0,0)) + frame = Image.new("RGBA", (width, height), (0, 0, 0, 0)) if self.imagePath and os.path.exists(self.imagePath): image = Image.open(self.imagePath) if image.size != (width, height): @@ -48,16 +50,16 @@ class Component(__base__.Component): def loadPreset(self, pr): self.page.lineEdit_image.setText(pr['image']) - + def savePreset(self): return { - 'image' : self.imagePath, + 'image': self.imagePath, } - + def pickImage(self): imgDir = self.settings.value("backgroundDir", os.path.expanduser("~")) - filename = QtGui.QFileDialog.getOpenFileName(self.page, - "Choose Image", imgDir, "Image Files (*.jpg *.png)") + filename = QtGui.QFileDialog.getOpenFileName( + self.page, "Choose Image", imgDir, "Image Files (*.jpg *.png)") if filename: self.settings.setValue("backgroundDir", os.path.dirname(filename)) self.page.lineEdit_image.setText(filename) diff --git a/components/original.py b/components/original.py index b0a7579..4d0e83b 100644 --- a/components/original.py +++ b/components/original.py @@ -2,7 +2,8 @@ import numpy from PIL import Image, ImageDraw from PyQt4 import uic, QtGui from PyQt4.QtGui import QColor -import os, random +import os +import random from . import __base__ import time from copy import copy @@ -12,24 +13,25 @@ class Component(__base__.Component): '''Original Audio Visualization''' def widget(self, parent): self.parent = parent - self.visColor = (255,255,255) + self.visColor = (255, 255, 255) - page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'original.ui')) + page = uic.loadUi(os.path.join( + os.path.dirname(os.path.realpath(__file__)), 'original.ui')) page.comboBox_visLayout.addItem("Classic") page.comboBox_visLayout.addItem("Split") page.comboBox_visLayout.addItem("Bottom") - #visLayoutValue = int(self.settings.value('visLayout')) page.comboBox_visLayout.setCurrentIndex(0) page.comboBox_visLayout.currentIndexChanged.connect(self.update) page.lineEdit_visColor.setText('%s,%s,%s' % self.visColor) page.pushButton_visColor.clicked.connect(lambda: self.pickColor()) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*self.visColor).name() + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*self.visColor).name() page.pushButton_visColor.setStyleSheet(btnStyle) page.lineEdit_visColor.textChanged.connect(self.update) self.page = page self.canceled = False return page - + def update(self): self.layout = self.page.comboBox_visLayout.currentIndex() self.visColor = self.RGBFromString(self.page.lineEdit_visColor.text()) @@ -37,21 +39,25 @@ class Component(__base__.Component): def loadPreset(self, pr): self.page.lineEdit_visColor.setText('%s,%s,%s' % pr['visColor']) - btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*pr['visColor']).name() + btnStyle = "QPushButton { background-color : %s; outline: none; }" \ + % QColor(*pr['visColor']).name() self.page.pushButton_visColor.setStyleSheet(btnStyle) self.page.comboBox_visLayout.setCurrentIndex(pr['layout']) - + def savePreset(self): - return { 'layout' : self.layout, - 'visColor' : self.visColor, - } + return { + 'layout': self.layout, + 'visColor': self.visColor, + } def previewRender(self, previewWorker): - spectrum = numpy.fromfunction(lambda x: 0.008*(x-128)**2, (255,), dtype="int16") + spectrum = numpy.fromfunction( + lambda x: 0.008*(x-128)**2, (255,), dtype="int16") width = int(previewWorker.core.settings.value('outputWidth')) height = int(previewWorker.core.settings.value('outputHeight')) - return self.drawBars(width, height, spectrum, self.visColor, self.layout) - + return self.drawBars( + width, height, spectrum, self.visColor, self.layout) + def preFrameRender(self, **kwargs): super().preFrameRender(**kwargs) self.smoothConstantDown = 0.08 @@ -64,19 +70,24 @@ class Component(__base__.Component): for i in range(0, len(self.completeAudioArray), self.sampleSize): if self.canceled: break - self.lastSpectrum = self.transformData(i, self.completeAudioArray, self.sampleSize, - self.smoothConstantDown, self.smoothConstantUp, self.lastSpectrum) + self.lastSpectrum = self.transformData( + i, self.completeAudioArray, self.sampleSize, + self.smoothConstantDown, self.smoothConstantUp, + self.lastSpectrum) self.spectrumArray[i] = copy(self.lastSpectrum) progress = int(100*(i/len(self.completeAudioArray))) if progress >= 100: progress = 100 - pStr = "Analyzing audio: "+ str(progress) +'%' + pStr = "Analyzing audio: "+str(progress)+'%' self.progressBarSetText.emit(pStr) self.progressBarUpdate.emit(int(progress)) - + def frameRender(self, moduleNo, arrayNo, frameNo): - return self.drawBars(self.width, self.height, self.spectrumArray[arrayNo], self.visColor, self.layout) + return self.drawBars( + self.width, self.height, + self.spectrumArray[arrayNo], + self.visColor, self.layout) def pickColor(self): RGBstring, btnStyle = super().pickColor() @@ -85,14 +96,17 @@ class Component(__base__.Component): self.page.lineEdit_visColor.setText(RGBstring) self.page.pushButton_visColor.setStyleSheet(btnStyle) - def transformData(self, i, completeAudioArray, sampleSize, smoothConstantDown, smoothConstantUp, lastSpectrum): + def transformData( + self, i, completeAudioArray, sampleSize, + smoothConstantDown, smoothConstantUp, lastSpectrum): if len(completeAudioArray) < (i + sampleSize): sampleSize = len(completeAudioArray) - i window = numpy.hanning(sampleSize) data = completeAudioArray[i:i+sampleSize][::1] * window paddedSampleSize = 2048 - paddedData = numpy.pad(data, (0, paddedSampleSize - sampleSize), 'constant') + paddedData = numpy.pad( + data, (0, paddedSampleSize - sampleSize), 'constant') spectrum = numpy.fft.fft(paddedData) sample_rate = 44100 frequencies = numpy.fft.fftfreq(len(spectrum), 1./sample_rate) @@ -106,8 +120,13 @@ class Component(__base__.Component): y[numpy.isinf(y)] = 0 if lastSpectrum is not None: - lastSpectrum[y < lastSpectrum] = y[y < lastSpectrum] * smoothConstantDown + lastSpectrum[y < lastSpectrum] * (1 - smoothConstantDown) - lastSpectrum[y >= lastSpectrum] = y[y >= lastSpectrum] * smoothConstantUp + lastSpectrum[y >= lastSpectrum] * (1 - smoothConstantUp) + lastSpectrum[y < lastSpectrum] = \ + y[y < lastSpectrum] * smoothConstantDown + \ + lastSpectrum[y < lastSpectrum] * (1 - smoothConstantDown) + + lastSpectrum[y >= lastSpectrum] = \ + y[y >= lastSpectrum] * smoothConstantUp + \ + lastSpectrum[y >= lastSpectrum] * (1 - smoothConstantUp) else: lastSpectrum = y @@ -120,7 +139,7 @@ class Component(__base__.Component): bF = width / 64 bH = bF / 2 bQ = bF / 4 - imTop = Image.new("RGBA", (width, height),(0,0,0,0)) + imTop = Image.new("RGBA", (width, height), (0, 0, 0, 0)) draw = ImageDraw.Draw(imTop) r, g, b = color color2 = (r, g, b, 125) @@ -128,12 +147,17 @@ class Component(__base__.Component): bP = height / 1200 for j in range(0, 63): - draw.rectangle((bH + j * bF, vH+bQ, bH + j * bF + bF, vH + bQ - spectrum[j * 4] * bP - bH), fill=color2) - draw.rectangle((bH + bQ + j * bF, vH , bH + bQ + j * bF + bH, vH - spectrum[j * 4] * bP), fill=color) + draw.rectangle(( + bH + j * bF, vH+bQ, bH + j * bF + bF, vH + bQ - + spectrum[j * 4] * bP - bH), fill=color2) + + draw.rectangle(( + bH + bQ + j * bF, vH, bH + bQ + j * bF + bH, vH - + spectrum[j * 4] * bP), fill=color) imBottom = imTop.transpose(Image.FLIP_TOP_BOTTOM) - im = Image.new("RGBA", (width, height),(0,0,0,0)) + im = Image.new("RGBA", (width, height), (0, 0, 0, 0)) if layout == 0: y = 0 - int(height/100*43) diff --git a/components/text.py b/components/text.py index 56a9502..6cdc0dd 100644 --- a/components/text.py +++ b/components/text.py @@ -25,9 +25,7 @@ class Component(__base__.Component): self.yPosition = height / 2 * 1.036 page = uic.loadUi(os.path.join( - os.path.dirname(os.path.realpath(__file__)), - 'text.ui' - )) + os.path.dirname(os.path.realpath(__file__)), 'text.ui')) page.comboBox_textAlign.addItem("Left") page.comboBox_textAlign.addItem("Middle") page.comboBox_textAlign.addItem("Right") @@ -61,7 +59,8 @@ class Component(__base__.Component): self.fontSize = self.page.spinBox_fontSize.value() self.xPosition = self.page.spinBox_xTextAlign.value() self.yPosition = self.page.spinBox_yTextAlign.value() - self.textColor = self.RGBFromString(self.page.lineEdit_textColor.text()) + self.textColor = self.RGBFromString( + self.page.lineEdit_textColor.text()) self.parent.drawPreview() def getXY(self): @@ -95,14 +94,14 @@ class Component(__base__.Component): def savePreset(self): return { - 'title': self.title, - 'titleFont': self.titleFont.toString(), - 'alignment': self.alignment, - 'fontSize': self.fontSize, - 'xPosition': self.xPosition, - 'yPosition': self.yPosition, - 'textColor': self.textColor - } + 'title': self.title, + 'titleFont': self.titleFont.toString(), + 'alignment': self.alignment, + 'fontSize': self.fontSize, + 'xPosition': self.xPosition, + 'yPosition': self.yPosition, + 'textColor': self.textColor + } def previewRender(self, previewWorker): width = int(previewWorker.core.settings.value('outputWidth')) diff --git a/components/video.py b/components/video.py index de91264..67a96dd 100644 --- a/components/video.py +++ b/components/video.py @@ -1,12 +1,18 @@ from PIL import Image, ImageDraw from PyQt4 import uic, QtGui, QtCore -import os, subprocess, threading +import os +import subprocess +import threading from queue import PriorityQueue from . import __base__ + class Video: '''Video Component Frame-Fetcher''' - def __init__(self, ffmpeg, videoPath, width, height, frameRate, chunkSize, parent, loopVideo): + def __init__( + self, ffmpeg, videoPath, width, height, + frameRate, chunkSize, parent, loopVideo): + self.parent = parent self.chunkSize = chunkSize self.size = (width, height) @@ -27,15 +33,18 @@ class Video: '-filter:v', 'scale='+str(width)+':'+str(height), '-vcodec', 'rawvideo', '-', ] - + self.frameBuffer = PriorityQueue() self.frameBuffer.maxsize = int(frameRate) self.finishedFrames = {} - - self.thread = threading.Thread(target=self.fillBuffer, name=self.__doc__) + + self.thread = threading.Thread( + target=self.fillBuffer, + name=self.__doc__ + ) self.thread.daemon = True self.thread.start() - + def frame(self, num): while True: if num in self.finishedFrames: @@ -44,9 +53,12 @@ class Video: i, image = self.frameBuffer.get() self.finishedFrames[i] = image self.frameBuffer.task_done() - - def fillBuffer(self): - self.pipe = subprocess.Popen(self.command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8) + + def fillBuffer(self): + self.pipe = subprocess.Popen( + self.command, stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, bufsize=10**8 + ) while True: if self.parent.canceled: break @@ -58,26 +70,29 @@ class Video: continue self.currentFrame = self.pipe.stdout.read(self.chunkSize) - #print('creating frame #%s' % str(self.frameNo)) if len(self.currentFrame) != 0: self.frameBuffer.put((self.frameNo, self.currentFrame)) self.lastFrame = self.currentFrame + class Component(__base__.Component): '''Video''' def widget(self, parent): self.parent = parent self.settings = parent.settings - page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'video.ui')) + page = uic.loadUi(os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'video.ui' + )) self.videoPath = '' self.x = 0 self.y = 0 self.loopVideo = False - + page.lineEdit_video.textChanged.connect(self.update) page.pushButton_video.clicked.connect(self.pickVideo) page.checkBox_loop.stateChanged.connect(self.update) - + self.page = page return page @@ -85,46 +100,50 @@ class Component(__base__.Component): self.videoPath = self.page.lineEdit_video.text() self.loopVideo = self.page.checkBox_loop.isChecked() self.parent.drawPreview() - + def previewRender(self, previewWorker): width = int(previewWorker.core.settings.value('outputWidth')) height = int(previewWorker.core.settings.value('outputHeight')) self.chunkSize = 4*width*height frame = self.getPreviewFrame(width, height) if not frame: - return Image.new("RGBA", (width, height),(0,0,0,0)) + return Image.new("RGBA", (width, height), (0, 0, 0, 0)) else: return frame - + def preFrameRender(self, **kwargs): super().preFrameRender(**kwargs) width = int(self.worker.core.settings.value('outputWidth')) height = int(self.worker.core.settings.value('outputHeight')) self.chunkSize = 4*width*height - self.video = Video(self.parent.core.FFMPEG_BIN, self.videoPath, + self.video = Video( + self.parent.core.FFMPEG_BIN, self.videoPath, width, height, self.settings.value("outputFrameRate"), - self.chunkSize, self.parent, self.loopVideo) - + self.chunkSize, self.parent, self.loopVideo + ) + def frameRender(self, moduleNo, arrayNo, frameNo): return self.video.frame(frameNo) def loadPreset(self, pr): self.page.lineEdit_video.setText(pr['video']) - + def savePreset(self): return { - 'video' : self.videoPath, + 'video': self.videoPath, } - + def pickVideo(self): imgDir = self.settings.value("backgroundDir", os.path.expanduser("~")) - filename = QtGui.QFileDialog.getOpenFileName(self.page, - "Choose Video", imgDir, "Video Files (*.mp4 *.mov)") + filename = QtGui.QFileDialog.getOpenFileName( + self.page, "Choose Video", + imgDir, "Video Files (*.mp4 *.mov)" + ) if filename: self.settings.setValue("backgroundDir", os.path.dirname(filename)) self.page.lineEdit_video.setText(filename) self.update() - + def getPreviewFrame(self, width, height): if not self.videoPath or not os.path.exists(self.videoPath): return @@ -139,7 +158,10 @@ class Component(__base__.Component): '-ss', '90', '-vframes', '1', ] - pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8) + pipe = subprocess.Popen( + command, stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, bufsize=10**8 + ) byteFrame = pipe.stdout.read(self.chunkSize) image = Image.frombytes('RGBA', (width, height), byteFrame) pipe.stdout.close() |
