Merge branch 'master' into feature-commandline

This commit is contained in:
Martin Kaistra 2017-05-22 10:50:18 +02:00
commit f63c1c382d
5 changed files with 103 additions and 28 deletions

61
core.py
View File

@ -6,6 +6,9 @@ import subprocess as sp
import numpy
from PIL import Image, ImageDraw, ImageFont
from PIL.ImageQt import ImageQt
import tempfile
from shutil import rmtree
import atexit
class Core():
@ -14,6 +17,8 @@ class Core():
self._image = None
self.FFMPEG_BIN = self.findFfmpeg()
self.tempDir = None
atexit.register(self.deleteTempDir)
def findFfmpeg(self):
if sys.platform == "win32":
@ -26,22 +31,32 @@ class Core():
except:
return "avconv"
def drawBaseImage(self, backgroundImage, titleText, titleFont, fontSize, alignment, xOffset, yOffset):
if self._image == None or not self.lastBackgroundImage == backgroundImage:
self.lastBackgroundImage = backgroundImage
def parseBaseImage(self, backgroundImage, preview=False):
''' determines if the base image is a single frame or list of frames '''
if backgroundImage == "":
im = Image.new("RGB", (1280, 720), "black")
return []
else:
im = Image.open(backgroundImage)
_, bgExt = os.path.splitext(backgroundImage)
if not bgExt == '.mp4':
return [backgroundImage]
else:
return self.getVideoFrames(backgroundImage, preview)
def drawBaseImage(self, backgroundFile, titleText, titleFont, fontSize, alignment, xOffset, yOffset):
if backgroundFile == '':
im = Image.new("RGB", (1280, 720), "black")
else:
im = Image.open(backgroundFile)
if self._image == None or not self.lastBackgroundImage == backgroundFile:
self.lastBackgroundImage = backgroundFile
# resize if necessary
if not im.size == (1280, 720):
im = im.resize((1280, 720), Image.ANTIALIAS)
self._image = ImageQt(im)
self._image1 = QtGui.QImage(self._image)
painter = QPainter(self._image1)
font = titleFont
@ -81,9 +96,8 @@ class Core():
imBottom = imTop.transpose(Image.FLIP_TOP_BOTTOM)
im = Image.new("RGB", (1280, 720), "black")
im.paste(image, (0, 0))
im.paste(imTop, (0, 0), mask=imTop)
im.paste(imBottom, (0, 360), mask=imBottom)
@ -150,3 +164,30 @@ class Core():
x = frequencies[0:int(paddedSampleSize/2) - 1]
return lastSpectrum
def deleteTempDir(self):
if self.tempDir and os.path.exists(self.tempDir):
rmtree(self.tempDir)
def getVideoFrames(self, videoPath, firstOnly=False):
self.tempDir = os.path.join(tempfile.gettempdir(), 'audio-visualizer-python-data')
# recreate the temporary directory so it is empty
self.deleteTempDir()
os.mkdir(self.tempDir)
if firstOnly:
filename = 'preview%s.jpg' % os.path.basename(videoPath).split('.', 1)[0]
options = '-ss 10 -vframes 1'
else:
filename = '$frame%05d.jpg'
options = ''
sp.call( \
'%s -i "%s" -y %s "%s"' % ( \
self.FFMPEG_BIN,
videoPath,
options,
os.path.join(self.tempDir, filename)
),
shell=True
)
return sorted([os.path.join(self.tempDir, f) for f in os.listdir(self.tempDir)])

View File

