From cb45bd6b5c49d0ed92612537fc6106c62da11fee Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 21:45:40 +0000 Subject: [PATCH 01/37] Test building with pyinstaller --- .github/workflows/build-binary.yaml | 34 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 1f86b98..40fc559 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -24,8 +24,9 @@ jobs: - name: Install Dependencies run: | - pip install -r requirements.txt - pip install imageio + pip install -Ur requirements.txt + pip install -U pillow + pip install -U pyinstaller - name: Set build vars id: build-vars @@ -33,23 +34,28 @@ jobs: echo "version=$(cat version)" >> "$GITHUB_OUTPUT" - name: Build Executable - uses: Nuitka/Nuitka-Action@main - with: - nuitka-version: main - script-name: describealign.py - macos-app-version: "${{ steps.build-vars.outputs.version }}" - product-version: "${{ steps.build-vars.outputs.version }}" + run: | + pyinstaller \ + --onedir \ + --windowed \ + -i describealign.png \ + describealign.py - name: Build artifacts if: ${{ runner.os == 'macOS' }} working-directory: build run: | - mv Info.plist Resources *.app/Contents - productbuild --component describealign.app /Applications --product ../Package/product.plist describealign.pkg + productbuild \ + --component describealign.app /Applications \ + --product ../Package/product.plist \ + --version '${{steps.build-vars.outputs.version}}' + describealign.pkg + + ls -la dist - name: Build artifacts if: ${{ runner.os == 'Linux' }} - working-directory: build + working-directory: dist run: | tar cvf describealign.tar *.bin @@ -58,7 +64,7 @@ jobs: with: name: ${{ runner.os }} Build path: | - build/*.exe - build/*.tar - build/*.pkg + dist/*.exe + dist/*.tar + dist/*.pkg compression-level: 0 From 8827b4762da6ec2215b6736e348bd67c1bd40f06 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 21:50:08 +0000 Subject: [PATCH 02/37] Move ls to right place --- .github/workflows/build-binary.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 40fc559..f45f5ef 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -40,6 +40,7 @@ jobs: --windowed \ -i describealign.png \ describealign.py + ls -la - name: Build artifacts if: ${{ runner.os == 'macOS' }} @@ -48,11 +49,9 @@ jobs: productbuild \ --component describealign.app /Applications \ --product ../Package/product.plist \ - --version '${{steps.build-vars.outputs.version}}' + --version '${{steps.build-vars.outputs.version}}' \ describealign.pkg - ls -la dist - - name: Build artifacts if: ${{ runner.os == 'Linux' }} working-directory: dist From be6b0c8f019d17b5b672406f2c130450f8396a51 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 21:58:18 +0000 Subject: [PATCH 03/37] Add linux build dependencies --- .github/workflows/build-binary.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index f45f5ef..3ac1ffa 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -10,6 +10,19 @@ jobs: runs-on: ${{ matrix.os }} steps: + - name: Install Linux packages + run: | + sudo apt-get update -qq + sudo apt-get install -y -qq \ + libxcb-render-util0-dev \ + libxcb-keysyms1-dev \ + libxcb-shape0-dev \ + libxcb-xinerama0-dev \ + libxcb-icccm4-dev \ + libxcb-image0-dev \ + libxkbcommon-x11-dev \ + libxcb-util-dev + - name: Check-out repository uses: actions/checkout@v4 @@ -40,7 +53,7 @@ jobs: --windowed \ -i describealign.png \ describealign.py - ls -la + ls -la dist - name: Build artifacts if: ${{ runner.os == 'macOS' }} From b4d497229668704dd65db60eb05b5845e4173360 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 21:59:26 +0000 Subject: [PATCH 04/37] Install linux packages only on linux --- .github/workflows/build-binary.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 3ac1ffa..2f225b2 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -11,6 +11,7 @@ jobs: steps: - name: Install Linux packages + if: ${{ runner.os == 'Linux' }} run: | sudo apt-get update -qq sudo apt-get install -y -qq \ From 82c7839c71f114a20540b6492de9bf81b38c4502 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 22:03:03 +0000 Subject: [PATCH 05/37] Remove windows line continuation --- .github/workflows/build-binary.yaml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 2f225b2..20cffd2 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -38,23 +38,19 @@ jobs: - name: Install Dependencies run: | + pip install -U pip wheel pip install -Ur requirements.txt pip install -U pillow pip install -U pyinstaller - name: Set build vars id: build-vars - run: | - echo "version=$(cat version)" >> "$GITHUB_OUTPUT" + run: echo "version=$(cat version)" >> "$GITHUB_OUTPUT" - name: Build Executable run: | - pyinstaller \ - --onedir \ - --windowed \ - -i describealign.png \ - describealign.py - ls -la dist + pyinstaller --onedir --windowed -i describealign.png describealign.py + ls dist - name: Build artifacts if: ${{ runner.os == 'macOS' }} From 15e6f14c751814b81c6c6e3012a568b35467dd9b Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 22:11:39 +0000 Subject: [PATCH 06/37] Handle build artifacts from pyinstaller --- .github/workflows/build-binary.yaml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 20cffd2..cc63d93 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -54,6 +54,7 @@ jobs: - name: Build artifacts if: ${{ runner.os == 'macOS' }} + id: build-artifacts-mac working-directory: build run: | productbuild \ @@ -61,19 +62,27 @@ jobs: --product ../Package/product.plist \ --version '${{steps.build-vars.outputs.version}}' \ describealign.pkg - + - name: Build artifacts if: ${{ runner.os == 'Linux' }} + id: build-artifacts-linux + working-directory: dist + run: | + tar cvf describealign.tar describealign + + - name: Build Artifacts + if: ${{runner.os == 'Windows'}} working-directory: dist run: | - tar cvf describealign.tar *.bin + mv describealign describealign.windows - name: Upload Artifacts uses: actions/upload-artifact@v4 with: name: ${{ runner.os }} Build path: | - dist/*.exe - dist/*.tar dist/*.pkg + dist/*.tar + dist/*.win compression-level: 0 + if-no-files-found: error From 57b5f6898fe780ec54f41103040297521cbf9039 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 22:28:34 +0000 Subject: [PATCH 07/37] Fix output dir for macos .app --- .github/workflows/build-binary.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index cc63d93..be28670 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -55,7 +55,7 @@ jobs: - name: Build artifacts if: ${{ runner.os == 'macOS' }} id: build-artifacts-mac - working-directory: build + working-directory: dist run: | productbuild \ --component describealign.app /Applications \ From f2aa5aace0817f22de5d63265eb62c632cc1bed6 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 22:57:42 +0000 Subject: [PATCH 08/37] Use platformdirs to generate default paths This ensures the paths are consistent with other apps, and that, for example, the config file is not stored in the .app bundle (which has the wrong file permissions) --- describealign.py | 15 ++++++++------- requirements.txt | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/describealign.py b/describealign.py index 717baea..febd279 100644 --- a/describealign.py +++ b/describealign.py @@ -84,8 +84,10 @@ import glob import itertools import datetime +from pathlib import Path import numpy as np import ffmpeg +import platformdirs import static_ffmpeg import python_speech_features as psf import scipy.signal @@ -99,15 +101,14 @@ import multiprocessing import platform +default_output_dir = platformdirs.user_videos_path() / 'videos_with_ad' +default_alignment_dir = platformdirs.user_data_path('describealign') / 'alignment_plots' + IS_RUNNING_WINDOWS = platform.system() == 'Windows' if IS_RUNNING_WINDOWS: import PySimpleGUIWx as sg - default_output_dir = 'videos_with_ad' - default_alignment_dir = 'alignment_plots' else: import PySimpleGUIQt as sg - default_output_dir = os.path.expanduser('~') + '/videos_with_ad' - default_alignment_dir = os.path.expanduser('~') + '/alignment_plots' def display(text, func=None): if func: @@ -977,7 +978,7 @@ def write_config_file(config_path, settings): with open(config_path, 'w') as f: config.write(f) -def read_config_file(config_path): +def read_config_file(config_path: Path): config = configparser.ConfigParser() config.read(config_path) settings = {'smoothness': config.getfloat('alignment', 'smoothness', fallback=50), @@ -995,7 +996,7 @@ def read_config_file(config_path): write_config_file(config_path, settings) return settings -def settings_gui(config_path): +def settings_gui(config_path: Path): settings = read_config_file(config_path) layout = [[sg.Text('Check tooltips (i.e. mouse-over text) for descriptions:')], [sg.Column([[sg.Text('extension:', size=(10, 1.2), pad=(1,5)), @@ -1125,7 +1126,7 @@ def combine_gui(video_files, audio_files, config_path): combine_window.close() def main_gui(): - config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.ini') + config_path = platformdirs.user_config_path(appname='describealign', ensure_exists=True) / 'config.ini' sg.theme('Light Blue 2') filetype_sep = ';' if IS_RUNNING_WINDOWS else ' ' diff --git a/requirements.txt b/requirements.txt index af751a0..9d4cbac 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ matplotlib~=3.5.0 numpy~=1.21.4 python_speech_features~=0.6 scipy~=1.10.1 +platformdirs~=4.2.0 pytsmod~=0.3.7 PySimpleGUIWx~=0.17.2; platform_system == 'Windows' PySimpleGUIQt~=0.35.0; platform_system != 'Windows' From dee69a8ec565990efc341e738ffa2f5e89d77b60 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Wed, 28 Feb 2024 23:41:51 +0000 Subject: [PATCH 09/37] Fix windows artifact path --- .github/workflows/build-binary.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index be28670..931ac92 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -83,6 +83,6 @@ jobs: path: | dist/*.pkg dist/*.tar - dist/*.win + dist/*.windows compression-level: 0 if-no-files-found: error From dfcbcfa8786ce3a500bc2581a6d30a9ca589835e Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Thu, 29 Feb 2024 01:10:26 +0000 Subject: [PATCH 10/37] Try macos homedir install to fix permissions issue --- .github/workflows/build-binary.yaml | 2 +- Package/product.plist | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 931ac92..5d27755 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -58,7 +58,7 @@ jobs: working-directory: dist run: | productbuild \ - --component describealign.app /Applications \ + --component describealign.app \ --product ../Package/product.plist \ --version '${{steps.build-vars.outputs.version}}' \ describealign.pkg diff --git a/Package/product.plist b/Package/product.plist index efbb93d..c78a964 100644 --- a/Package/product.plist +++ b/Package/product.plist @@ -5,7 +5,7 @@ - + home + From ca7b5be98fdd43933c6b1d8997b570103457d74b Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 19:28:04 +0000 Subject: [PATCH 11/37] Disable homedir install, add .spec artifcts, install ffmpeg on mac --- .github/workflows/build-binary.yaml | 19 +++++++++++++++---- Package/product.plist | 4 ++-- Package/scripts/postinstall | 2 ++ describealign.py | 9 +++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 Package/scripts/postinstall diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 5d27755..635f225 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -40,8 +40,7 @@ jobs: run: | pip install -U pip wheel pip install -Ur requirements.txt - pip install -U pillow - pip install -U pyinstaller + pip install -U pillow pyinstaller - name: Set build vars id: build-vars @@ -50,15 +49,18 @@ jobs: - name: Build Executable run: | pyinstaller --onedir --windowed -i describealign.png describealign.py - ls dist - name: Build artifacts if: ${{ runner.os == 'macOS' }} id: build-artifacts-mac working-directory: dist run: | - productbuild \ + pkgbuild \ + --scripts ../Package/scripts \ --component describealign.app \ + /tmp/describealign-component.pkg + productbuild \ + --package /tmp/describealign-component.pkg \ --product ../Package/product.plist \ --version '${{steps.build-vars.outputs.version}}' \ describealign.pkg @@ -86,3 +88,12 @@ jobs: dist/*.windows compression-level: 0 if-no-files-found: error + + - name: Upload specs + uses: actions/upload-artifact@v4 + with: + name: ${{ runner.os }} spec + path: | + *.spec + compression-level: 0 + if-no-files-found: error diff --git a/Package/product.plist b/Package/product.plist index c78a964..efbb93d 100644 --- a/Package/product.plist +++ b/Package/product.plist @@ -5,7 +5,7 @@ - home - + diff --git a/Package/scripts/postinstall b/Package/scripts/postinstall new file mode 100644 index 0000000..cff1b35 --- /dev/null +++ b/Package/scripts/postinstall @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +exec "$DSTROOT/describealign.app/Contents/MacOS/describealign" --install-ffmpeg diff --git a/describealign.py b/describealign.py index febd279..d41219e 100644 --- a/describealign.py +++ b/describealign.py @@ -85,10 +85,12 @@ import itertools import datetime from pathlib import Path +import sys import numpy as np import ffmpeg import platformdirs import static_ffmpeg +import static_ffmpeg.run import python_speech_features as psf import scipy.signal import scipy.optimize @@ -1233,8 +1235,15 @@ def error(self, message): parser.add_argument("--extension", default="copy", help='File type of output video (e.g. mkv). When set to "copy", copies the ' + \ 'file type of the corresponding input video. Default is "copy".') + parser.add_argument("--install-ffmpeg", action="store_true", + help="Install the required ffmpeg binaries and then exit. This is meant to be" + \ + "run from a privileged installer process (e.g. OS X Installer)") args = parser.parse_args() + if args.install_ffmpeg: + static_ffmpeg.run.get_or_fetch_platform_executables_else_raise() + sys.exit(0) + combine(args.video, args.audio, args.smoothness, args.stretch_audio, args.keep_non_ad, args.boost, args.ad_detect_sensitivity, args.boost_sensitivity, args.yes, args.prepend, args.no_pitch_correction, args.output_dir, args.alignment_dir, From ee135dc4559fea4ef9cfad951c8743e0bee29e16 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 20:22:23 +0000 Subject: [PATCH 12/37] Add spec file for build --- .github/workflows/build-binary.yaml | 22 ++++--------- .gitignore | 2 +- describealign.spec | 51 +++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 describealign.spec diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 635f225..846951c 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -48,22 +48,23 @@ jobs: - name: Build Executable run: | - pyinstaller --onedir --windowed -i describealign.png describealign.py + pyinstaller describealign.spec + env: + APP_VERSION: ${{ steps.build-vars.outputs.version }} - name: Build artifacts if: ${{ runner.os == 'macOS' }} id: build-artifacts-mac - working-directory: dist run: | pkgbuild \ - --scripts ../Package/scripts \ - --component describealign.app \ + --scripts Package/scripts \ + --component dist/describealign.app \ /tmp/describealign-component.pkg productbuild \ --package /tmp/describealign-component.pkg \ - --product ../Package/product.plist \ + --product Package/product.plist \ --version '${{steps.build-vars.outputs.version}}' \ - describealign.pkg + dist/describealign.pkg - name: Build artifacts if: ${{ runner.os == 'Linux' }} @@ -88,12 +89,3 @@ jobs: dist/*.windows compression-level: 0 if-no-files-found: error - - - name: Upload specs - uses: actions/upload-artifact@v4 - with: - name: ${{ runner.os }} spec - path: | - *.spec - compression-level: 0 - if-no-files-found: error diff --git a/.gitignore b/.gitignore index 68bc17f..354ae1c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,7 @@ MANIFEST # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest -*.spec +# *.spec # Installer logs pip-log.txt diff --git a/describealign.spec b/describealign.spec new file mode 100644 index 0000000..d2f6a85 --- /dev/null +++ b/describealign.spec @@ -0,0 +1,51 @@ +# -*- mode: python ; coding: utf-8 -*- +import os + +a = Analysis( + ['describealign.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name='describealign', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=False, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon=['describealign.png'], +) +coll = COLLECT( + exe, + a.binaries, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='describealign', +) +app = BUNDLE( + coll, + name='describealign.app', + icon='describealign.png', + bundle_identifier=None, + version=os.getenv('APP_VERSION'), +) From 64da2906068f495d84f22e0a1e676c86d2647cfd Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 20:50:28 +0000 Subject: [PATCH 13/37] Set exec bit on script --- Package/scripts/postinstall | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Package/scripts/postinstall diff --git a/Package/scripts/postinstall b/Package/scripts/postinstall old mode 100644 new mode 100755 From 130792c6738e956fd7b90888e8a5e77eafef7e26 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 21:16:08 +0000 Subject: [PATCH 14/37] Allow running describe-align with only --install-ffmpeg --- describealign.py | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/describealign.py b/describealign.py index d41219e..8d6ae36 100644 --- a/describealign.py +++ b/describealign.py @@ -1187,20 +1187,11 @@ def main_gui(): # Entry point for command line interaction, for example: # > describealign video.mp4 audio_desc.mp3 def command_line_interface(): - # override command line argument parser's error handler to make it pause before exiting - # this allows users to see the error message when accidentally not running from command line - class ArgumentParser(argparse.ArgumentParser): - def error(self, message): - if 'required: video, audio' in message: - print('No input arguments detected, starting GUI...') - main_gui() - self.exit() - else: - self.exit(2, f'{self.prog}: error: {message}\n') - parser = ArgumentParser(description="Replaces a video's sound with an audio description.", + parser = argparse.ArgumentParser( + description="Replaces a video's sound with an audio description.", usage="describealign video_file.mp4 audio_file.mp3") - parser.add_argument("video", help='A video file or directory containing video files.') - parser.add_argument("audio", help='An audio file or directory containing audio files.') + parser.add_argument("video", help='A video file or directory containing video files.', default=None) + parser.add_argument("audio", help='An audio file or directory containing audio files.', default=None) parser.add_argument('--smoothness', type=float, default=50, help='Lower values make the alignment more accurate when there are skips ' + \ '(e.g. describer pauses), but also make it more likely to misalign. ' + \ @@ -1242,12 +1233,13 @@ def error(self, message): if args.install_ffmpeg: static_ffmpeg.run.get_or_fetch_platform_executables_else_raise() - sys.exit(0) - - combine(args.video, args.audio, args.smoothness, args.stretch_audio, args.keep_non_ad, - args.boost, args.ad_detect_sensitivity, args.boost_sensitivity, args.yes, - args.prepend, args.no_pitch_correction, args.output_dir, args.alignment_dir, - args.extension) + elif args.video or args.audio: + combine(args.video, args.audio, args.smoothness, args.stretch_audio, args.keep_non_ad, + args.boost, args.ad_detect_sensitivity, args.boost_sensitivity, args.yes, + args.prepend, args.no_pitch_correction, args.output_dir, args.alignment_dir, + args.extension) + else: + main_gui() # allows the script to be run on its own, rather than through the package, for example: # python3 describealign.py video.mp4 audio_desc.mp3 From 4657abfa9fc967e28e422907db6f39e9a5e21a60 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 21:21:28 +0000 Subject: [PATCH 15/37] Handle no args early in execution --- describealign.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/describealign.py b/describealign.py index 8d6ae36..6a8dba5 100644 --- a/describealign.py +++ b/describealign.py @@ -1187,6 +1187,11 @@ def main_gui(): # Entry point for command line interaction, for example: # > describealign video.mp4 audio_desc.mp3 def command_line_interface(): + if len(sys.argv) < 2: + # No args, run gui + main_gui() + sys.exit(0) + parser = argparse.ArgumentParser( description="Replaces a video's sound with an audio description.", usage="describealign video_file.mp4 audio_file.mp3") @@ -1239,7 +1244,7 @@ def command_line_interface(): args.prepend, args.no_pitch_correction, args.output_dir, args.alignment_dir, args.extension) else: - main_gui() + parser.print_usage() # allows the script to be run on its own, rather than through the package, for example: # python3 describealign.py video.mp4 audio_desc.mp3 From 9b6ee4834a124a82d031de4bb581694e07adc143 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 22:01:49 +0000 Subject: [PATCH 16/37] Fix positional arguments --- describealign.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/describealign.py b/describealign.py index 6a8dba5..ed3047a 100644 --- a/describealign.py +++ b/describealign.py @@ -1195,8 +1195,8 @@ def command_line_interface(): parser = argparse.ArgumentParser( description="Replaces a video's sound with an audio description.", usage="describealign video_file.mp4 audio_file.mp3") - parser.add_argument("video", help='A video file or directory containing video files.', default=None) - parser.add_argument("audio", help='An audio file or directory containing audio files.', default=None) + parser.add_argument("video", help='A video file or directory containing video files.', nargs='?') + parser.add_argument("audio", help='An audio file or directory containing audio files.', nargs='?') parser.add_argument('--smoothness', type=float, default=50, help='Lower values make the alignment more accurate when there are skips ' + \ '(e.g. describer pauses), but also make it more likely to misalign. ' + \ From 807660c867a1353dc08010ed1f21456bc47ba759 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 22:46:12 +0000 Subject: [PATCH 17/37] Remove second static_ffmpeg import --- describealign.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/describealign.py b/describealign.py index ed3047a..0b81384 100644 --- a/describealign.py +++ b/describealign.py @@ -83,14 +83,12 @@ import os import glob import itertools -import datetime from pathlib import Path import sys import numpy as np import ffmpeg import platformdirs import static_ffmpeg -import static_ffmpeg.run import python_speech_features as psf import scipy.signal import scipy.optimize From d09fc22ead65119595a10491adc6bf6c26bae4d6 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 23:11:39 +0000 Subject: [PATCH 18/37] Fix install location for macos package --- .github/workflows/build-binary.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 846951c..61f7785 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -57,6 +57,7 @@ jobs: id: build-artifacts-mac run: | pkgbuild \ + --install-location /Applications \ --scripts Package/scripts \ --component dist/describealign.app \ /tmp/describealign-component.pkg From 11ee9f9023a1f3fd5235acea3a22578434ef4094 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 2 Mar 2024 23:50:22 +0000 Subject: [PATCH 19/37] Fix ffmpeg exec bits --- describealign.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/describealign.py b/describealign.py index 0b81384..80632fb 100644 --- a/describealign.py +++ b/describealign.py @@ -95,6 +95,7 @@ import scipy.interpolate import scipy.ndimage as nd import scipy.sparse +import stat import pytsmod import configparser import traceback @@ -1235,7 +1236,8 @@ def command_line_interface(): args = parser.parse_args() if args.install_ffmpeg: - static_ffmpeg.run.get_or_fetch_platform_executables_else_raise() + # Make sure the file is world executable + os.chmod(get_ffmpeg(), 0o755) elif args.video or args.audio: combine(args.video, args.audio, args.smoothness, args.stretch_audio, args.keep_non_ad, args.boost, args.ad_detect_sensitivity, args.boost_sensitivity, args.yes, From 8463e001bd670fc9b470dbb064d39e6d5a48c220 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 00:03:37 +0000 Subject: [PATCH 20/37] Fix ffprobe permissions too --- describealign.py | 1 + 1 file changed, 1 insertion(+) diff --git a/describealign.py b/describealign.py index 80632fb..335c8dd 100644 --- a/describealign.py +++ b/describealign.py @@ -1238,6 +1238,7 @@ def command_line_interface(): if args.install_ffmpeg: # Make sure the file is world executable os.chmod(get_ffmpeg(), 0o755) + os.chmod(get_ffprobe(), 0o755) elif args.video or args.audio: combine(args.video, args.audio, args.smoothness, args.stretch_audio, args.keep_non_ad, args.boost, args.ad_detect_sensitivity, args.boost_sensitivity, args.yes, From 1e230218e8d2c30fa3d57cef1f9455d682f8bbf4 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 01:40:20 +0000 Subject: [PATCH 21/37] Fix type errors concatting with non-strings --- describealign.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/describealign.py b/describealign.py index 335c8dd..173baf4 100644 --- a/describealign.py +++ b/describealign.py @@ -124,7 +124,7 @@ def throw_runtime_error(text, func=None): def ensure_folders_exist(dirs, display_func=None): for dir in dirs: if not os.path.isdir(dir): - display("Directory not found, creating it: " + dir, display_func) + display(f"Directory not found, creating it: {dir}", display_func) os.makedirs(dir) def get_sorted_filenames(path, extensions, alt_extensions=set([])): @@ -812,8 +812,8 @@ def write_replaced_media_to_disk(output_filename, media_arr, video_file=None, au write_command = ffmpeg.output(media_input, original_video, output_filename, acodec=audio_codec, vcodec='copy', scodec='copy', max_interleave_delta='0', loglevel='fatal', - **{'bsf:v': 'setts=ts=\'' + setts_cmd + '\'', - 'bsf:s': 'setts=ts=\'' + setts_cmd + '\''}).overwrite_output() + **{'bsf:v': f'setts=ts=\'{setts_cmd}\'', + 'bsf:s': f'setts=ts=\'{setts_cmd}\''}).overwrite_output() write_command.run(cmd=get_ffmpeg()) else: # work around for bug that sometimes breaks setts when output and input formats differ @@ -826,8 +826,8 @@ def write_replaced_media_to_disk(output_filename, media_arr, video_file=None, au pipe_input = ffmpeg.input('pipe:', format=format, thread_queue_size='512') write_command2 = ffmpeg.output(media_input, pipe_input, output_filename, c='copy', max_interleave_delta='0', loglevel='fatal', vsync='passthrough', - **{'bsf:v': 'setts=ts=\'' + setts_cmd + '\'', - 'bsf:s': 'setts=ts=\'' + setts_cmd + '\''}).overwrite_output() + **{'bsf:v': f'setts=ts=\'{setts_cmd}\'', + 'bsf:s': f'setts=ts=\'{setts_cmd}\''}).overwrite_output() ffmpeg_caller2 = write_command2.run_async(pipe_stdin=True, cmd=get_ffmpeg()) while True: in_bytes = ffmpeg_caller.stdout.read(100000) @@ -901,7 +901,7 @@ def combine(video, audio, smoothness=50, stretch_audio=False, keep_non_ad=False, ext = ('' if extension[0] == '.' else '.') + extension output_filename = prepend + os.path.splitext(os.path.split(video_file)[1])[0] + ext output_filename = os.path.join(output_dir, output_filename) - display(" " + output_filename, display_func) + display(f" {output_filename}", display_func) if os.path.exists(output_filename) and os.path.getsize(output_filename) > 0: display(" output file already exists, skipping...", display_func) @@ -1105,7 +1105,7 @@ def combine_gui(video_files, audio_files, config_path): if not print_queue.empty(): if IS_RUNNING_WINDOWS: cursor_position = output_textbox.WxTextCtrl.GetInsertionPoint() - output_textbox.update('\n' + print_queue.get(), append=True) + output_textbox.update(f'\n {print_queue.get()}', append=True) if IS_RUNNING_WINDOWS: output_textbox.WxTextCtrl.SetInsertionPoint(cursor_position) event, values = combine_window.read(timeout=100) @@ -1135,13 +1135,13 @@ def main_gui(): all_video_file_types = [('All Video File Types', '*.' + f'{filetype_sep}*.'.join(VIDEO_EXTENSIONS)),] all_video_and_audio_file_types = [('All Video and Audio File Types', '*.' + f'{filetype_sep}*.'.join(VIDEO_EXTENSIONS | AUDIO_EXTENSIONS)),] - audio_file_types = [(ext, "*." + ext) for ext in AUDIO_EXTENSIONS] - video_and_audio_file_types = [(ext, "*." + ext) for ext in VIDEO_EXTENSIONS] + audio_file_types + audio_file_types = [(ext, f"*.{ext}") for ext in AUDIO_EXTENSIONS] + video_and_audio_file_types = [(ext, f"*.{ext}") for ext in VIDEO_EXTENSIONS] + audio_file_types audio_file_types = all_audio_file_types + audio_file_types video_and_audio_file_types = all_video_file_types + all_video_and_audio_file_types + video_and_audio_file_types # work around bug in PySimpleGUIWx's convert_tkinter_filetypes_to_wx function if IS_RUNNING_WINDOWS: - file_fix = lambda file_types: file_types[:1] + [('|' + type[0], type[1]) for type in file_types[1:]] + file_fix = lambda file_types: file_types[:1] + [(f'|{type[0]}', type[1]) for type in file_types[1:]] audio_file_types = file_fix(audio_file_types) video_and_audio_file_types = file_fix(video_and_audio_file_types) From e43e469d5e1ef7e1547951aaad161c3a904ece3b Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 02:03:53 +0000 Subject: [PATCH 22/37] Bump lib versions --- requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9d4cbac..f220f4a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,11 @@ ffmpeg_python~=0.2.0 static-ffmpeg~=2.5 -matplotlib~=3.5.0 -numpy~=1.21.4 +matplotlib~=3.5 +numpy~=1.21 python_speech_features~=0.6 -scipy~=1.10.1 -platformdirs~=4.2.0 +scipy~=1.10 +platformdirs~=4.2 pytsmod~=0.3.7 PySimpleGUIWx~=0.17.2; platform_system == 'Windows' PySimpleGUIQt~=0.35.0; platform_system != 'Windows' -PySide2~=5.15.2.1; platform_system != "Windows" +PySide2~=5.15; platform_system != "Windows" From 0971d12adeb2348cce0e8cadb5021fe904638682 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 02:56:47 +0000 Subject: [PATCH 23/37] Redirect stdout to fix errors on windows --- describealign.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/describealign.py b/describealign.py index 173baf4..5aacd84 100644 --- a/describealign.py +++ b/describealign.py @@ -80,6 +80,8 @@ if PLOT_ALIGNMENT_TO_FILE: import matplotlib.pyplot as plt import argparse +from contextlib import redirect_stderr, redirect_stdout +import io import os import glob import itertools @@ -95,7 +97,6 @@ import scipy.interpolate import scipy.ndimage as nd import scipy.sparse -import stat import pytsmod import configparser import traceback @@ -1076,10 +1077,21 @@ def settings_gui(config_path: Path): break settings_window.close() +class QueueWriter(io.TextIOBase): + def __init__(self, queue) -> None: + super().__init__() + self._queue = queue + + def write(self, s: str) -> int: + self._queue.put(s) + return len(s) + def combine_print_exceptions(print_queue, *args, **kwargs): + writer = QueueWriter(print_queue) try: - combine(*args, **kwargs) - except: + with redirect_stdout(writer), redirect_stderr(writer): + combine(*args, **kwargs) + except Exception: print_queue.put(traceback.format_exc()) # raise From fdc4d843104c0b3dbdaccc8fe8dd206d7e5825df Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 03:24:01 +0000 Subject: [PATCH 24/37] Remove duplicate logging, fix newline handling in status console --- describealign.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/describealign.py b/describealign.py index 5aacd84..6514d0e 100644 --- a/describealign.py +++ b/describealign.py @@ -1088,12 +1088,11 @@ def write(self, s: str) -> int: def combine_print_exceptions(print_queue, *args, **kwargs): writer = QueueWriter(print_queue) - try: - with redirect_stdout(writer), redirect_stderr(writer): - combine(*args, **kwargs) - except Exception: - print_queue.put(traceback.format_exc()) - # raise + with redirect_stdout(writer), redirect_stderr(writer): + try: + combine(*args, **kwargs) + except Exception: + traceback.print_exc() def combine_gui(video_files, audio_files, config_path): output_textbox = sg.Multiline(size=(80,30), key='-OUTPUT-') @@ -1105,7 +1104,7 @@ def combine_gui(video_files, audio_files, config_path): print_queue = multiprocessing.Queue() settings = read_config_file(config_path) - settings.update({'display_func':print_queue.put, 'yes':True}) + settings.update({'yes':True}) proc = multiprocessing.Process(target=combine_print_exceptions, args=(print_queue, video_files, audio_files), kwargs=settings, daemon=True) @@ -1117,7 +1116,7 @@ def combine_gui(video_files, audio_files, config_path): if not print_queue.empty(): if IS_RUNNING_WINDOWS: cursor_position = output_textbox.WxTextCtrl.GetInsertionPoint() - output_textbox.update(f'\n {print_queue.get()}', append=True) + output_textbox.update(print_queue.get(), append=True) if IS_RUNNING_WINDOWS: output_textbox.WxTextCtrl.SetInsertionPoint(cursor_position) event, values = combine_window.read(timeout=100) From 52f8d16c58af4b3f571875538e7337f7ed1c036e Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 03:46:31 +0000 Subject: [PATCH 25/37] Fix windows path name --- .github/workflows/build-binary.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 61f7785..00a9446 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -78,7 +78,8 @@ jobs: if: ${{runner.os == 'Windows'}} working-directory: dist run: | - mv describealign describealign.windows + mkdir windows + mv describealign windows/describealign - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -87,6 +88,5 @@ jobs: path: | dist/*.pkg dist/*.tar - dist/*.windows - compression-level: 0 + dist/windows/describealign/* if-no-files-found: error From 9fae05134d2d50c4cb71dc4084d6c4a98371d328 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 04:15:56 +0000 Subject: [PATCH 26/37] Zip windows dist dir --- .github/workflows/build-binary.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 00a9446..e07704d 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -72,14 +72,13 @@ jobs: id: build-artifacts-linux working-directory: dist run: | - tar cvf describealign.tar describealign + tar cvzf describealign.tar.gz describealign - name: Build Artifacts if: ${{runner.os == 'Windows'}} working-directory: dist run: | - mkdir windows - mv describealign windows/describealign + zip -r describealign.zip describealign - name: Upload Artifacts uses: actions/upload-artifact@v4 @@ -87,6 +86,6 @@ jobs: name: ${{ runner.os }} Build path: | dist/*.pkg - dist/*.tar - dist/windows/describealign/* + dist/*.tar.gz + dist/*.zip if-no-files-found: error From 1ecbce2e3faf2fadd45fe4e4595e4d7736453509 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 04:46:20 +0000 Subject: [PATCH 27/37] Fix zip on windows --- .github/workflows/build-binary.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index e07704d..1f57ff1 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -74,12 +74,14 @@ jobs: run: | tar cvzf describealign.tar.gz describealign - - name: Build Artifacts - if: ${{runner.os == 'Windows'}} - working-directory: dist - run: | - zip -r describealign.zip describealign - + - name: Archive Release + uses: thedoctor0/zip-release@0.7.5 + with: + type: 'zip' + directory: dist + path: dist/describealign + filename: 'describealign.zip' + - name: Upload Artifacts uses: actions/upload-artifact@v4 with: From 47c4d4b501849108f5427de065943564192491b4 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 04:49:59 +0000 Subject: [PATCH 28/37] Add run condition for zip step --- .github/workflows/build-binary.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index 1f57ff1..c9bbb4b 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -75,11 +75,12 @@ jobs: tar cvzf describealign.tar.gz describealign - name: Archive Release + if: ${{ runner.os == 'Windows' }} uses: thedoctor0/zip-release@0.7.5 with: type: 'zip' directory: dist - path: dist/describealign + path: describealign filename: 'describealign.zip' - name: Upload Artifacts From 033e2fd088e3d5849cca5baff1b647045e32f9cb Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sun, 3 Mar 2024 20:25:56 +0000 Subject: [PATCH 29/37] Remove nuitka config --- describealign.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/describealign.py b/describealign.py index 6514d0e..a7ed61d 100644 --- a/describealign.py +++ b/describealign.py @@ -24,34 +24,6 @@ along with this program. If not, see . ''' -# Nuitka build options: -# nuitka-project-if: {OS} != "Windows": -# nuitka-project: --enable-plugins=pyside2 -# -# Compilation mode, standalone everywhere, except on macOS there app bundle -# nuitka-project-if: {OS} == "Darwin": -# nuitka-project: --standalone -# nuitka-project: --macos-create-app-bundle -# Mac needs onefile too apparently, because pyside2 plugin requires it. -# All other platforms need it to, so set it universally. -# nuitka-project: --onefile -# -# Debugging options, controlled via environment variable at compile time. -# nuitka-project-if: os.getenv("DEBUG_COMPILATION", "no") == "yes": -# nuitka-project: --enable-console -# nuitka-project-else: -# nuitka-project: --disable-console - -# Set app icon -# nuitka-project-if: {OS} == "Windows": -# nuitka-project: --windows-icon-from-ico=describealign.png -# nuitka-project-else: -# nuitka-project-if: {OS} == "Darwin": -# nuitka-project: --macos-app-icon=describealign.png -# nuitka-project-else: -# nuitka-project: --linux-icon=describealign.png -# End Nuitka build options - VIDEO_EXTENSIONS = set(['mp4', 'mkv', 'avi', 'mov', 'webm', 'm4v', 'flv', 'vob']) AUDIO_EXTENSIONS = set(['mp3', 'm4a', 'opus', 'wav', 'aac', 'flac', 'ac3', 'mka']) PLOT_ALIGNMENT_TO_FILE = True From a731e5bfae0839aef7ddf697335723846f98eac7 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 11:59:13 +0000 Subject: [PATCH 30/37] Set version constraints on build dependencies --- .github/workflows/build-binary.yaml | 2 +- build-requirements.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 build-requirements.txt diff --git a/.github/workflows/build-binary.yaml b/.github/workflows/build-binary.yaml index c9bbb4b..3f10a14 100644 --- a/.github/workflows/build-binary.yaml +++ b/.github/workflows/build-binary.yaml @@ -40,7 +40,7 @@ jobs: run: | pip install -U pip wheel pip install -Ur requirements.txt - pip install -U pillow pyinstaller + pip install -Ur build-requirements.txt - name: Set build vars id: build-vars diff --git a/build-requirements.txt b/build-requirements.txt new file mode 100644 index 0000000..6a465c0 --- /dev/null +++ b/build-requirements.txt @@ -0,0 +1,2 @@ +pyinstaller~=6.4 +pillow~=10.2 From ecfbce6994de5c4a8409794fae913ed42d7715fb Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 12:17:41 +0000 Subject: [PATCH 31/37] Migrate config if existing config found --- describealign.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/describealign.py b/describealign.py index a7ed61d..e3e2654 100644 --- a/describealign.py +++ b/describealign.py @@ -1109,8 +1109,27 @@ def combine_gui(video_files, audio_files, config_path): break combine_window.close() +def migrate_config(old_path: Path, new_path: Path) -> None: + """ + Migrate configuration from old location. + + Only runs if the old_path exists but new_path does not + """ + if new_path.exists() or not old_path.exists(): + return + + old_data = old_path.read_text(encoding='utf-8') + new_path.write_text(old_data, encoding='utf-8') + print(f"Configuration migrated to {new_path}") + def main_gui(): config_path = platformdirs.user_config_path(appname='describealign', ensure_exists=True) / 'config.ini' + old_config = Path(__file__).resolve().parent / 'config.ini' + try: + migrate_config(old_config, config_path) + except OSError: + print(f"Error migrating old config:", *traceback.format_exception_only()) + sg.theme('Light Blue 2') filetype_sep = ';' if IS_RUNNING_WINDOWS else ' ' From 34f2fc9dd9017739474b63b03f5c58d3d05a1183 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 22:55:59 +0000 Subject: [PATCH 32/37] Revert back to original default output dirs --- describealign.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/describealign.py b/describealign.py index e3e2654..6c4a8b2 100644 --- a/describealign.py +++ b/describealign.py @@ -75,14 +75,15 @@ import multiprocessing import platform -default_output_dir = platformdirs.user_videos_path() / 'videos_with_ad' -default_alignment_dir = platformdirs.user_data_path('describealign') / 'alignment_plots' - IS_RUNNING_WINDOWS = platform.system() == 'Windows' if IS_RUNNING_WINDOWS: import PySimpleGUIWx as sg + default_output_dir = 'videos_with_ad' + default_alignment_dir = 'alignment_plots' else: import PySimpleGUIQt as sg + default_output_dir = os.path.expanduser('~') + '/videos_with_ad' + default_alignment_dir = os.path.expanduser('~') + '/alignment_plots' def display(text, func=None): if func: From 7d6e972fa7a126c5b4150c1650980f6099da9983 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 22:58:24 +0000 Subject: [PATCH 33/37] Add back the print when launching GUI --- describealign.py | 1 + 1 file changed, 1 insertion(+) diff --git a/describealign.py b/describealign.py index 6c4a8b2..d77ff32 100644 --- a/describealign.py +++ b/describealign.py @@ -1191,6 +1191,7 @@ def main_gui(): def command_line_interface(): if len(sys.argv) < 2: # No args, run gui + print('No input arguments detected, starting GUI...') main_gui() sys.exit(0) From a80093e2371f19b526e3e71e414a12a3370e2140 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 23:05:01 +0000 Subject: [PATCH 34/37] Delete old config after migration --- describealign.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/describealign.py b/describealign.py index d77ff32..caeb81d 100644 --- a/describealign.py +++ b/describealign.py @@ -1122,6 +1122,12 @@ def migrate_config(old_path: Path, new_path: Path) -> None: old_data = old_path.read_text(encoding='utf-8') new_path.write_text(old_data, encoding='utf-8') print(f"Configuration migrated to {new_path}") + try: + old_path.unlink() + except OSError: + print("Failed to remove old config:", *traceback.format_exception_only()) + else: + print("Successfully removed old config file.") def main_gui(): config_path = platformdirs.user_config_path(appname='describealign', ensure_exists=True) / 'config.ini' @@ -1130,6 +1136,7 @@ def main_gui(): migrate_config(old_config, config_path) except OSError: print(f"Error migrating old config:", *traceback.format_exception_only()) + print(f"Old config left in place at {old_config}") sg.theme('Light Blue 2') From a1c5b5998e0cbea9754b8ecc5620520f43f10871 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 23:08:44 +0000 Subject: [PATCH 35/37] Use the correct form of format_exception_only --- describealign.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/describealign.py b/describealign.py index caeb81d..2c047aa 100644 --- a/describealign.py +++ b/describealign.py @@ -1124,8 +1124,8 @@ def migrate_config(old_path: Path, new_path: Path) -> None: print(f"Configuration migrated to {new_path}") try: old_path.unlink() - except OSError: - print("Failed to remove old config:", *traceback.format_exception_only()) + except OSError as exc: + print("Failed to remove old config:", *traceback.format_exception_only(exc)) else: print("Successfully removed old config file.") @@ -1134,8 +1134,8 @@ def main_gui(): old_config = Path(__file__).resolve().parent / 'config.ini' try: migrate_config(old_config, config_path) - except OSError: - print(f"Error migrating old config:", *traceback.format_exception_only()) + except OSError as exc: + print(f"Error migrating old config:", *traceback.format_exception_only(exc)) print(f"Old config left in place at {old_config}") sg.theme('Light Blue 2') From 72a55a97d0dc37c5af836b16685d23aee752cd96 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Mon, 4 Mar 2024 23:35:18 +0000 Subject: [PATCH 36/37] Switch QueueWriter to inherit TextIOWrapper This ensures it implements all of the methods expected of sys.stdout, it shouldn't really make a difference but this is more type-safe --- describealign.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/describealign.py b/describealign.py index 2c047aa..01b945c 100644 --- a/describealign.py +++ b/describealign.py @@ -1050,9 +1050,9 @@ def settings_gui(config_path: Path): break settings_window.close() -class QueueWriter(io.TextIOBase): +class QueueWriter(io.TextIOWrapper): def __init__(self, queue) -> None: - super().__init__() + super().__init__(buffer=io.BytesIO()) self._queue = queue def write(self, s: str) -> int: From d0b86b6cd39d5e76397fcb4759213154802a5a43 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Tue, 5 Mar 2024 00:55:50 +0000 Subject: [PATCH 37/37] Set default explicitly --- describealign.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/describealign.py b/describealign.py index 01b945c..3329acc 100644 --- a/describealign.py +++ b/describealign.py @@ -1205,8 +1205,8 @@ def command_line_interface(): parser = argparse.ArgumentParser( description="Replaces a video's sound with an audio description.", usage="describealign video_file.mp4 audio_file.mp3") - parser.add_argument("video", help='A video file or directory containing video files.', nargs='?') - parser.add_argument("audio", help='An audio file or directory containing audio files.', nargs='?') + parser.add_argument("video", help='A video file or directory containing video files.', nargs='?', default=None) + parser.add_argument("audio", help='An audio file or directory containing audio files.', nargs='?', default=None) parser.add_argument('--smoothness', type=float, default=50, help='Lower values make the alignment more accurate when there are skips ' + \ '(e.g. describer pauses), but also make it more likely to misalign. ' + \