diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a593966a..507264f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,8 +3,23 @@ name: CI 'on': push jobs: - ci: - runs-on: ubuntu-latest + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: macos-latest + CMD_BUILD: | + brew install create-dmg + poetry run make bundle_mac version=$GITHUB_REF_NAME + PATH: | + dist/buzz*.dmg + dist/buzz*.tar.gz + - os: windows-latest + CMD_BUILD: | + poetry run make bundle_windows version=$env:GITHUB_REF_NAME + PATH: | + dist/buzz*.tar.gz steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 @@ -22,12 +37,26 @@ jobs: uses: actions/cache@v3 with: path: .venv - key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}-${{ hashFiles('**/package-lock.json') }}-2 + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}-2 - - run: pip install poetry - run: poetry install - - run: poetry run make buzz + - run: ${{ matrix.CMD_BUILD }} - uses: actions/upload-artifact@v3 with: - name: pyinstaller - path: dist/* + name: Buzz + path: | + ${{ matrix.PATH }} + release: + runs-on: ubuntu-latest + needs: build + if: startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v3 + with: + name: Buzz + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: | + buzz*.tar.gz + buzz*.dmg diff --git a/Makefile b/Makefile index b27c1d44..f663a2aa 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,13 @@ buzz: clean: rm -r dist/* || true +bundle_windows: + make buzz + tar -czf dist/buzz-${version}-windows.tar.gz dist/Buzz + bundle_mac: make buzz - tar -czf dist/buzz-${version}-unix.zip dist/Buzz + tar -czf dist/buzz-${version}-unix.tar.gz dist/Buzz mkdir -p dist/dmg && cp -r dist/Buzz.app dist/dmg create-dmg \ --volname "Buzz" \ diff --git a/README.md b/README.md index 1439c509..bce14cd1 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ![MIT License](https://img.shields.io/badge/license-MIT-green) [![CI](https://github.com/chidiwilliams/buzz/actions/workflows/ci.yml/badge.svg)](https://github.com/chidiwilliams/buzz/actions/workflows/ci.yml) +![GitHub release (latest by date)](https://img.shields.io/github/v/release/chidiwilliams/buzz) Buzz transcribes audio from your computer's microphones to text in real-time using OpenAI's [Whisper](https://github.com/openai/whisper). @@ -30,6 +31,25 @@ choco install ffmpeg scoop install ffmpeg ``` +## Installation + +To install Buzz, download the [latest version](https://github.com/chidiwilliams/buzz/releases/latest) for your Operating System. + +## Mac + +- Download and open the `*-mac.dmg` file. +- After the installation window opens, drag the Buzz icon into the folder to add Buzz to your Applications directory. + +## Windows + +- Download and unzip the `*-windows.zip` file. +- Open the Buzz.exe file + +## Linux + +- Download and unzip the `*-unix.zip` file. +- Open the Buzz binary file. + ## How to use To record from a system microphone, select a model, language, task, microphone, and delay, then click Record. @@ -52,40 +72,45 @@ To record audio playing out from your computer, you'll need to install an audio 1. Install [BlackHole via Homebrew](https://github.com/ExistentialAudio/BlackHole#option-2-install-via-homebrew) -```shell -brew install blackhole-2ch -``` + ```shell + brew install blackhole-2ch + ``` 2. Open Audio MIDI Setup from Spotlight or from `/Applications/Utilities/Audio Midi Setup.app`. -![](https://existential.audio/howto/img/spotlight.png) + ![Open Audio MIDI Setup from Spotlight](https://existential.audio/howto/img/spotlight.png) 3. Click the '+' icon at the lower left corner and select 'Create Multi-Output Device'. -![](https://existential.audio/howto/img/createmulti-output.png) + ![Create multi-output device](https://existential.audio/howto/img/createmulti-output.png) 4. Add your default speaker and BlackHole to the multi-output device. -![Screenshot of multi-output device](https://existential.audio/howto/img/multi-output.png) + ![Screenshot of multi-output device](https://existential.audio/howto/img/multi-output.png) 5. Select this multi-output device as your speaker (application or system-wide) to play audio into BlackHole. 6. Open Buzz, select BlackHole as your microphone, and record as before to see transcriptions from the audio playing through BlackHole. -## Build +## Build/run locally -To build Buzz, install the dependencies: +To build/run Buzz locally from source, first install the dependencies: + +1. Install [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer). +2. Install the project dependencies. + + ```shell + poetry install + ``` + +Then, to run: ```shell -# using pip -pip install . - -# using poetry -poetry install +poetry run python main.py ``` -Then run: +To build: ```shell -make buzz +poetry run pyinstaller --noconfirm Buzz.spec ``` diff --git a/gui.py b/gui.py index 4df9cd33..716567c5 100644 --- a/gui.py +++ b/gui.py @@ -1,5 +1,6 @@ import enum -from typing import List, Optional, Tuple +import platform +from typing import Dict, List, Optional, Tuple import sounddevice import whisper @@ -11,10 +12,19 @@ from whisper import tokenizer from transcriber import Transcriber +def get_platform_styles(all_platform_styles: Dict[str, str]): + return all_platform_styles.get(platform.system(), '') + + class Label(QLabel): + os_styles = { + 'Darwin': 'QLabel { color: #ddd; }' + } + def __init__(self, name: str, *args) -> None: super().__init__(name, *args) - self.setStyleSheet('QLabel { color: #ddd; text-align: right; }') + self.setStyleSheet('QLabel { text-align: right; } %s' % + get_platform_styles(self.os_styles)) self.setAlignment(Qt.AlignmentFlag( Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignRight)) @@ -115,6 +125,15 @@ class DelaysComboBox(QComboBox): class TextDisplayBox(QTextEdit): """TextDisplayBox is a read-only textbox""" + os_styles = { + 'Darwin': '''QTextEdit { + border-radius: 6; + background-color: #252525; + color: #dfdfdf; + }''', + 'Windows': 'QTextEdit { background-color: #ffffff; }' + } + def __init__(self, *args) -> None: super().__init__(*args) self.setReadOnly(True) @@ -125,10 +144,7 @@ class TextDisplayBox(QTextEdit): padding-top: 5; padding-bottom: 5; padding-right: 5; - border-radius: 6; - background-color: #252525; - color: #dfdfdf; - }''') + } %s''' % get_platform_styles(self.os_styles)) class RecordButton(QPushButton):