diff --git a/.gitignore b/.gitignore index f4d88c1..845fbbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ __pycache__ settings.ini -build/* \ No newline at end of file +build/* +.ropeproject +.idea +*.egg-info +dist diff --git a/README.md b/README.md index a029f8d..179c323 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,17 @@ You need Python 3, PyQt4, PIL (or Pillow), numpy and the program ffmpeg, which i Installation ------------ +### Easy installation +* Install python +* Install pyqt4 using your package manager or by going to their website here [http://www.riverbankcomputing.co.uk/software/pyqt/download](http://www.riverbankcomputing.co.uk/software/pyqt/download) +* Install ffmpeg using your package manager or by going to their website here [https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html) +* Clone this repo: `git clone https://github.com/djfun/audio-visualizer-python` or by hitting the download button up top and unzipping. +* Navigate to the `audio-visualizer-python` directory in your terminal/command prompt (**Windows:** open the command prompt as administrator) +* Install using setuptools: `python setup.py install` +* You may need to use `sudo python setup.py install` if you don't have write permission to your python installation. This will install it system-wide. + +Once installed, run it with `audio-visualizer-python` from your command prompt. + ### Manual installation on Ubuntu * Get all the python stuff: `sudo apt install python3 python3-pyqt4 python3-pil python3-numpy` * If you have PyQt5 installed, get pillow (at least version 3.3.0) from pip: `apt install python3-pip; pip3 install pillow` diff --git a/avpython/__init__.py b/avpython/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core.py b/avpython/core.py similarity index 100% rename from core.py rename to avpython/core.py diff --git a/main.py b/avpython/main.py similarity index 97% rename from main.py rename to avpython/main.py index 9f608d8..5548e0a 100644 --- a/main.py +++ b/avpython/main.py @@ -11,12 +11,12 @@ from PyQt4.QtCore import QSettings import signal -import preview_thread, core, video_thread +from avpython import preview_thread, core, video_thread class Command(QtCore.QObject): - + videoTask = QtCore.pyqtSignal(str, str, QFont, int, int, int, int, tuple, tuple, str, str) - + def __init__(self): QtCore.QObject.__init__(self) @@ -36,7 +36,7 @@ def __init__(self): self.args = self.parser.parse_args() self.settings = QSettings('settings.ini', QSettings.IniFormat) - + # load colours as tuples from comma-separated strings self.textColor = core.Core.RGBFromString(self.settings.value("textColor", '255, 255, 255')) self.visColor = core.Core.RGBFromString(self.settings.value("visColor", '255, 255, 255')) @@ -44,13 +44,13 @@ def __init__(self): self.textColor = core.Core.RGBFromString(self.args.textcolor) if self.args.viscolor: self.visColor = core.Core.RGBFromString(self.args.viscolor) - + # font settings if self.args.font: self.font = QFont(self.args.font) else: self.font = QFont(self.settings.value("titleFont", QFont())) - + if self.args.fontsize: self.fontsize = int(self.args.fontsize) else: @@ -77,7 +77,7 @@ def __init__(self): self.videoWorker.moveToThread(self.videoThread) self.videoWorker.videoCreated.connect(self.videoCreated) - + self.videoThread.start() self.videoTask.emit(self.args.bgimage, self.args.text, @@ -119,7 +119,7 @@ def __init__(self, window): self.window = window self.core = core.Core() self.settings = QSettings('settings.ini', QSettings.IniFormat) - + # load colors as tuples from a comma-separated string self.textColor = core.Core.RGBFromString(self.settings.value("textColor", '255, 255, 255')) self.visColor = core.Core.RGBFromString(self.settings.value("visColor", '255, 255, 255')) @@ -131,13 +131,13 @@ def __init__(self, window): self.previewWorker.moveToThread(self.previewThread) self.previewWorker.imageCreated.connect(self.showPreviewImage) - + self.previewThread.start() self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.processTask.emit) self.timer.start(500) - + window.pushButton_selectInput.clicked.connect(self.openInputFileDialog) window.pushButton_selectOutput.clicked.connect(self.openOutputFileDialog) window.pushButton_createVideo.clicked.connect(self.createAudioVisualisation) @@ -176,7 +176,7 @@ def __init__(self, window): window.pushButton_visColor.setStyleSheet(btnStyle) titleFont = self.settings.value("titleFont") - if not titleFont == None: + if not titleFont == None: window.fontComboBox.setCurrentFont(QFont(titleFont)) alignment = self.settings.value("alignment") @@ -209,7 +209,7 @@ def cleanUp(self): self.timer.stop() self.previewThread.quit() self.previewThread.wait() - + self.settings.setValue("titleFont", self.window.fontComboBox.currentFont().toString()) self.settings.setValue("alignment", str(self.window.alignmentComboBox.currentIndex())) self.settings.setValue("fontSize", str(self.window.fontsizeSpinBox.value())) @@ -224,7 +224,7 @@ def openInputFileDialog(self): fileName = QtGui.QFileDialog.getOpenFileName(self.window, "Open Music File", inputDir, "Music Files (*.mp3 *.wav *.ogg *.flac)"); - if not fileName == "": + if not fileName == "": self.settings.setValue("inputDir", os.path.dirname(fileName)) self.window.label_input.setText(fileName) @@ -234,7 +234,7 @@ def openOutputFileDialog(self): fileName = QtGui.QFileDialog.getSaveFileName(self.window, "Set Output Video File", outputDir, "Video Files (*.mkv)"); - if not fileName == "": + if not fileName == "": self.settings.setValue("outputDir", os.path.dirname(fileName)) self.window.label_output.setText(fileName) @@ -244,7 +244,7 @@ def openBackgroundFileDialog(self): fileName = QtGui.QFileDialog.getOpenFileName(self.window, "Open Background Image", backgroundDir, "Image Files (*.jpg *.png);; Video Files (*.mp4)"); - if not fileName == "": + if not fileName == "": self.settings.setValue("backgroundDir", os.path.dirname(fileName)) self.window.label_background.setText(fileName) self.drawPreview() @@ -259,7 +259,7 @@ def createAudioVisualisation(self): 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(), self.window.lineEdit_title.text(), @@ -272,7 +272,7 @@ def createAudioVisualisation(self): core.Core.RGBFromString(self.window.lineEdit_visColor.text()), self.window.label_input.text(), self.window.label_output.text()) - + def progressBarUpdated(self, value): self.window.progressBar_create.setValue(value) @@ -314,17 +314,11 @@ def pickColor(self, colorTarget): self.window.lineEdit_visColor.setText(RGBstring) window.pushButton_visColor.setStyleSheet(btnStyle) -if len(sys.argv) > 1: - # command line mode - app = QtGui.QApplication(sys.argv, False) - command = Command() - signal.signal(signal.SIGINT, command.cleanUp) - sys.exit(app.exec_()) -else: - # gui mode - if __name__ == "__main__": + +def main(): app = QtGui.QApplication(sys.argv) - window = uic.loadUi("main.ui") + dir_path = os.path.dirname(os.path.realpath(__file__)) + window = uic.loadUi(os.path.join(dir_path, "main.ui")) # window.adjustSize() desc = QtGui.QDesktopWidget() dpi = desc.physicalDpiX() @@ -332,10 +326,21 @@ def pickColor(self, colorTarget): window.resize(window.width() * (dpi / 96), window.height() * (dpi / 96)) window.verticalLayout_2.setContentsMargins(0, topMargin, 0, 0) - + main = Main(window) signal.signal(signal.SIGINT, main.cleanUp) atexit.register(main.cleanUp) sys.exit(app.exec_()) + +if len(sys.argv) > 1: + # command line mode + app = QtGui.QApplication(sys.argv, False) + command = Command() + signal.signal(signal.SIGINT, command.cleanUp) + sys.exit(app.exec_()) +else: + # gui mode + if __name__ == "__main__": + main() diff --git a/main.ui b/avpython/main.ui similarity index 100% rename from main.ui rename to avpython/main.ui diff --git a/preview_thread.py b/avpython/preview_thread.py similarity index 98% rename from preview_thread.py rename to avpython/preview_thread.py index 041d39e..6ee2f8b 100644 --- a/preview_thread.py +++ b/avpython/preview_thread.py @@ -2,7 +2,7 @@ from PyQt4.QtCore import pyqtSignal, pyqtSlot from PIL import Image, ImageDraw, ImageFont from PIL.ImageQt import ImageQt -import core +from avpython import core import time from queue import Queue, Empty import numpy diff --git a/video_thread.py b/avpython/video_thread.py similarity index 99% rename from video_thread.py rename to avpython/video_thread.py index 6f71d38..fcf3840 100644 --- a/video_thread.py +++ b/avpython/video_thread.py @@ -2,7 +2,7 @@ from PyQt4.QtCore import pyqtSignal, pyqtSlot from PIL import Image, ImageDraw, ImageFont from PIL.ImageQt import ImageQt -import core +from avpython import core import numpy import subprocess as sp import sys @@ -46,7 +46,7 @@ def getBackgroundAtIndex(i): else: # base images will be drawn while drawing the audio bars imBackground = None - + self.progressBarSetText.emit('Loading audio file…') completeAudioArray = self.core.readAudioFile(inputFile) @@ -79,7 +79,7 @@ def getBackgroundAtIndex(i): ffmpegCommand.append('-2') ffmpegCommand.append(outputFile) - + out_pipe = sp.Popen(ffmpegCommand, stdin=sp.PIPE,stdout=sys.stdout, stderr=sys.stdout) @@ -87,7 +87,7 @@ def getBackgroundAtIndex(i): smoothConstantUp = 0.8 lastSpectrum = None sampleSize = 1470 - + numpy.seterr(divide='ignore') bgI = 0 for i in range(0, len(completeAudioArray), sampleSize): diff --git a/setup.py b/setup.py index 0d9cbc4..8424620 100644 --- a/setup.py +++ b/setup.py @@ -1,30 +1,19 @@ -from cx_Freeze import setup, Executable +from setuptools import setup, find_packages -# Dependencies are automatically detected, but it might need -# fine tuning. -buildOptions = dict(packages = [], excludes = [ - "apport", - "apt", - "ctypes", - "curses", - "distutils", - "email", - "html", - "http", - "json", - "xmlrpc", - "nose" - ], include_files = ["main.ui"]) - -import sys -base = 'Win32GUI' if sys.platform=='win32' else None - -executables = [ - Executable('main.py', base=base, targetName = 'audio-visualizer-python') -] - -setup(name='audio-visualizer-python', - version = '1.0', - description = 'a little GUI tool to render visualization videos of audio files', - options = dict(build_exe = buildOptions), - executables = executables) +setup(name='audio_visualizer_python', + version='1.0', + description='a little GUI tool to render visualization \ + videos of audio files', + license='MIT', + url='https://github.com/djfun/audio-visualizer-python', + packages=find_packages(), + package_data={ + 'avpython': ['main.ui'], + }, + install_requires=['pillow', 'numpy'], + entry_points={ + 'gui_scripts': [ + 'audio-visualizer-python = avpython.main:main' + ] + } + )