@ -191,7 +191,7 @@ class Main(QtCore.QObject):
backgroundDir = self.settings.value("backgroundDir", expanduser("~"))
fileName = QtGui.QFileDialog.getOpenFileName(self.window,
"Open Background Image", backgroundDir, "Image Files (*.jpg *.png)");
"Open Background Image", backgroundDir, "Image Files (*.jpg *.png);; Video Files (*.mp4)");
if not fileName == "":
self.settings.setValue("backgroundDir", os.path.dirname(fileName))
@ -207,6 +207,7 @@ class Main(QtCore.QObject):
self.videoWorker.moveToThread(self.videoThread)
self.videoWorker.videoCreated.connect(self.videoCreated)
self.videoWorker.progressBarUpdate.connect(self.progressBarUpdated)
self.videoWorker.progressBarSetText.connect(self.progressBarSetText)
self.videoThread.start()
self.videoTask.emit(self.window.label_background.text(),
@ -223,6 +224,9 @@ class Main(QtCore.QObject):
def progressBarUpdated(self, value):
self.window.progressBar_create.setValue(value)
def progressBarSetText(self, value):
self.window.progressBar_create.setFormat(value)
def videoCreated(self):
self.videoThread.quit()
self.videoThread.wait()

View File

@ -386,7 +386,10 @@
<number>24</number>
</property>
<property name="textVisible">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="alignment">
<enum>Qt::AlignCenter</enum>
</property>
</widget>
</item>

View File

@ -43,8 +43,17 @@ class Worker(QtCore.QObject):
except Empty:
continue
bgImage = self.core.parseBaseImage(\
nextPreviewInformation["backgroundImage"],
preview=True
)
if bgImage == []:
bgImage = ''
else:
bgImage = bgImage[0]
im = self.core.drawBaseImage(
nextPreviewInformation["backgroundImage"],
bgImage,
nextPreviewInformation["titleText"],
nextPreviewInformation["titleFont"],
nextPreviewInformation["fontSize"],

View File

@ -11,6 +11,7 @@ class Worker(QtCore.QObject):
videoCreated = pyqtSignal()
progressBarUpdate = pyqtSignal(int)
progressBarSetText = pyqtSignal(str)
def __init__(self, parent=None):
QtCore.QObject.__init__(self)
@ -21,18 +22,29 @@ class Worker(QtCore.QObject):
@pyqtSlot(str, str, QtGui.QFont, int, int, int, int, str, str)
def createVideo(self, backgroundImage, titleText, titleFont, fontSize, alignment, xOffset, yOffset, inputFile, outputFile):
# print('worker thread id: {}'.format(QtCore.QThread.currentThreadId()))
imBackground = self.core.drawBaseImage(
backgroundImage,
titleText,
titleFont,
fontSize,
alignment,
xOffset,
yOffset)
def getBackgroundAtIndex(i):
return self.core.drawBaseImage(
backgroundFrames[i],
titleText,
titleFont,
fontSize,
alignment,
xOffset,
yOffset)
self.progressBarUpdate.emit(0)
progressBarValue = 0
self.progressBarUpdate.emit(progressBarValue)
self.progressBarSetText.emit('Loading background image…')
backgroundFrames = self.core.parseBaseImage(backgroundImage)
if len(backgroundFrames) < 2:
# the base image is not a video so we can draw it now
imBackground = getBackgroundAtIndex(0)
else:
# base images will be drawn while drawing the audio bars
imBackground = None
self.progressBarSetText.emit('Loading audio file…')
completeAudioArray = self.core.readAudioFile(inputFile)
# test if user has libfdk_aac
@ -71,11 +83,10 @@ class Worker(QtCore.QObject):
smoothConstantDown = 0.08
smoothConstantUp = 0.8
lastSpectrum = None
progressBarValue = 0
sampleSize = 1470
numpy.seterr(divide='ignore')
bgI = 0
for i in range(0, len(completeAudioArray), sampleSize):
# create video for output
lastSpectrum = self.core.transformData(
@ -85,7 +96,12 @@ class Worker(QtCore.QObject):
smoothConstantDown,
smoothConstantUp,
lastSpectrum)
im = self.core.drawBars(lastSpectrum, imBackground)
if imBackground != None:
im = self.core.drawBars(lastSpectrum, imBackground)
else:
im = self.core.drawBars(lastSpectrum, getBackgroundAtIndex(bgI))
if bgI < len(backgroundFrames)-1:
bgI += 1
# write to out_pipe
try:
@ -97,6 +113,7 @@ class Worker(QtCore.QObject):
if progressBarValue + 1 <= (i / len(completeAudioArray)) * 100:
progressBarValue = numpy.floor((i / len(completeAudioArray)) * 100)
self.progressBarUpdate.emit(progressBarValue)
self.progressBarSetText.emit('%s%%' % str(int(progressBarValue)))
numpy.seterr(all='print')
@ -108,4 +125,5 @@ class Worker(QtCore.QObject):
out_pipe.wait()
print("Video file created")
self.progressBarUpdate.emit(100)
self.progressBarSetText.emit('100%')
self.videoCreated.emit()