2015-03-03 14:11:55 -05:00
|
|
|
from PyQt4 import QtCore, QtGui, uic
|
|
|
|
from PyQt4.QtCore import pyqtSignal, pyqtSlot
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
|
|
from PIL.ImageQt import ImageQt
|
|
|
|
import core
|
|
|
|
import numpy
|
|
|
|
import subprocess as sp
|
|
|
|
import sys
|
|
|
|
|
|
|
|
class Worker(QtCore.QObject):
|
|
|
|
|
|
|
|
videoCreated = pyqtSignal()
|
|
|
|
progressBarUpdate = pyqtSignal(int)
|
2017-05-21 22:44:48 -04:00
|
|
|
progressBarSetText = pyqtSignal(str)
|
2015-03-03 14:11:55 -05:00
|
|
|
|
|
|
|
def __init__(self, parent=None):
|
|
|
|
QtCore.QObject.__init__(self)
|
|
|
|
self.core = core.Core()
|
2017-05-27 04:06:17 -04:00
|
|
|
self.core.settings = parent.settings
|
|
|
|
parent.videoTask.connect(self.createVideo)
|
|
|
|
|
2015-03-03 14:11:55 -05:00
|
|
|
|
2017-05-22 19:42:32 -04:00
|
|
|
@pyqtSlot(str, str, QtGui.QFont, int, int, int, int, tuple, tuple, str, str)
|
|
|
|
def createVideo(self, backgroundImage, titleText, titleFont, fontSize, alignment,\
|
|
|
|
xOffset, yOffset, textColor, visColor, inputFile, outputFile):
|
2015-03-03 14:11:55 -05:00
|
|
|
# print('worker thread id: {}'.format(QtCore.QThread.currentThreadId()))
|
2017-05-18 19:14:27 -04:00
|
|
|
def getBackgroundAtIndex(i):
|
|
|
|
return self.core.drawBaseImage(
|
|
|
|
backgroundFrames[i],
|
|
|
|
titleText,
|
|
|
|
titleFont,
|
|
|
|
fontSize,
|
|
|
|
alignment,
|
|
|
|
xOffset,
|
2017-05-22 19:42:32 -04:00
|
|
|
yOffset,
|
|
|
|
textColor,
|
|
|
|
visColor)
|
2017-05-18 19:14:27 -04:00
|
|
|
|
2017-05-21 22:44:48 -04:00
|
|
|
progressBarValue = 0
|
|
|
|
self.progressBarUpdate.emit(progressBarValue)
|
|
|
|
self.progressBarSetText.emit('Loading background image…')
|
|
|
|
|
2017-05-18 19:14:27 -04:00
|
|
|
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
|
2017-05-21 22:44:48 -04:00
|
|
|
|
|
|
|
self.progressBarSetText.emit('Loading audio file…')
|
2015-03-03 14:11:55 -05:00
|
|
|
completeAudioArray = self.core.readAudioFile(inputFile)
|
|
|
|
|
2016-09-10 09:09:58 -04:00
|
|
|
# test if user has libfdk_aac
|
|
|
|
encoders = sp.check_output(self.core.FFMPEG_BIN + " -encoders -hide_banner", shell=True)
|
2017-05-27 04:06:17 -04:00
|
|
|
acodec = self.core.settings.value('outputAudioCodec')
|
2017-05-27 00:06:47 -04:00
|
|
|
|
|
|
|
if b'libfdk_aac' in encoders and acodec == 'aac':
|
2016-09-10 09:09:58 -04:00
|
|
|
acodec = 'libfdk_aac'
|
|
|
|
|
|
|
|
ffmpegCommand = [ self.core.FFMPEG_BIN,
|
2015-03-03 14:11:55 -05:00
|
|
|
'-y', # (optional) means overwrite the output file if it already exists.
|
|
|
|
'-f', 'rawvideo',
|
|
|
|
'-vcodec', 'rawvideo',
|
2017-05-27 04:06:17 -04:00
|
|
|
'-s', self.core.settings.value('outputWidth')+'x'+self.core.settings.value('outputHeight'), # size of one frame
|
2015-03-03 14:11:55 -05:00
|
|
|
'-pix_fmt', 'rgb24',
|
2017-05-27 04:06:17 -04:00
|
|
|
'-r', self.core.settings.value('outputFrameRate'), # frames per second
|
2015-03-03 14:11:55 -05:00
|
|
|
'-i', '-', # The input comes from a pipe
|
|
|
|
'-an',
|
|
|
|
'-i', inputFile,
|
2016-09-10 09:09:58 -04:00
|
|
|
'-acodec', acodec, # output audio codec
|
2017-05-27 04:06:17 -04:00
|
|
|
'-b:a', self.core.settings.value('outputAudioBitrate'),
|
|
|
|
'-vcodec', self.core.settings.value('outputVideoCodec'),
|
|
|
|
'-pix_fmt', self.core.settings.value('outputVideoFormat'),
|
|
|
|
'-preset', self.core.settings.value('outputPreset'),
|
|
|
|
'-f', self.core.settings.value('outputFormat')]
|
2016-09-10 09:09:58 -04:00
|
|
|
|
|
|
|
if acodec == 'aac':
|
|
|
|
ffmpegCommand.append('-strict')
|
|
|
|
ffmpegCommand.append('-2')
|
|
|
|
|
|
|
|
ffmpegCommand.append(outputFile)
|
2017-05-18 19:54:48 -04:00
|
|
|
|
2016-09-10 09:09:58 -04:00
|
|
|
out_pipe = sp.Popen(ffmpegCommand,
|
2015-03-03 14:11:55 -05:00
|
|
|
stdin=sp.PIPE,stdout=sys.stdout, stderr=sys.stdout)
|
|
|
|
|
|
|
|
smoothConstantDown = 0.08
|
|
|
|
smoothConstantUp = 0.8
|
|
|
|
lastSpectrum = None
|
|
|
|
sampleSize = 1470
|
2017-05-21 22:44:48 -04:00
|
|
|
|
2015-03-03 14:11:55 -05:00
|
|
|
numpy.seterr(divide='ignore')
|
2017-05-18 19:14:27 -04:00
|
|
|
bgI = 0
|
2015-03-03 14:11:55 -05:00
|
|
|
for i in range(0, len(completeAudioArray), sampleSize):
|
|
|
|
# create video for output
|
|
|
|
lastSpectrum = self.core.transformData(
|
|
|
|
i,
|
|
|
|
completeAudioArray,
|
|
|
|
sampleSize,
|
|
|
|
smoothConstantDown,
|
|
|
|
smoothConstantUp,
|
|
|
|
lastSpectrum)
|
2017-05-18 19:14:27 -04:00
|
|
|
if imBackground != None:
|
2017-05-22 19:42:32 -04:00
|
|
|
im = self.core.drawBars(lastSpectrum, imBackground, visColor)
|
2017-05-18 19:14:27 -04:00
|
|
|
else:
|
2017-05-22 19:42:32 -04:00
|
|
|
im = self.core.drawBars(lastSpectrum, getBackgroundAtIndex(bgI), visColor)
|
2017-05-18 19:14:27 -04:00
|
|
|
if bgI < len(backgroundFrames)-1:
|
|
|
|
bgI += 1
|
2015-03-03 14:11:55 -05:00
|
|
|
|
|
|
|
# write to out_pipe
|
|
|
|
try:
|
2016-08-17 17:34:05 -04:00
|
|
|
out_pipe.stdin.write(im.tobytes())
|
2015-03-03 14:11:55 -05:00
|
|
|
finally:
|
|
|
|
True
|
|
|
|
|
|
|
|
# increase progress bar value
|
|
|
|
if progressBarValue + 1 <= (i / len(completeAudioArray)) * 100:
|
|
|
|
progressBarValue = numpy.floor((i / len(completeAudioArray)) * 100)
|
|
|
|
self.progressBarUpdate.emit(progressBarValue)
|
2017-05-21 22:44:48 -04:00
|
|
|
self.progressBarSetText.emit('%s%%' % str(int(progressBarValue)))
|
2015-03-03 14:11:55 -05:00
|
|
|
|
|
|
|
numpy.seterr(all='print')
|
|
|
|
|
|
|
|
out_pipe.stdin.close()
|
|
|
|
if out_pipe.stderr is not None:
|
|
|
|
print(out_pipe.stderr.read())
|
|
|
|
out_pipe.stderr.close()
|
2015-03-04 05:54:29 -05:00
|
|
|
# out_pipe.terminate() # don't terminate ffmpeg too early
|
2015-03-03 14:11:55 -05:00
|
|
|
out_pipe.wait()
|
|
|
|
print("Video file created")
|
2017-05-22 16:58:05 -04:00
|
|
|
self.core.deleteTempDir()
|
2015-03-03 14:11:55 -05:00
|
|
|
self.progressBarUpdate.emit(100)
|
2017-05-21 22:44:48 -04:00
|
|
|
self.progressBarSetText.emit('100%')
|
2016-08-17 17:34:05 -04:00
|
|
|
self.videoCreated.emit()
|