mirror of
https://github.com/chidiwilliams/buzz.git
synced 2024-06-07 18:52:12 +02:00
Fix terminal value in .desktop file (#487)
This commit is contained in:
parent
1b13a366cb
commit
530bf28407
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
|
@ -94,12 +94,14 @@ jobs:
|
|||
submodules: recursive
|
||||
- uses: snapcore/action-build@v1
|
||||
id: snapcraft
|
||||
# - uses: snapcore/action-publish@v1
|
||||
# env:
|
||||
# SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
|
||||
# with:
|
||||
# snap: ${{ steps.snapcraft.outputs.snap }}
|
||||
# release: edge
|
||||
- run: |
|
||||
sudo snap install --devmode *.snap
|
||||
# - uses: snapcore/action-publish@v1
|
||||
# env:
|
||||
# SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_TOKEN }}
|
||||
# with:
|
||||
# snap: ${{ steps.snapcraft.outputs.snap }}
|
||||
# release: edge
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: snap
|
||||
|
|
|
@ -14,4 +14,4 @@ Exec=/opt/buzz/Buzz
|
|||
|
||||
Icon=buzz
|
||||
|
||||
Terminal=False
|
||||
Terminal=false
|
||||
|
|
0
buzz/__init__.py
Normal file
0
buzz/__init__.py
Normal file
130
buzz/file_transcriber_queue_worker.py
Normal file
130
buzz/file_transcriber_queue_worker.py
Normal file
|
@ -0,0 +1,130 @@
|
|||
import datetime
|
||||
import logging
|
||||
import multiprocessing
|
||||
import queue
|
||||
from typing import Optional, Tuple, List
|
||||
|
||||
from PyQt6.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
|
||||
|
||||
from buzz.model_loader import ModelType
|
||||
from buzz.transcriber import FileTranscriptionTask, FileTranscriber, WhisperCppFileTranscriber, \
|
||||
OpenAIWhisperAPIFileTranscriber, WhisperFileTranscriber, Segment
|
||||
|
||||
|
||||
class FileTranscriberQueueWorker(QObject):
|
||||
tasks_queue: multiprocessing.Queue
|
||||
current_task: Optional[FileTranscriptionTask] = None
|
||||
current_transcriber: Optional[FileTranscriber] = None
|
||||
current_transcriber_thread: Optional[QThread] = None
|
||||
task_updated = pyqtSignal(FileTranscriptionTask)
|
||||
completed = pyqtSignal()
|
||||
|
||||
def __init__(self, parent: Optional[QObject] = None):
|
||||
super().__init__(parent)
|
||||
self.tasks_queue = queue.Queue()
|
||||
self.canceled_tasks = set()
|
||||
|
||||
@pyqtSlot()
|
||||
def run(self):
|
||||
logging.debug('Waiting for next transcription task')
|
||||
|
||||
# Get next non-canceled task from queue
|
||||
while True:
|
||||
self.current_task: Optional[FileTranscriptionTask] = self.tasks_queue.get()
|
||||
|
||||
# Stop listening when a "None" task is received
|
||||
if self.current_task is None:
|
||||
self.completed.emit()
|
||||
return
|
||||
|
||||
if self.current_task.id in self.canceled_tasks:
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
logging.debug('Starting next transcription task')
|
||||
|
||||
model_type = self.current_task.transcription_options.model.model_type
|
||||
if model_type == ModelType.WHISPER_CPP:
|
||||
self.current_transcriber = WhisperCppFileTranscriber(
|
||||
task=self.current_task)
|
||||
elif model_type == ModelType.OPEN_AI_WHISPER_API:
|
||||
self.current_transcriber = OpenAIWhisperAPIFileTranscriber(task=self.current_task)
|
||||
elif model_type == ModelType.HUGGING_FACE or \
|
||||
model_type == ModelType.WHISPER or \
|
||||
model_type == ModelType.FASTER_WHISPER:
|
||||
self.current_transcriber = WhisperFileTranscriber(task=self.current_task)
|
||||
else:
|
||||
raise Exception(f'Unknown model type: {model_type}')
|
||||
|
||||
self.current_transcriber_thread = QThread(self)
|
||||
|
||||
self.current_transcriber.moveToThread(self.current_transcriber_thread)
|
||||
|
||||
self.current_transcriber_thread.started.connect(
|
||||
self.current_transcriber.run)
|
||||
self.current_transcriber.completed.connect(
|
||||
self.current_transcriber_thread.quit)
|
||||
self.current_transcriber.error.connect(
|
||||
self.current_transcriber_thread.quit)
|
||||
|
||||
self.current_transcriber.completed.connect(
|
||||
self.current_transcriber.deleteLater)
|
||||
self.current_transcriber.error.connect(
|
||||
self.current_transcriber.deleteLater)
|
||||
self.current_transcriber_thread.finished.connect(
|
||||
self.current_transcriber_thread.deleteLater)
|
||||
|
||||
self.current_transcriber.progress.connect(self.on_task_progress)
|
||||
self.current_transcriber.error.connect(self.on_task_error)
|
||||
|
||||
self.current_transcriber.completed.connect(self.on_task_completed)
|
||||
|
||||
# Wait for next item on the queue
|
||||
self.current_transcriber.error.connect(self.run)
|
||||
self.current_transcriber.completed.connect(self.run)
|
||||
|
||||
self.current_task.started_at = datetime.datetime.now()
|
||||
self.current_transcriber_thread.start()
|
||||
|
||||
def add_task(self, task: FileTranscriptionTask):
|
||||
if task.queued_at is None:
|
||||
task.queued_at = datetime.datetime.now()
|
||||
|
||||
self.tasks_queue.put(task)
|
||||
task.status = FileTranscriptionTask.Status.QUEUED
|
||||
self.task_updated.emit(task)
|
||||
|
||||
def cancel_task(self, task_id: int):
|
||||
self.canceled_tasks.add(task_id)
|
||||
|
||||
if self.current_task.id == task_id:
|
||||
if self.current_transcriber is not None:
|
||||
self.current_transcriber.stop()
|
||||
|
||||
@pyqtSlot(Exception)
|
||||
def on_task_error(self, error: Exception):
|
||||
if self.current_task is not None and self.current_task.id not in self.canceled_tasks:
|
||||
self.current_task.status = FileTranscriptionTask.Status.FAILED
|
||||
self.current_task.error = str(error)
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
@pyqtSlot(tuple)
|
||||
def on_task_progress(self, progress: Tuple[int, int]):
|
||||
if self.current_task is not None:
|
||||
self.current_task.status = FileTranscriptionTask.Status.IN_PROGRESS
|
||||
self.current_task.fraction_completed = progress[0] / progress[1]
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
@pyqtSlot(list)
|
||||
def on_task_completed(self, segments: List[Segment]):
|
||||
if self.current_task is not None:
|
||||
self.current_task.status = FileTranscriptionTask.Status.COMPLETED
|
||||
self.current_task.segments = segments
|
||||
self.current_task.completed_at = datetime.datetime.now()
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
def stop(self):
|
||||
self.tasks_queue.put(None)
|
||||
if self.current_transcriber is not None:
|
||||
self.current_transcriber.stop()
|
|
@ -35,8 +35,9 @@ from .store.keyring_store import KeyringStore
|
|||
from .transcriber import (SUPPORTED_OUTPUT_FORMATS, FileTranscriptionOptions, OutputFormat,
|
||||
Task,
|
||||
TranscriptionOptions,
|
||||
FileTranscriberQueueWorker, FileTranscriptionTask, RecordingTranscriber, LOADED_WHISPER_DLL,
|
||||
FileTranscriptionTask, RecordingTranscriber, LOADED_WHISPER_DLL,
|
||||
DEFAULT_WHISPER_TEMPERATURE, LANGUAGES)
|
||||
from .file_transcriber_queue_worker import FileTranscriberQueueWorker
|
||||
from .widgets.line_edit import LineEdit
|
||||
from .widgets.model_download_progress_dialog import ModelDownloadProgressDialog
|
||||
from .widgets.model_type_combo_box import ModelTypeComboBox
|
||||
|
|
|
@ -5,8 +5,6 @@ import json
|
|||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
import queue
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
|
@ -25,7 +23,7 @@ import sounddevice
|
|||
import stable_whisper
|
||||
import tqdm
|
||||
import whisper
|
||||
from PyQt6.QtCore import QObject, QProcess, pyqtSignal, pyqtSlot, QThread
|
||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtSlot
|
||||
from sounddevice import PortAudioError
|
||||
from whisper import tokenizer
|
||||
|
||||
|
@ -237,7 +235,7 @@ class FileTranscriber(QObject):
|
|||
transcription_task: FileTranscriptionTask
|
||||
progress = pyqtSignal(tuple) # (current, total)
|
||||
completed = pyqtSignal(list) # List[Segment]
|
||||
error = pyqtSignal(str)
|
||||
error = pyqtSignal(Exception)
|
||||
|
||||
def __init__(self, task: FileTranscriptionTask,
|
||||
parent: Optional['QObject'] = None):
|
||||
|
@ -249,8 +247,7 @@ class FileTranscriber(QObject):
|
|||
try:
|
||||
segments = self.transcribe()
|
||||
except Exception as exc:
|
||||
self.error.emit(str(exc))
|
||||
logging.exception('')
|
||||
self.error.emit(exc)
|
||||
return
|
||||
|
||||
self.completed.emit(segments)
|
||||
|
@ -272,10 +269,16 @@ class FileTranscriber(QObject):
|
|||
...
|
||||
|
||||
|
||||
class Stopped(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class WhisperCppFileTranscriber(FileTranscriber):
|
||||
duration_audio_ms = sys.maxsize # max int
|
||||
segments: List[Segment]
|
||||
running = False
|
||||
state: 'WhisperCppFileTranscriber.State'
|
||||
|
||||
class State:
|
||||
running = True
|
||||
|
||||
def __init__(self, task: FileTranscriptionTask,
|
||||
parent: Optional['QObject'] = None) -> None:
|
||||
|
@ -286,14 +289,10 @@ class WhisperCppFileTranscriber(FileTranscriber):
|
|||
self.model_path = task.model_path
|
||||
self.task = task.transcription_options.task
|
||||
self.word_level_timings = task.transcription_options.word_level_timings
|
||||
self.segments = []
|
||||
|
||||
self.process = QProcess(self)
|
||||
self.process.readyReadStandardError.connect(self.read_std_err)
|
||||
self.process.readyReadStandardOutput.connect(self.read_std_out)
|
||||
self.state = self.State()
|
||||
|
||||
def transcribe(self) -> List[Segment]:
|
||||
self.running = True
|
||||
self.state.running = True
|
||||
model_path = self.model_path
|
||||
|
||||
logging.debug(
|
||||
|
@ -301,84 +300,42 @@ class WhisperCppFileTranscriber(FileTranscriber):
|
|||
'word level timings = %s',
|
||||
self.file_path, self.language, self.task, model_path, self.word_level_timings)
|
||||
|
||||
wav_file = tempfile.mktemp() + '.wav'
|
||||
(
|
||||
ffmpeg.input(self.file_path)
|
||||
.output(wav_file, acodec="pcm_s16le", ac=1, ar=whisper.audio.SAMPLE_RATE)
|
||||
.run(cmd=["ffmpeg", "-nostdin"], capture_stdout=True, capture_stderr=True)
|
||||
)
|
||||
audio = whisper.audio.load_audio(self.file_path)
|
||||
self.duration_audio_ms = len(audio) * 1000 / whisper.audio.SAMPLE_RATE
|
||||
|
||||
args = [
|
||||
'--language', self.language if self.language is not None else 'en',
|
||||
'--max-len', '1' if self.word_level_timings else '0',
|
||||
'--model', model_path,
|
||||
]
|
||||
if self.task == Task.TRANSLATE:
|
||||
args.append('--translate')
|
||||
args.append(wav_file)
|
||||
whisper_params = whisper_cpp_params(language=self.language if self.language is not None else '', task=self.task,
|
||||
word_level_timings=self.word_level_timings)
|
||||
whisper_params.encoder_begin_callback_user_data = ctypes.c_void_p(id(self.state))
|
||||
whisper_params.encoder_begin_callback = whisper_cpp.whisper_encoder_begin_callback(self.encoder_begin_callback)
|
||||
whisper_params.new_segment_callback_user_data = ctypes.c_void_p(id(self.state))
|
||||
whisper_params.new_segment_callback = whisper_cpp.whisper_new_segment_callback(self.new_segment_callback)
|
||||
|
||||
logging.debug(
|
||||
'Running whisper_cpp process, args = "%s"', ' '.join(args))
|
||||
model = WhisperCpp(model=model_path)
|
||||
result = model.transcribe(audio=self.file_path, params=whisper_params)
|
||||
|
||||
self.process.start('./whisper_cpp', args)
|
||||
self.process.waitForFinished()
|
||||
if not self.state.running:
|
||||
raise Stopped
|
||||
|
||||
# Ensure all std_out data has been read
|
||||
self.read_std_out()
|
||||
self.state.running = False
|
||||
return result['segments']
|
||||
|
||||
status = self.process.exitStatus()
|
||||
logging.debug('whisper_cpp process completed with status = %s', status)
|
||||
if status == QProcess.ExitStatus.NormalExit:
|
||||
self.progress.emit(
|
||||
(self.duration_audio_ms, self.duration_audio_ms))
|
||||
|
||||
self.running = False
|
||||
return self.segments
|
||||
|
||||
def stop(self):
|
||||
if self.running:
|
||||
process_state = self.process.state()
|
||||
if process_state == QProcess.ProcessState.Starting or process_state == QProcess.ProcessState.Running:
|
||||
self.process.terminate()
|
||||
|
||||
def read_std_out(self):
|
||||
try:
|
||||
output = self.process.readAllStandardOutput().data().decode('UTF-8').strip()
|
||||
if len(output) > 0:
|
||||
lines = output.split('\n')
|
||||
for line in lines:
|
||||
timings, text = line.split(' ')
|
||||
start, end = self.parse_timings(timings)
|
||||
segment = Segment(start, end, text.strip())
|
||||
self.segments.append(segment)
|
||||
self.progress.emit((end, self.duration_audio_ms))
|
||||
except (UnicodeDecodeError, ValueError):
|
||||
pass
|
||||
|
||||
def parse_timings(self, timings: str) -> Tuple[int, int]:
|
||||
start, end = timings[1:len(timings) - 1].split(' --> ')
|
||||
return self.parse_timestamp(start), self.parse_timestamp(end)
|
||||
def new_segment_callback(self, ctx, _state, _n_new, user_data):
|
||||
n_segments = whisper_cpp.whisper_full_n_segments(ctx)
|
||||
t1 = whisper_cpp.whisper_full_get_segment_t1(ctx, n_segments - 1)
|
||||
# t1 seems to sometimes be larger than the duration when the
|
||||
# audio ends in silence. Trim to fix the displayed progress.
|
||||
progress = min(t1 * 10, self.duration_audio_ms)
|
||||
state: WhisperCppFileTranscriber.State = ctypes.cast(user_data, ctypes.py_object).value
|
||||
if state.running:
|
||||
self.progress.emit((progress, self.duration_audio_ms))
|
||||
|
||||
@staticmethod
|
||||
def parse_timestamp(timestamp: str) -> int:
|
||||
hrs, mins, secs_ms = timestamp.split(':')
|
||||
secs, ms = secs_ms.split('.')
|
||||
return int(hrs) * 60 * 60 * 1000 + int(mins) * 60 * 1000 + int(secs) * 1000 + int(ms)
|
||||
def encoder_begin_callback(_ctx, _state, user_data):
|
||||
state: WhisperCppFileTranscriber.State = ctypes.cast(user_data, ctypes.py_object).value
|
||||
return state.running == 1
|
||||
|
||||
def read_std_err(self):
|
||||
try:
|
||||
output = self.process.readAllStandardError().data().decode('UTF-8').strip()
|
||||
logging.debug('whisper_cpp (stderr): %s', output)
|
||||
|
||||
lines = output.split('\n')
|
||||
for line in lines:
|
||||
if line.startswith('main: processing'):
|
||||
match = re.search(r'samples, (.*) sec', line)
|
||||
if match is not None:
|
||||
self.duration_audio_ms = round(
|
||||
float(match.group(1)) * 1000)
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
def stop(self):
|
||||
self.state.running = False
|
||||
|
||||
|
||||
class OpenAIWhisperAPIFileTranscriber(FileTranscriber):
|
||||
|
@ -697,122 +654,3 @@ class WhisperCpp:
|
|||
|
||||
def __del__(self):
|
||||
whisper_cpp.whisper_free(self.ctx)
|
||||
|
||||
|
||||
class FileTranscriberQueueWorker(QObject):
|
||||
tasks_queue: multiprocessing.Queue
|
||||
current_task: Optional[FileTranscriptionTask] = None
|
||||
current_transcriber: Optional[FileTranscriber] = None
|
||||
current_transcriber_thread: Optional[QThread] = None
|
||||
task_updated = pyqtSignal(FileTranscriptionTask)
|
||||
completed = pyqtSignal()
|
||||
|
||||
def __init__(self, parent: Optional[QObject] = None):
|
||||
super().__init__(parent)
|
||||
self.tasks_queue = queue.Queue()
|
||||
self.canceled_tasks = set()
|
||||
|
||||
@pyqtSlot()
|
||||
def run(self):
|
||||
logging.debug('Waiting for next transcription task')
|
||||
|
||||
# Get next non-canceled task from queue
|
||||
while True:
|
||||
self.current_task: Optional[FileTranscriptionTask] = self.tasks_queue.get()
|
||||
|
||||
# Stop listening when a "None" task is received
|
||||
if self.current_task is None:
|
||||
self.completed.emit()
|
||||
return
|
||||
|
||||
if self.current_task.id in self.canceled_tasks:
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
logging.debug('Starting next transcription task')
|
||||
|
||||
model_type = self.current_task.transcription_options.model.model_type
|
||||
if model_type == ModelType.WHISPER_CPP:
|
||||
self.current_transcriber = WhisperCppFileTranscriber(
|
||||
task=self.current_task)
|
||||
elif model_type == ModelType.OPEN_AI_WHISPER_API:
|
||||
self.current_transcriber = OpenAIWhisperAPIFileTranscriber(task=self.current_task)
|
||||
elif model_type == ModelType.HUGGING_FACE or \
|
||||
model_type == ModelType.WHISPER or \
|
||||
model_type == ModelType.FASTER_WHISPER:
|
||||
self.current_transcriber = WhisperFileTranscriber(task=self.current_task)
|
||||
else:
|
||||
raise Exception(f'Unknown model type: {model_type}')
|
||||
|
||||
self.current_transcriber_thread = QThread(self)
|
||||
|
||||
self.current_transcriber.moveToThread(self.current_transcriber_thread)
|
||||
|
||||
self.current_transcriber_thread.started.connect(
|
||||
self.current_transcriber.run)
|
||||
self.current_transcriber.completed.connect(
|
||||
self.current_transcriber_thread.quit)
|
||||
self.current_transcriber.error.connect(
|
||||
self.current_transcriber_thread.quit)
|
||||
|
||||
self.current_transcriber.completed.connect(
|
||||
self.current_transcriber.deleteLater)
|
||||
self.current_transcriber.error.connect(
|
||||
self.current_transcriber.deleteLater)
|
||||
self.current_transcriber_thread.finished.connect(
|
||||
self.current_transcriber_thread.deleteLater)
|
||||
|
||||
self.current_transcriber.progress.connect(self.on_task_progress)
|
||||
self.current_transcriber.error.connect(self.on_task_error)
|
||||
|
||||
self.current_transcriber.completed.connect(self.on_task_completed)
|
||||
|
||||
# Wait for next item on the queue
|
||||
self.current_transcriber.error.connect(self.run)
|
||||
self.current_transcriber.completed.connect(self.run)
|
||||
|
||||
self.current_task.started_at = datetime.datetime.now()
|
||||
self.current_transcriber_thread.start()
|
||||
|
||||
def add_task(self, task: FileTranscriptionTask):
|
||||
if task.queued_at is None:
|
||||
task.queued_at = datetime.datetime.now()
|
||||
|
||||
self.tasks_queue.put(task)
|
||||
task.status = FileTranscriptionTask.Status.QUEUED
|
||||
self.task_updated.emit(task)
|
||||
|
||||
def cancel_task(self, task_id: int):
|
||||
self.canceled_tasks.add(task_id)
|
||||
|
||||
if self.current_task.id == task_id:
|
||||
if self.current_transcriber is not None:
|
||||
self.current_transcriber.stop()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def on_task_error(self, error: str):
|
||||
if self.current_task is not None and self.current_task.id not in self.canceled_tasks:
|
||||
self.current_task.status = FileTranscriptionTask.Status.FAILED
|
||||
self.current_task.error = error
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
@pyqtSlot(tuple)
|
||||
def on_task_progress(self, progress: Tuple[int, int]):
|
||||
if self.current_task is not None:
|
||||
self.current_task.status = FileTranscriptionTask.Status.IN_PROGRESS
|
||||
self.current_task.fraction_completed = progress[0] / progress[1]
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
@pyqtSlot(list)
|
||||
def on_task_completed(self, segments: List[Segment]):
|
||||
if self.current_task is not None:
|
||||
self.current_task.status = FileTranscriptionTask.Status.COMPLETED
|
||||
self.current_task.segments = segments
|
||||
self.current_task.completed_at = datetime.datetime.now()
|
||||
self.task_updated.emit(self.current_task)
|
||||
|
||||
def stop(self):
|
||||
self.tasks_queue.put(None)
|
||||
if self.current_transcriber is not None:
|
||||
self.current_transcriber.stop()
|
||||
|
|
86
poetry.lock
generated
86
poetry.lock
generated
|
@ -632,36 +632,36 @@ test-randomorder = ["pytest-randomly"]
|
|||
|
||||
[[package]]
|
||||
name = "ctranslate2"
|
||||
version = "3.15.1"
|
||||
version = "3.16.0"
|
||||
description = "Fast inference engine for Transformer models"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ctranslate2-3.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:64f051fa667792083921b91f9a1ae16442348d36ee59ef72cdbf3c487da15dd4"},
|
||||
{file = "ctranslate2-3.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5821fe50557a1a8e7e77eed170a1407fa1991b484a714959c944d6ba2db73633"},
|
||||
{file = "ctranslate2-3.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5922b32ccc21c6501a4cfd22756f574addb33e5e7a9fa6b35768d70974fdcd5a"},
|
||||
{file = "ctranslate2-3.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa85c4f84d293ab87f49f8b66083971751f4830f780fa9462723694a090100f8"},
|
||||
{file = "ctranslate2-3.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:4bd0e3820461fa13b220da949b6704089a245e0adc5b98d6943559398c1edef8"},
|
||||
{file = "ctranslate2-3.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54852c6c9af936dc41732d05593061499986a1b8fed8ce18f246f250bec02303"},
|
||||
{file = "ctranslate2-3.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6a4ec0952fdbfe5d2a7faa8fc8ef9ca66ef962a7c03ccef8b8faba90cc738e4b"},
|
||||
{file = "ctranslate2-3.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05be47755ed3546319e366853b4a6e10976839522ad0292a1072bdeb09961646"},
|
||||
{file = "ctranslate2-3.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:918b0920293cdb84fd48cee806c5d1dc02b0f44fb8e46b1554ef0afa5782af2e"},
|
||||
{file = "ctranslate2-3.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:609cc8582e2cd72d8b098c25b0292c8f957b89e2f2534f7715c7abd56ed2697c"},
|
||||
{file = "ctranslate2-3.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0f1631de468c723dfcfbf76a8d3a8df373f08347a4823fb61e929fa485e71eea"},
|
||||
{file = "ctranslate2-3.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0b049c459fcf930a32254dd6b269c9ffa2e93b0f3de82ee9acbd186c27d7a9"},
|
||||
{file = "ctranslate2-3.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caabbf3c0807e5fa189e7ecd20d40c0a135b098bde1c96aa3dd64f329646c566"},
|
||||
{file = "ctranslate2-3.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e59d01bd04400a391d9baf7bb2af4ba9acfe70187f3c6a871bd5eac1e34ea021"},
|
||||
{file = "ctranslate2-3.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03f0357d16aabbfb5c6b8cf28bfd804aa9f705c774a51af6b397859a99ef3d36"},
|
||||
{file = "ctranslate2-3.15.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8d6bab1864b614a040a8e4b43cd96afe54b2c1bf2dae1c00795134dbccf08734"},
|
||||
{file = "ctranslate2-3.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaed30f9d2483f5b982fb653bd4936a121d5dbdd755780b32b68b8df21e3984c"},
|
||||
{file = "ctranslate2-3.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca8e43052bd1c0b439ce7763a70d02e0b8a6a8f876eb08a9f76b180f4886f200"},
|
||||
{file = "ctranslate2-3.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:634d2b5698b3f2a3754ef47c945b8108ebf9cb69ff2398aa9c04ab1a68abf25c"},
|
||||
{file = "ctranslate2-3.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4bf2c33b12cca04bb3a1b51cae9949c36056ad44071a9daa2f0934ea9910e442"},
|
||||
{file = "ctranslate2-3.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:580e165dffc4aea6d23c1a4fce291ada2191d416d3bfcab5d373597db0088f8f"},
|
||||
{file = "ctranslate2-3.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eefdece8019e8b0e339ada394d1a96dd8ba6821d5a2b82af5a68d2023a8b8358"},
|
||||
{file = "ctranslate2-3.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69a8cd4421006d4dc22162d51acaa58c0190f8189c1519f602417b48cd7af3d"},
|
||||
{file = "ctranslate2-3.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:ffbade375f7fb73b8c533e6cfe5fa7d6cafcf0f4a634c9fa1300a2221c819c42"},
|
||||
{file = "ctranslate2-3.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dab4ec990914afeb2ecbd5c49c0badc32fdfaddd8b03535a42cb64b963d5d5e7"},
|
||||
{file = "ctranslate2-3.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:656825973a4e208803a8bc7963b2a96520c0b3957b0a152fd357807d38f01033"},
|
||||
{file = "ctranslate2-3.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4268087e08c3f8da2240e63d5767aadb2fc109cee6e9958ec0926e72ea5d80ce"},
|
||||
{file = "ctranslate2-3.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f2b204a5034b8dc76d0c817135612629fc566ffbd478e2f08ce26869ce6156e"},
|
||||
{file = "ctranslate2-3.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:d7520bb7379fdabc324db00a80fe27bcef3b92c7e24546c5d7b3b5b20806bb4b"},
|
||||
{file = "ctranslate2-3.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e657517fd91548779c9a10e49c08cb79a224bb51318189c09ac7c90564d438c6"},
|
||||
{file = "ctranslate2-3.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e94bece10ce563eb553c57a96957d074fe49a90b751c880486272ffd7f826dc3"},
|
||||
{file = "ctranslate2-3.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ffadda038a6c7da2bb8cd33319c1027314b358510f269b0e3bcc85bc251413f"},
|
||||
{file = "ctranslate2-3.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47b36fdbd3df12edac3acd2bdee2edf49c47d39b446400d16538a530bec009ab"},
|
||||
{file = "ctranslate2-3.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:de3c4449b1e382b6d544b8ec9938d9c08b7c64347d1ad4fa025bec0c13f59872"},
|
||||
{file = "ctranslate2-3.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7739ae6e3d923446ce10518b6970a20e45e6c4e3dc1074f749b4550e6a016349"},
|
||||
{file = "ctranslate2-3.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bad956a13bd4f752d6dee0a55a1dcf91d1f4efe103b3fb59e56a11876cad65f"},
|
||||
{file = "ctranslate2-3.16.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d231c0083d384f6184c8fcae9e3a4d9a1aacee9e6e62c343d2809899d96370d"},
|
||||
{file = "ctranslate2-3.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:936657316251a989198543feb2ff7a0da6d1a25eb26f6c4ee8603d483b9ee9c3"},
|
||||
{file = "ctranslate2-3.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21e688aee7d4eeefc899b6b81bba3d274cf9e6e34784246b3f2dd90897d0f365"},
|
||||
{file = "ctranslate2-3.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8302c73e1e50549acdcf98dacb12542a5bcc65517eacd5354023e1c40d6f380a"},
|
||||
{file = "ctranslate2-3.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27c83a7ed53208f2c7585340a2b680c8216f0e61e3cf708ccbd47cf908919942"},
|
||||
{file = "ctranslate2-3.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d77c44506fc48be3abb13bda6c498105604c2bb8e0621d60270abd8752b4ba07"},
|
||||
{file = "ctranslate2-3.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:7cecef368455d9d3aac19758547e1faf498444628d7755f71eb592b40c0901ea"},
|
||||
{file = "ctranslate2-3.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8687c897ac2b2b319c9d998603e9c8acb78937e1dcf2543443b3e57d4b1130d6"},
|
||||
{file = "ctranslate2-3.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a87b614d02fdecb743db9afaab66d386f72a711072648051386920092950320c"},
|
||||
{file = "ctranslate2-3.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8aefe37b33173f4d44ea7a45cd6ae127d9821b0cf47b650f34769b80277759b"},
|
||||
{file = "ctranslate2-3.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcb515e512cfe07db3c4d9660674eadf4ee275cf7cbd1ec1070999948941a6f1"},
|
||||
{file = "ctranslate2-3.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:196b1dc5ea043c446ed944d12ec6a50efe9d6bcc802a1b29fa7c42f72d476645"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -765,14 +765,14 @@ dev = ["Sphinx (==2.1.0)", "future (==0.17.1)", "numpy (==1.16.4)", "pytest (==4
|
|||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.12.1"
|
||||
version = "3.12.2"
|
||||
description = "A platform independent file lock."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "filelock-3.12.1-py3-none-any.whl", hash = "sha256:42f1e4ff2b497311213d61ad7aac5fed9050608e5309573f101eefa94143134a"},
|
||||
{file = "filelock-3.12.1.tar.gz", hash = "sha256:82b1f7da46f0ae42abf1bc78e548667f484ac59d2bcec38c713cee7e2eb51e83"},
|
||||
{file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"},
|
||||
{file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
|
@ -1531,25 +1531,25 @@ virtualenv = ">=20.10.0"
|
|||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "4.23.2"
|
||||
version = "4.23.3"
|
||||
description = ""
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "protobuf-4.23.2-cp310-abi3-win32.whl", hash = "sha256:384dd44cb4c43f2ccddd3645389a23ae61aeb8cfa15ca3a0f60e7c3ea09b28b3"},
|
||||
{file = "protobuf-4.23.2-cp310-abi3-win_amd64.whl", hash = "sha256:09310bce43353b46d73ba7e3bca78273b9bc50349509b9698e64d288c6372c2a"},
|
||||
{file = "protobuf-4.23.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:b2cfab63a230b39ae603834718db74ac11e52bccaaf19bf20f5cce1a84cf76df"},
|
||||
{file = "protobuf-4.23.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:c52cfcbfba8eb791255edd675c1fe6056f723bf832fa67f0442218f8817c076e"},
|
||||
{file = "protobuf-4.23.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:86df87016d290143c7ce3be3ad52d055714ebaebb57cc659c387e76cfacd81aa"},
|
||||
{file = "protobuf-4.23.2-cp37-cp37m-win32.whl", hash = "sha256:281342ea5eb631c86697e1e048cb7e73b8a4e85f3299a128c116f05f5c668f8f"},
|
||||
{file = "protobuf-4.23.2-cp37-cp37m-win_amd64.whl", hash = "sha256:ce744938406de1e64b91410f473736e815f28c3b71201302612a68bf01517fea"},
|
||||
{file = "protobuf-4.23.2-cp38-cp38-win32.whl", hash = "sha256:6c081863c379bb1741be8f8193e893511312b1d7329b4a75445d1ea9955be69e"},
|
||||
{file = "protobuf-4.23.2-cp38-cp38-win_amd64.whl", hash = "sha256:25e3370eda26469b58b602e29dff069cfaae8eaa0ef4550039cc5ef8dc004511"},
|
||||
{file = "protobuf-4.23.2-cp39-cp39-win32.whl", hash = "sha256:efabbbbac1ab519a514579ba9ec52f006c28ae19d97915951f69fa70da2c9e91"},
|
||||
{file = "protobuf-4.23.2-cp39-cp39-win_amd64.whl", hash = "sha256:54a533b971288af3b9926e53850c7eb186886c0c84e61daa8444385a4720297f"},
|
||||
{file = "protobuf-4.23.2-py3-none-any.whl", hash = "sha256:8da6070310d634c99c0db7df48f10da495cc283fd9e9234877f0cd182d43ab7f"},
|
||||
{file = "protobuf-4.23.2.tar.gz", hash = "sha256:20874e7ca4436f683b64ebdbee2129a5a2c301579a67d1a7dda2cdf62fb7f5f7"},
|
||||
{file = "protobuf-4.23.3-cp310-abi3-win32.whl", hash = "sha256:514b6bbd54a41ca50c86dd5ad6488afe9505901b3557c5e0f7823a0cf67106fb"},
|
||||
{file = "protobuf-4.23.3-cp310-abi3-win_amd64.whl", hash = "sha256:cc14358a8742c4e06b1bfe4be1afbdf5c9f6bd094dff3e14edb78a1513893ff5"},
|
||||
{file = "protobuf-4.23.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2991f5e7690dab569f8f81702e6700e7364cc3b5e572725098215d3da5ccc6ac"},
|
||||
{file = "protobuf-4.23.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:08fe19d267608d438aa37019236db02b306e33f6b9902c3163838b8e75970223"},
|
||||
{file = "protobuf-4.23.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3b01a5274ac920feb75d0b372d901524f7e3ad39c63b1a2d55043f3887afe0c1"},
|
||||
{file = "protobuf-4.23.3-cp37-cp37m-win32.whl", hash = "sha256:aca6e86a08c5c5962f55eac9b5bd6fce6ed98645d77e8bfc2b952ecd4a8e4f6a"},
|
||||
{file = "protobuf-4.23.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0149053336a466e3e0b040e54d0b615fc71de86da66791c592cc3c8d18150bf8"},
|
||||
{file = "protobuf-4.23.3-cp38-cp38-win32.whl", hash = "sha256:84ea0bd90c2fdd70ddd9f3d3fc0197cc24ecec1345856c2b5ba70e4d99815359"},
|
||||
{file = "protobuf-4.23.3-cp38-cp38-win_amd64.whl", hash = "sha256:3bcbeb2bf4bb61fe960dd6e005801a23a43578200ea8ceb726d1f6bd0e562ba1"},
|
||||
{file = "protobuf-4.23.3-cp39-cp39-win32.whl", hash = "sha256:5cb9e41188737f321f4fce9a4337bf40a5414b8d03227e1d9fbc59bc3a216e35"},
|
||||
{file = "protobuf-4.23.3-cp39-cp39-win_amd64.whl", hash = "sha256:29660574cd769f2324a57fb78127cda59327eb6664381ecfe1c69731b83e8288"},
|
||||
{file = "protobuf-4.23.3-py3-none-any.whl", hash = "sha256:447b9786ac8e50ae72cae7a2eec5c5df6a9dbf9aa6f908f1b8bda6032644ea62"},
|
||||
{file = "protobuf-4.23.3.tar.gz", hash = "sha256:7a92beb30600332a52cdadbedb40d33fd7c8a0d7f549c440347bc606fb3fe34b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2585,4 +2585,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.9.13,<3.11"
|
||||
content-hash = "55f51f9fab6c4d69d85bae1bed3d4c62e9cba8819feaf3acdf6de0aa05100092"
|
||||
content-hash = "487051d5612787780f1d23aa1125ea8e8a43cb09024967113bd9fda9b8c42b3d"
|
||||
|
|
|
@ -12,7 +12,6 @@ sounddevice = "^0.4.5"
|
|||
torch = "1.12.1"
|
||||
transformers = "~4.24.0"
|
||||
appdirs = "^1.4.4"
|
||||
ffmpeg-python = "^0.2.0"
|
||||
humanize = "^4.4.0"
|
||||
PyQt6 = "6.4.0"
|
||||
stable-ts = "1.0.2"
|
||||
|
|
|
@ -84,6 +84,12 @@ parts:
|
|||
- libpulse0
|
||||
- libasound2
|
||||
- libasound2-plugins
|
||||
override-build: |
|
||||
craftctl default
|
||||
cp $CRAFT_PART_BUILD/libwhisper.so $CRAFT_PART_INSTALL/
|
||||
cp $CRAFT_PART_BUILD/libwhisper.so $CRAFT_PART_INSTALL/usr/lib/
|
||||
cp $CRAFT_PART_BUILD/whisper_cpp $CRAFT_PART_INSTALL/
|
||||
mkdir $CRAFT_PART_INSTALL/buzz && cp $CRAFT_PART_BUILD/buzz/whisper_cpp.py $CRAFT_PART_INSTALL/buzz/
|
||||
python-packages:
|
||||
- aiohttp==3.8.4
|
||||
- aiosignal==1.3.1
|
||||
|
@ -160,7 +166,7 @@ apps:
|
|||
desktop: usr/share/applications/buzz.desktop
|
||||
environment:
|
||||
PATH: $SNAP/usr/bin:$SNAP/bin:$PATH
|
||||
LD_LIBRARY_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/lapack:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/blas:$LD_LIBRARY_PATH
|
||||
LD_LIBRARY_PATH: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/lapack:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/blas:$SNAP:$LD_LIBRARY_PATH
|
||||
PYTHONPATH: $SNAP/usr/lib/python3/dist-packages:$SNAP/usr/lib/python3.10/site-packages:$SNAP/usr/local/lib/python3.10/dist-packages:$SNAP/usr/lib/python3.10/dist-packages:$PYTHONPATH
|
||||
# Fallback to XWayland if running in a Wayland session.
|
||||
DISABLE_WAYLAND: 1
|
||||
|
|
|
@ -73,7 +73,7 @@ class TestWhisperCppFileTranscriber:
|
|||
task=FileTranscriptionTask(file_path='testdata/whisper-french.mp3',
|
||||
transcription_options=transcription_options,
|
||||
file_transcription_options=file_transcription_options, model_path=model_path))
|
||||
mock_progress = Mock()
|
||||
mock_progress = Mock(side_effect=lambda value: print('progress: ', value))
|
||||
mock_completed = Mock()
|
||||
transcriber.progress.connect(mock_progress)
|
||||
transcriber.completed.connect(mock_completed)
|
||||
|
|
Loading…
Reference in a new issue