diff --git a/core.py b/core.py index 8ea884b..7b3c69a 100644 --- a/core.py +++ b/core.py @@ -11,6 +11,7 @@ from shutil import rmtree import atexit import time from collections import OrderedDict +import json class Core(): @@ -22,6 +23,13 @@ class Core(): if not os.path.exists(self.tempDir): os.makedirs(self.tempDir) atexit.register(self.deleteTempDir) + self.wd = os.path.dirname(os.path.realpath(__file__)) + self.loadEncoderOptions() + + def loadEncoderOptions(self): + file_path = os.path.join(self.wd, 'encoder-options.json') + with open(file_path) as json_file: + self.encoder_options = json.load(json_file) def findFfmpeg(self): if sys.platform == "win32": diff --git a/encoder-options.json b/encoder-options.json index 699ead4..53aa0e5 100644 --- a/encoder-options.json +++ b/encoder-options.json @@ -6,32 +6,14 @@ "default-vcodec": "H264", "default-acodec": "AAC", "video-codecs": [ - { - "name": "H264", - "encoders": ["libx264"] - }, - { - "name": "H264 (nvenc)", - "encoders": ["nvenc_264"] - }, - { - "name": "MPEG4", - "encoders": ["mpeg4"] - } + "H264", + "H264 (nvenc)", + "MPEG4" ], "audio-codecs": [ - { - "name": "AAC", - "encoders": ["libfdk_aac","aac"] - }, - { - "name": "AC3", - "encoders": ["ac3"] - }, - { - "name": "MP3", - "encoders": ["libmp3lame"] - } + "AAC", + "AC3", + "MP3" ] }, { @@ -40,40 +22,37 @@ "default-vcodec": "H264", "default-acodec": "AAC", "video-codecs": [ - { - "name": "H264", - "encoders": ["libx264"] - }, - { - "name": "H264 (nvenc)", - "encoders": ["nvenc_264"] - }, - { - "name": "MPEG4", - "encoders": ["mpeg4"] - }, - { - "name": "XVID", - "encoders": ["libxvid"] - } + "H264", + "H264 (nvenc)", + "MPEG4", + "XVID" ], "audio-codecs": [ - { - "name": "AAC", - "encoders": ["libfdk_aac","aac"] - }, - { - "name": "AC3", - "encoders": ["ac3"] - }, - { - "name": "MP3", - "encoders": ["libmp3lame"] - }, - { - "name": "PCM s16 LE", - "encoders": ["pcm_s16le"] - } + "AAC", + "AC3", + "MP3", + "PCM s16 LE" + ] + }, + { + "name": "MKV", + "container": "matroska", + "default-vcodec": "H264", + "default-acodec": "AAC", + "video-codecs": [ + "H264", + "H264 (nvenc)", + "MPEG4", + "MPEG2", + "DV", + "WMV" + ], + "audio-codecs": [ + "AAC", + "AC3", + "MP3", + "PCM s16 LE", + "WMA" ] }, { @@ -82,52 +61,19 @@ "default-vcodec": "H264", "default-acodec": "AAC", "video-codecs": [ - { - "name": "H264", - "encoders": ["libx264"] - }, - { - "name": "H264 (nvenc)", - "encoders": ["nvenc_264"] - }, - { - "name": "MPEG4", - "encoders": ["mpeg4"] - }, - { - "name": "MPEG2", - "encoders": ["mp2video"] - }, - { - "name": "DV", - "encoders": ["dvvideo"] - }, - { - "name": "WMV", - "encoders": ["wmv2"] - } + "H264", + "H264 (nvenc)", + "MPEG4", + "MPEG2", + "DV", + "WMV" ], "audio-codecs": [ - { - "name": "AAC", - "encoders": ["libfdk_aac","aac"] - }, - { - "name": "AC3", - "encoders": ["ac3"] - }, - { - "name": "WMA", - "encoders": ["wmav2"] - }, - { - "name": "MP3", - "encoders": ["libmp3lame"] - }, - { - "name": "PCM s16 LE", - "encoders": ["pcm_s16le"] - } + "AAC", + "AC3", + "MP3", + "PCM s16 LE", + "WMA" ] }, { @@ -136,20 +82,11 @@ "default-vcodec": "VP9", "default-acodec": "Vorbis", "video-codecs": [ - { - "name": "VP9", - "encoders": ["libvpx-vp9"] - }, - { - "name": "VP8", - "encoders": ["libvpx"] - } + "VP9", + "VP8" ], "audio-codecs": [ - { - "name": "Vorbis", - "encoders": ["vorbis"] - } + "Vorbis" ] }, { @@ -158,34 +95,36 @@ "default-vcodec": "FLV", "default-acodec": "Vorbis", "video-codecs": [ - { - "name": "Sorenson (flv)", - "encoders": ["flv"] - }, - { - "name": "H264", - "encoders": ["libx264"] - }, - { - "name": "MPEG4", - "encoders": ["mpeg4"] - } + "Sorenson (flv)", + "H264", + "H264 (nvenc)", + "MPEG4" ], "audio-codecs": [ - { - "name": "MP3", - "encoders": ["libmp3lame"] - }, - { - "name": "Vorbis", - "encoders": ["vorbis"] - }, - { - "name": "PCM s16 LE", - "encoders": ["pcm_s16le"] - } + "MP3", + "PCM s16 LE", + "Vorbis" ] } - ] - + ], + "video-codecs":{ + "H264": ["libx264"], + "H264 (nvenc)": ["nvenc_264"], + "MPEG4": ["mpeg4"], + "VP9": ["libvpx-vp9"], + "VP8": ["libvpx"], + "XVID": ["libxvid"], + "Sorenson (flv)": ["flv"], + "MPEG2": ["mp2video"], + "DV": ["dvvideo"], + "WMV": ["wmv2"] + }, + "audio-codecs": { + "AAC": ["libfdk_aac","aac"], + "AC3": ["ac3"], + "MP3": ["libmp3lame"], + "PCM s16 LE": ["pcm_s16le"], + "WMA": ["wmav2"], + "Vorbis": ["libvorbis"] + } } \ No newline at end of file diff --git a/main.py b/main.py index 78c1d9b..3082e95 100644 --- a/main.py +++ b/main.py @@ -25,12 +25,13 @@ def LoadDefaultSettings(self): "outputWidth": 1280, "outputHeight": 720, "outputFrameRate": 30, - "outputAudioCodec": "aac", + "outputAudioCodec": "AAC", "outputAudioBitrate": "192k", - "outputVideoCodec": "libx264", + "outputVideoCodec": "H264", "outputVideoFormat": "yuv420p", "outputPreset": "medium", "outputFormat": "mp4", + "outputContainer": "MP4", "projectDir": os.path.join(self.dataDir, 'projects'), } diff --git a/mainwindow.py b/mainwindow.py index b779298..6fbc3ed 100644 --- a/mainwindow.py +++ b/mainwindow.py @@ -101,6 +101,37 @@ class MainWindow(QtCore.QObject): window.pushButton_Cancel.clicked.connect(self.stopVideo) window.setWindowTitle("Audio Visualizer") + for i, container in enumerate(self.core.encoder_options['containers']): + window.comboBox_videoContainer.addItem(container['name']) + if container['name'] == self.settings.value('outputContainer'): + selectedContainer = i + + window.comboBox_videoContainer.setCurrentIndex(selectedContainer) + window.comboBox_videoContainer.currentIndexChanged.connect( + self.updateCodecs + ) + + self.updateCodecs() + + for i in range(window.comboBox_videoCodec.count()): + codec = window.comboBox_videoCodec.itemText(i) + if codec == self.settings.value('outputVideoCodec'): + window.comboBox_videoCodec.setCurrentIndex(i) + print(codec) + + for i in range(window.comboBox_audioCodec.count()): + codec = window.comboBox_audioCodec.itemText(i) + if codec == self.settings.value('outputAudioCodec'): + window.comboBox_audioCodec.setCurrentIndex(i) + + window.comboBox_videoCodec.currentIndexChanged.connect( + self.updateCodecSettings + ) + + window.comboBox_audioCodec.currentIndexChanged.connect( + self.updateCodecSettings + ) + self.previewWindow = PreviewWindow(self, os.path.join( os.path.dirname(os.path.realpath(__file__)), "background.png")) window.verticalLayout_previewWrapper.addWidget(self.previewWindow) @@ -123,11 +154,11 @@ class MainWindow(QtCore.QObject): str(self.settings.value('outputHeight')) for i, res in enumerate(self.resolutions): window.comboBox_resolution.addItem(res) - if res == currentRes: - currentRes = i - window.comboBox_resolution.setCurrentIndex(currentRes) - window.comboBox_resolution.currentIndexChanged.connect( - self.updateResolution) + if res == currentRes: + currentRes = i + window.comboBox_resolution.setCurrentIndex(currentRes) + window.comboBox_resolution.currentIndexChanged.connect( + self.updateResolution) self.window.pushButton_listMoveUp.clicked.connect( self.moveComponentUp) @@ -171,6 +202,34 @@ class MainWindow(QtCore.QObject): self.previewThread.wait() self.autosave() + def updateCodecs(self): + containerWidget = self.window.comboBox_videoContainer + vCodecWidget = self.window.comboBox_videoCodec + aCodecWidget = self.window.comboBox_audioCodec + index = containerWidget.currentIndex() + name = containerWidget.itemText(index) + self.settings.setValue('outputContainer', name) + + vCodecWidget.clear() + aCodecWidget.clear() + + for container in self.core.encoder_options['containers']: + if container['name'] == name: + for vCodec in container['video-codecs']: + vCodecWidget.addItem(vCodec) + for aCodec in container['audio-codecs']: + aCodecWidget.addItem(aCodec) + + def updateCodecSettings(self): + vCodecWidget = self.window.comboBox_videoCodec + aCodecWidget = self.window.comboBox_audioCodec + currentVideoCodec = vCodecWidget.currentIndex() + currentVideoCodec = vCodecWidget.itemText(currentVideoCodec) + currentAudioCodec = aCodecWidget.currentIndex() + currentAudioCodec = aCodecWidget.itemText(currentAudioCodec) + self.settings.setValue('outputVideoCodec', currentVideoCodec) + self.settings.setValue('outputAudioCodec', currentAudioCodec) + def autosave(self): if time.time() - self.lastAutosave >= 1.0: if os.path.exists(self.autosavePath): @@ -285,7 +344,7 @@ class MainWindow(QtCore.QObject): self.videoThread.wait() def updateResolution(self): - resIndex = int(window.comboBox_resolution.currentIndex()) + resIndex = int(self.window.comboBox_resolution.currentIndex()) res = self.resolutions[resIndex].split('x') self.settings.setValue('outputWidth', res[0]) self.settings.setValue('outputHeight', res[1]) diff --git a/video_thread.py b/video_thread.py index 5897ff0..d8694a4 100644 --- a/video_thread.py +++ b/video_thread.py @@ -101,10 +101,35 @@ class Worker(QtCore.QObject): # test if user has libfdk_aac encoders = sp.check_output( self.core.FFMPEG_BIN + " -encoders -hide_banner", shell=True) + + encoders = encoders.decode("utf-8") + acodec = self.core.settings.value('outputAudioCodec') - if b'libfdk_aac' in encoders and acodec == 'aac': - acodec = 'libfdk_aac' + options = self.core.encoder_options + containerName = self.core.settings.value('outputContainer') + vcodec = self.core.settings.value('outputVideoCodec') + acodec = self.core.settings.value('outputAudioCodec') + + for cont in options['containers']: + if cont['name'] == containerName: + container = cont['container'] + + vencoders = options['video-codecs'][vcodec] + aencoders = options['audio-codecs'][acodec] + + print(encoders) + for encoder in vencoders: + print(encoder) + if encoder in encoders: + vencoder = encoder + break + + for encoder in aencoders: + print(encoder) + if encoder in encoders: + aencoder = encoder + break ffmpegCommand = [ self.core.FFMPEG_BIN, @@ -120,12 +145,12 @@ class Worker(QtCore.QObject): '-i', '-', # The input comes from a pipe '-an', '-i', inputFile, - '-acodec', acodec, # output audio codec + '-vcodec', vencoder, + '-acodec', aencoder, # output audio codec '-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') + '-f', container ] if acodec == 'aac':