From 39e66ffa2d07b87b57ed90b369ab26aedf0a69e8 Mon Sep 17 00:00:00 2001 From: tassaron Date: Sun, 4 Jun 2017 13:00:36 -0400 Subject: video component almost working, rm hardcoded backgrounds --- core.py | 61 +++++++------------------------------------------------------ 1 file changed, 7 insertions(+), 54 deletions(-) (limited to 'core.py') diff --git a/core.py b/core.py index 16ecb35..ecbf12c 100644 --- a/core.py +++ b/core.py @@ -13,11 +13,8 @@ from collections import OrderedDict class Core(): def __init__(self): - self.lastBackgroundImage = "" - self._image = None - self.FFMPEG_BIN = self.findFfmpeg() - self.tempDir = None + self.tempDir = os.path.join(tempfile.gettempdir(), 'audio-visualizer-python-data') atexit.register(self.deleteTempDir) def findFfmpeg(self): @@ -31,31 +28,6 @@ class Core(): except: return "avconv" - def parseBaseImage(self, backgroundImage, preview=False): - ''' determines if the base image is a single frame or list of frames ''' - if backgroundImage == "": - return [''] - else: - _, bgExt = os.path.splitext(backgroundImage) - if not bgExt == '.mp4': - return [backgroundImage] - else: - return self.getVideoFrames(backgroundImage, preview) - - def drawBaseImage(self, backgroundFile): - if backgroundFile == '': - im = Image.new("RGB", (int(self.settings.value('outputWidth')), int(self.settings.value('outputHeight'))), "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 == (int(self.settings.value('outputWidth')), int(self.settings.value('outputHeight'))): - im = im.resize((int(self.settings.value('outputWidth')), int(self.settings.value('outputHeight'))), Image.ANTIALIAS) - - return im - def readAudioFile(self, filename, parent): command = [ self.FFMPEG_BIN, '-i', filename] @@ -121,30 +93,11 @@ class Core(): return completeAudioArray 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)]) + try: + if os.path.exists(self.tempDir): + rmtree(self.tempDir) + except FileNotFoundError: + pass def cancel(self): self.canceled = True @@ -153,6 +106,6 @@ class Core(): self.canceled = False @staticmethod - def sortedStringDict(dictionary): + def stringOrderedDict(dictionary): sorted_ = OrderedDict(sorted(dictionary.items(), key=lambda t: t[0])) return repr(sorted_) -- cgit v1.2.3 From 277e86f2795093deaa12f294c29ac2f951ae65cd Mon Sep 17 00:00:00 2001 From: tassaron Date: Sun, 4 Jun 2017 20:27:43 -0400 Subject: not dumping frames anymore, but not working yet either will finish later --- components/video.py | 69 +++++++++++++++++++++++++++++++++-------------------- core.py | 5 ++-- main.py | 2 +- video_thread.py | 1 - 4 files changed, 47 insertions(+), 30 deletions(-) (limited to 'core.py') diff --git a/components/video.py b/components/video.py index 1a9f344..97b824c 100644 --- a/components/video.py +++ b/components/video.py @@ -30,11 +30,11 @@ class Component(__base__.Component): def previewRender(self, previewWorker): self.width = int(previewWorker.core.settings.value('outputWidth')) self.height = int(previewWorker.core.settings.value('outputHeight')) - frames = self.getVideoFrames(True) - if not hasattr(self, 'staticFrame') or not self.working and frames: + frame1 = self.getPreviewFrame() + if not hasattr(self, 'staticFrame') or not self.working and frame1: frame = Image.new("RGBA", (self.width, self.height), (0, 0, 0, 0)) - if frames: - im = Image.open(frames[0]) + if frame1: + im = Image.open(frame1) im = self.resize(im) frame.paste(im) if not self.working: @@ -77,39 +77,56 @@ class Component(__base__.Component): self.settings.setValue("backgroundDir", os.path.dirname(filename)) self.page.lineEdit_video.setText(filename) self.update() - - def getVideoFrames(self, preview=False): - # recreate the temporary directory so it is empty - # FIXME: don't dump all the frames at once, don't dump more than sound length - # FIXME: make cancellable, report status to user, etc etc etc + + def getPreviewFrame(self): if not self.videoPath: return name = os.path.basename(self.videoPath).split('.', 1)[0] - if preview: - filename = 'preview%s.jpg' % name - if os.path.exists(os.path.join(self.parent.core.tempDir, filename)): - return False - else: - filename = name+'-frame%05d.jpg' - - # recreate tempDir and dump needed frame(s) - self.parent.core.deleteTempDir() - os.mkdir(self.parent.core.tempDir) - if preview: - options = '-ss 10 -vframes 1' - else: - options = '' #'-vframes 99999' + filename = 'preview%s.jpg' % name + if os.path.exists(os.path.join(self.parent.core.tempDir, filename)): + # no, we don't need a new preview frame + return False + + # get a preview frame subprocess.call( \ '%s -i "%s" -y %s "%s"' % ( \ self.parent.core.FFMPEG_BIN, self.videoPath, - options, + '-ss 10 -vframes 1', os.path.join(self.parent.core.tempDir, filename) ), shell=True ) - print('### Got Preview Frame From %s ###' % name if preview else '### Finished Dumping Frames From %s ###' % name) - return sorted([os.path.join(self.parent.core.tempDir, f) for f in os.listdir(self.parent.core.tempDir)]) + print('### Got Preview Frame From %s ###' % name) + return os.path.join(self.parent.core.tempDir, filename) + + def getVideoFrames(self): + # FIXME: make cancellable, report status to user, etc etc etc + if not self.videoPath: + return + + command = [ + self.parent.core.FFMPEG_BIN, + '-i', self.videoPath, + '-f', 'image2pipe', + '-vcodec', 'rawvideo', '-', + '-pix_fmt', 'rgba', + ] + + # pipe in video frames from ffmpeg + in_pipe = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=8**10) + # maybe bufsize=4*self.width*self.height+100 ? + chunk = 4*self.width*self.height + + frames = [] + while True: + byteFrame = in_pipe.stdout.read(chunk) + if len(byteFrame) == 0: + break + img = Image.frombytes('RGBA', (self.width, self.height), byteFrame, 'raw', 'RGBa') + frames.append(img) + + return frames def resize(self, im): if im.size != (self.width, self.height): diff --git a/core.py b/core.py index ecbf12c..99403f1 100644 --- a/core.py +++ b/core.py @@ -15,6 +15,8 @@ class Core(): def __init__(self): self.FFMPEG_BIN = self.findFfmpeg() self.tempDir = os.path.join(tempfile.gettempdir(), 'audio-visualizer-python-data') + if not os.path.exists(self.tempDir): + os.makedirs(self.tempDir) atexit.register(self.deleteTempDir) def findFfmpeg(self): @@ -94,8 +96,7 @@ class Core(): def deleteTempDir(self): try: - if os.path.exists(self.tempDir): - rmtree(self.tempDir) + rmtree(self.tempDir) except FileNotFoundError: pass diff --git a/main.py b/main.py index da72b1e..637ece8 100644 --- a/main.py +++ b/main.py @@ -253,7 +253,7 @@ class Main(QtCore.QObject): outputDir = self.settings.value("outputDir", expanduser("~")) fileName = QtGui.QFileDialog.getSaveFileName(self.window, - "Set Output Video File", outputDir, "Video Files (*.mkv)"); + "Set Output Video File", outputDir, "Video Files (*.mkv *.mp4)"); if not fileName == "": self.settings.setValue("outputDir", os.path.dirname(fileName)) diff --git a/video_thread.py b/video_thread.py index e74fffa..0542bc2 100644 --- a/video_thread.py +++ b/video_thread.py @@ -228,7 +228,6 @@ class Worker(QtCore.QObject): self.error = False self.canceled = False self.parent.drawPreview() - self.core.deleteTempDir() self.stopped = True self.encoding.emit(False) self.videoCreated.emit() -- cgit v1.2.3