From bc51c581c250a42c7833f29b0d6d83d1183ace75 Mon Sep 17 00:00:00 2001 From: Chidi Williams Date: Tue, 24 Jan 2023 01:10:24 +0000 Subject: [PATCH] Fix Linux build (#341) --- .github/workflows/ci.yml | 19 ++++++++++++++++++- README.md | 36 ++++++++++++++++++++++++------------ buzz/gui.py | 7 +++++-- buzz/transcriber.py | 3 +++ main.py | 3 +++ tests/gui_test.py | 8 ++++++-- 6 files changed, 59 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d04916b6..b804abcd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: include: - os: macos-latest - os: windows-latest + - os: ubuntu-20.04 steps: - uses: actions/checkout@v3 with: @@ -63,7 +64,16 @@ jobs: run: poetry config experimental.new-installer false && poetry install - name: Test - run: poetry run make test + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils + /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX + sudo apt update + sudo apt install -y libpulse-mainloop-glib0 libegl1-mesa-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libportaudio2 + fi + + poetry run make test + shell: bash - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v3 @@ -78,6 +88,7 @@ jobs: include: - os: macos-latest - os: windows-latest + - os: ubuntu-20.04 steps: - uses: actions/checkout@v3 with: @@ -140,6 +151,10 @@ jobs: elif [ "$RUNNER_OS" == "Linux" ]; then + sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 x11-utils + /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX + sudo apt update + sudo apt install -y libpulse-mainloop-glib0 libegl1-mesa-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libportaudio2 gettext poetry run make bundle_linux fi @@ -161,6 +176,7 @@ jobs: dist/Buzz*-windows.tar.gz dist/Buzz*-windows.exe dist/Buzz*-mac.dmg + dist/Buzz*-unix.tar.gz release: runs-on: ${{ matrix.os }} @@ -189,6 +205,7 @@ jobs: with: files: | Buzz*-windows.tar.gz + Buzz*-unix.tar.gz Buzz*-windows.exe Buzz*-mac.dmg diff --git a/README.md b/README.md index 4bf4c71c..69523ffc 100644 --- a/README.md +++ b/README.md @@ -24,21 +24,31 @@ OpenAI's [Whisper](https://github.com/openai/whisper). ## Installation To install Buzz, download the [latest version](https://github.com/chidiwilliams/buzz/releases/latest) for your operating -system. Buzz is available on **Mac** and **Windows**. +system. Buzz is available on **Mac**, **Windows**, and **Linux**. -### Mac (macOS 11.7 and above) +### Mac (macOS 11.7 and later) -Install via [brew](https://brew.sh/): +- Install via [brew](https://brew.sh/): -```shell -brew install --cask buzz -``` + ```shell + brew install --cask buzz + ``` -Or, download and run the `Buzz-x.y.z.dmg` file. + Alternatively, download and run the `Buzz-x.y.z.dmg` file. -### Windows +### Windows (Windows 10 and later) -Download and run the `Buzz-x.y.z.exe` file. +- Download and run the `Buzz-x.y.z.exe` file. + +### Linux (Ubuntu 20.04 and later) + +- Install dependencies: + + ```shell + sudo apt-get install libportaudio2 + ``` + +- Download and extract the `Buzz-x.y.z-unix.tar.gz` file ## How to use @@ -97,10 +107,12 @@ and [Virtual Audio Cable](https://vac.muzychenko.net/en/)). To import a file: -- Click Import on the File menu (or **Command + O** on Mac, **Ctrl + O** on Windows). -- Choose an audio or video file. Supported formats: "mp3", "wav", "m4a", "ogg", "mp4", "webm", "ogm". -- Select a task, language, quality, and export format. +- Click Import Media File on the File menu (or the '+' icon on the toolbar, or **Command/Ctrl + O**). +- Choose an audio or video file. +- Select a task, language, and the model settings. - Click Run. +- When the transcription status shows 'Completed', double-click on the row (or select the row and click the '⤢' icon) to + open the transcription. | Field | Options | Default | Description | |--------------------|---------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------| diff --git a/buzz/gui.py b/buzz/gui.py index 24ceedf0..27fdd6c9 100644 --- a/buzz/gui.py +++ b/buzz/gui.py @@ -341,11 +341,14 @@ class TranscriptionViewerWidget(QWidget): transcription_task: FileTranscriptionTask def __init__( - self, transcription_task: FileTranscriptionTask, parent: Optional['QWidget'] = None, + self, transcription_task: FileTranscriptionTask, + open_transcription_output=True, + parent: Optional['QWidget'] = None, flags: Qt.WindowType = Qt.WindowType.Widget, ) -> None: super().__init__(parent, flags) self.transcription_task = transcription_task + self.open_transcription_output = open_transcription_output self.setMinimumWidth(500) self.setMinimumHeight(500) @@ -394,7 +397,7 @@ class TranscriptionViewerWidget(QWidget): return write_output(path=output_file_path, segments=self.transcription_task.segments, - should_open=True, output_format=output_format) + should_open=self.open_transcription_output, output_format=output_format) class AdvancedSettingsButton(QPushButton): diff --git a/buzz/transcriber.py b/buzz/transcriber.py index bd3362d0..44fdd2de 100644 --- a/buzz/transcriber.py +++ b/buzz/transcriber.py @@ -483,8 +483,11 @@ def write_output(path: str, segments: List[Segment], should_open: bool, output_f f'{to_timestamp(segment.start, ms_separator=",")} --> {to_timestamp(segment.end, ms_separator=",")}\n') file.write(f'{segment.text}\n\n') + logging.debug('Written transcription output') + if should_open: try: + logging.debug('Opening transcription output') os.startfile(path) except AttributeError: opener = "open" if platform.system() == "Darwin" else "xdg-open" diff --git a/main.py b/main.py index cca0b0b2..d7e0ec7a 100644 --- a/main.py +++ b/main.py @@ -29,6 +29,9 @@ if platform.system() == 'Windows': os.add_dll_directory(app_dir) if __name__ == "__main__": + if platform.system() == 'Linux': + multiprocessing.set_start_method('spawn') + # Fixes opening new window when app has been frozen on Windows: # https://stackoverflow.com/a/33979091 multiprocessing.freeze_support() diff --git a/tests/gui_test.py b/tests/gui_test.py index 853a4654..ea75ca18 100644 --- a/tests/gui_test.py +++ b/tests/gui_test.py @@ -1,4 +1,5 @@ import logging +import multiprocessing import os.path import pathlib import platform @@ -27,6 +28,9 @@ from buzz.transcriber import (FileTranscriptionOptions, FileTranscriptionTask, from tests.mock_sounddevice import MockInputStream, mock_query_devices from .mock_qt import MockNetworkAccessManager, MockNetworkReply +if platform.system() == 'Linux': + multiprocessing.set_start_method('spawn') + @pytest.fixture(scope='module', autouse=True) def audio_setup(): @@ -369,7 +373,7 @@ class TestTranscriptionViewerWidget: transcription_options=TranscriptionOptions(), segments=[Segment(40, 299, 'Bien'), Segment(299, 329, 'venue dans')], - model_path='')) + model_path=''), open_transcription_output=False) qtbot.add_widget(widget) assert widget.windowTitle() == 'whisper-french.mp3' @@ -389,7 +393,7 @@ class TestTranscriptionViewerWidget: transcription_options=TranscriptionOptions(), segments=[Segment(40, 299, 'Bien'), Segment(299, 329, 'venue dans')], - model_path='')) + model_path=''), open_transcription_output=False) qtbot.add_widget(widget) export_button = widget.findChild(QPushButton)