mirror of
https://github.com/chidiwilliams/buzz.git
synced 2026-03-14 14:45:46 +01:00
Add speaker identification2 (#1290)
Co-authored-by: David Olowomeye <100958002+greatdaveo@users.noreply.github.com>
This commit is contained in:
parent
cabbd487f9
commit
73376a63ac
153 changed files with 7409 additions and 719 deletions
|
|
@ -1,9 +1,12 @@
|
|||
[run]
|
||||
omit =
|
||||
buzz/whisper_cpp/*
|
||||
buzz/transcriber/local_whisper_cpp_server_transcriber.py
|
||||
*_test.py
|
||||
demucs/*
|
||||
buzz/transcriber/local_whisper_cpp_server_transcriber.py
|
||||
whisper_diarization/*
|
||||
deepmultilingualpunctuation/*
|
||||
ctc_forced_aligner/*
|
||||
|
||||
[html]
|
||||
directory = coverage/html
|
||||
|
|
|
|||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -70,10 +70,10 @@ jobs:
|
|||
~/AppData/Local/Buzz/Buzz/Cache
|
||||
key: whisper-models
|
||||
|
||||
- uses: AnimMouse/setup-ffmpeg@v1.2.1
|
||||
- uses: AnimMouse/setup-ffmpeg@v1
|
||||
id: setup-ffmpeg
|
||||
with:
|
||||
version: ${{ matrix.os == 'macos-15-intel' && '7.1.1' || matrix.os == 'macos-latest' && '71' || '7.1' }}
|
||||
version: ${{ matrix.os == 'macos-15-intel' && '7.1.1' || matrix.os == 'macos-latest' && '80' || '8.0' }}
|
||||
|
||||
- name: Test ffmpeg
|
||||
run: ffmpeg -i ./testdata/audio-long.mp3 ./testdata/audio-long.wav
|
||||
|
|
|
|||
13
.github/workflows/snapcraft.yml
vendored
13
.github/workflows/snapcraft.yml
vendored
|
|
@ -15,9 +15,22 @@ concurrency:
|
|||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
BUZZ_DISABLE_TELEMETRY: true
|
||||
outputs:
|
||||
snap: ${{ steps.snapcraft.outputs.snap }}
|
||||
steps:
|
||||
# Ideas from https://github.com/orgs/community/discussions/25678
|
||||
- name: Remove unused build tools
|
||||
run: |
|
||||
sudo apt-get remove -y '^llvm-.*'
|
||||
sudo apt-get remove -y 'php.*'
|
||||
sudo apt-get remove -y azure-cli google-cloud-sdk hhvm google-chrome-stable firefox powershell mono-devel || true
|
||||
sudo apt-get autoremove -y
|
||||
sudo apt-get clean
|
||||
python -m pip cache purge
|
||||
rm -rf /opt/hostedtoolcache || true
|
||||
- name: Maximize build space
|
||||
uses: easimon/maximize-build-space@master
|
||||
with:
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -31,4 +31,5 @@ benchmarks.json
|
|||
/coverage/
|
||||
/wheelhouse/
|
||||
/.flatpak-builder
|
||||
/repo
|
||||
/repo
|
||||
/nemo_msdd_configs
|
||||
|
|
|
|||
12
.gitmodules
vendored
12
.gitmodules
vendored
|
|
@ -1,3 +1,15 @@
|
|||
[submodule "whisper.cpp"]
|
||||
path = whisper.cpp
|
||||
url = https://github.com/ggerganov/whisper.cpp
|
||||
[submodule "whisper_diarization"]
|
||||
path = whisper_diarization
|
||||
url = https://github.com/MahmoudAshraf97/whisper-diarization
|
||||
[submodule "demucs"]
|
||||
path = demucs
|
||||
url = https://github.com/MahmoudAshraf97/demucs.git
|
||||
[submodule "deepmultilingualpunctuation"]
|
||||
path = deepmultilingualpunctuation
|
||||
url = https://github.com/oliverguhr/deepmultilingualpunctuation.git
|
||||
[submodule "ctc_forced_aligner"]
|
||||
path = ctc_forced_aligner
|
||||
url = https://github.com/MahmoudAshraf97/ctc-forced-aligner.git
|
||||
|
|
|
|||
|
|
@ -30,7 +30,13 @@ datas += collect_data_files("transformers", include_py_files=True)
|
|||
datas += collect_data_files("faster_whisper", include_py_files=True)
|
||||
datas += collect_data_files("stable_whisper", include_py_files=True)
|
||||
datas += collect_data_files("whisper")
|
||||
datas += [("demucs", "demucs")]
|
||||
datas += collect_data_files("demucs", include_py_files=True)
|
||||
datas += collect_data_files("whisper_diarization", include_py_files=True)
|
||||
datas += collect_data_files("deepmultilingualpunctuation", include_py_files=True)
|
||||
datas += collect_data_files("ctc_forced_aligner", include_py_files=True)
|
||||
datas += collect_data_files("nemo", include_py_files=True)
|
||||
datas += collect_data_files("lightning_fabric", include_py_files=True)
|
||||
datas += collect_data_files("pytorch_lightning", include_py_files=True)
|
||||
datas += [("buzz/assets/*", "assets")]
|
||||
datas += [("buzz/locale", "locale")]
|
||||
datas += [("buzz/schema.sql", ".")]
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ sudo apt-get install --no-install-recommends libyaml-dev libtbb-dev libxkbcommon
|
|||
```
|
||||
On versions prior to Ubuntu 24.04 install `sudo apt-get install --no-install-recommends libegl1-mesa`
|
||||
5. Install the dependencies `uv sync`
|
||||
6. Build Buzz `uv build`
|
||||
7. Run Buzz `uv run buzz`
|
||||
6. Run Buzz `uv run buzz`
|
||||
|
||||
#### Necessary dependencies for Faster Whisper on GPU
|
||||
|
||||
|
|
@ -81,8 +80,7 @@ On versions prior to Ubuntu 24.04 install `sudo apt-get install --no-install-rec
|
|||
3. Install uv `curl -LsSf https://astral.sh/uv/install.sh | sh` (or `brew install uv`)
|
||||
4. Install system dependencies you may be missing `brew install ffmpeg`
|
||||
5. Install the dependencies `uv sync`
|
||||
6. Build Buzz `uv build`
|
||||
7. Run Buzz `uv run buzz`
|
||||
6. Run Buzz `uv run buzz`
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
7
Makefile
7
Makefile
|
|
@ -1,4 +1,5 @@
|
|||
version := 1.3.4
|
||||
# Change also in pyproject.toml and buzz/__version__.py
|
||||
version := 1.4.0
|
||||
|
||||
mac_app_path := ./dist/Buzz.app
|
||||
mac_zip_path := ./dist/Buzz-${version}-mac.zip
|
||||
|
|
@ -28,7 +29,7 @@ else
|
|||
rm -rf dist/* || true
|
||||
endif
|
||||
|
||||
COVERAGE_THRESHOLD := 75
|
||||
COVERAGE_THRESHOLD := 70
|
||||
|
||||
test: buzz/whisper_cpp
|
||||
pytest -s -vv --cov=buzz --cov-report=xml --cov-report=html --benchmark-skip --cov-fail-under=${COVERAGE_THRESHOLD} --cov-config=.coveragerc
|
||||
|
|
@ -67,7 +68,7 @@ ifeq ($(shell uname -s), Linux)
|
|||
cp whisper.cpp/build/bin/whisper-server buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/src/libwhisper.so buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/src/libwhisper.so.1 buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/src/libwhisper.so.1.7.6 buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/src/libwhisper.so.1.8.2 buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/ggml/src/libggml.so buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/ggml/src/libggml-base.so buzz/whisper_cpp/ || true
|
||||
cp whisper.cpp/build/ggml/src/libggml-cpu.so buzz/whisper_cpp/ || true
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ OpenAI's [Whisper](https://github.com/openai/whisper).
|
|||
[](https://GitHub.com/chidiwilliams/buzz/releases/)
|
||||
|
||||
<blockquote>
|
||||
<p>Buzz is better on the App Store. Get a Mac-native version of Buzz with a cleaner look, audio playback, drag-and-drop import, transcript editing, search, and much more.</p>
|
||||
<p>An older version of Buzz available on the App Store. Get a Mac-native version of Buzz with a cleaner look, audio playback, drag-and-drop import, transcript editing, search, and much more.</p>
|
||||
<a href="https://apps.apple.com/us/app/buzz-captions/id6446018936?mt=12&itsct=apps_box_badge&itscg=30200"><img src="https://toolbox.marketingtools.apple.com/api/badges/download-on-the-mac-app-store/black/en-us?size=250x83&releaseDate=1679529600" alt="Download on the Mac App Store" /></a>
|
||||
</blockquote>
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
VERSION = "1.3.4"
|
||||
VERSION = "1.4.0"
|
||||
|
|
|
|||
14
buzz/assets/speaker-identification.svg
Normal file
14
buzz/assets/speaker-identification.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<svg height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 493.347 493.347" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill:#010002;" d="M191.936,385.946c-14.452,0-29.029-1.36-43.319-4.04l-5.299-0.996l-66.745,37.15v-63.207
|
||||
l-6.629-4.427C25.496,320.716,0,277.045,0,230.617c0-85.648,86.102-155.33,191.936-155.33c17.077,0,33.623,1.838,49.394,5.239
|
||||
c-50.486,27.298-84.008,74.801-84.008,128.765c0,72.969,61.25,134.147,142.942,149.464
|
||||
C269.41,375.892,232.099,385.946,191.936,385.946z"/>
|
||||
<path style="fill:#010002;" d="M437.777,304.278l-6.629,4.427v48.075l-50.933-28.343l-0.125,0.024l-5.167,0.967
|
||||
c-11.444,2.142-23.104,3.228-34.673,3.228c-1.241,0-2.47-0.054-3.705-0.078c-82.707-1.599-149.387-56.268-149.387-123.287
|
||||
c0-52.109,40.324-96.741,97.129-114.791c14.47-4.594,30.001-7.471,46.219-8.3c3.228-0.167,6.468-0.274,9.75-0.274
|
||||
c84.413,0,153.092,55.343,153.092,123.365C493.347,246.053,473.089,280.679,437.777,304.278z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1 KiB |
11
buzz/buzz.py
11
buzz/buzz.py
|
|
@ -56,6 +56,17 @@ def main():
|
|||
format=log_format,
|
||||
)
|
||||
|
||||
# Silence noisy third-party library loggers
|
||||
logging.getLogger("matplotlib").setLevel(logging.WARNING)
|
||||
logging.getLogger("graphviz").setLevel(logging.WARNING)
|
||||
logging.getLogger("nemo_logger").setLevel(logging.ERROR)
|
||||
logging.getLogger("numba").setLevel(logging.WARNING)
|
||||
logging.getLogger("torio._extension.utils").setLevel(logging.WARNING)
|
||||
logging.getLogger("export_config_manager").setLevel(logging.WARNING)
|
||||
logging.getLogger("training_telemetry_provider").setLevel(logging.ERROR)
|
||||
logging.getLogger("default_recorder").setLevel(logging.WARNING)
|
||||
logging.getLogger("config").setLevel(logging.WARNING)
|
||||
|
||||
if getattr(sys, "frozen", False) is False:
|
||||
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||
stdout_handler.setLevel(logging.DEBUG)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from uuid import UUID
|
|||
|
||||
from PyQt6.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
|
||||
|
||||
from demucs import api as demucsApi
|
||||
from demucs.demucs import api as demucsApi
|
||||
|
||||
from buzz.model_loader import ModelType
|
||||
from buzz.transcriber.file_transcriber import FileTranscriber
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: buzz\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-10-17 07:59+0200\n"
|
||||
"Last-Translator: Éric Duarte <contacto@ericdq.com>\n"
|
||||
"Language-Team: Catalan <jmas@softcatala.org>\n"
|
||||
|
|
@ -554,64 +554,68 @@ msgstr "Veure"
|
|||
msgid "Timestamps"
|
||||
msgstr "Marqua de temps"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Exporta"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Traduir"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Redimensionar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr "Cerca"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr "Mostra/amaga la barra de cerca (Ctrl+F)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr "Cerca:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr "Introduïu el text a cercar..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr "Coincidència anterior (Maj+Retorn)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr "Coincidència següent (retorn)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr "Neteja"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr "Controls de reproducció:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr "Segment de bucle"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr "Activa/desactiva el bucle en fer clic als segments de transcripció"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr "Segueix l'àudio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
|
|
@ -619,75 +623,146 @@ msgstr ""
|
|||
"Activa/desactiva seguint la posició d'àudio actual a la transcripció. Quan "
|
||||
"està activada, es desplaça automàticament al text actual."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr "Desplaça't fins a l'actual"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr "Desplaçar-se fins al text que es parla actualment"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr "1 de més de 100 coincidències"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr "1 de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr " coincidències"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr "No s'ha trobat cap coincidència"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr " de més de 100 coincidències"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr " de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Clau API necessària"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Introduïu la clau API d'OpenAI a les preferències"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Opcions de redimensionament"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Longitud desitjada dels subtítols"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Opcions de fusió"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Fusiona per buit"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Divideix per puntuació"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Divideix per la longitud màxima"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Fusiona"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Cancel·la la transcripció"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Desa el fitxer"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Desa el fitxer"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Ole Guldberg2 <xalt7x.service@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -552,138 +552,213 @@ msgstr "Vis"
|
|||
msgid "Timestamps"
|
||||
msgstr "Tidsstempler"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Eksporter"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Oversæt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Behandel størrelse"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "API-nøgle påkrævet"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Indtast venligst OpenAI API-nøgle i indstillinger"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Størrelsesindstillinger"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Ønskede undertekst længde"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Sammenfletningsindstillinger"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Sammenflet ved hul"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Split ved punktum"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Split ved max længde"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Sammenflet"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Afbryd transkription"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Gem fil"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Gem fil"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-03-05 14:41+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -552,138 +552,213 @@ msgstr "Anzeigen"
|
|||
msgid "Timestamps"
|
||||
msgstr "Zeitstempel"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Export"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Übersetzen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Größe ändern"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "API-Schlüssel erforderlich"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Bitte geben Sie den OpenAI-API-Schlüssel in den Einstellungen ein"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Größenänderungsoptionen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Gewünschte Untertitellänge"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Zusammenführungsoptionen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Nach Abstand zusammenführen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Durch Satzzeichen getrennt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Aufgeteilt nach maximaler Länge"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Vereinigen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Transkription abbrechen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Datei speichern"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Datei speichern"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -540,138 +540,211 @@ msgstr ""
|
|||
msgid "Timestamps"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr ""
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-09-08 12:43+0200\n"
|
||||
"Last-Translator: Éric Duarte <contacto@ericdq.com>\n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -589,66 +589,70 @@ msgstr "Ver"
|
|||
msgid "Timestamps"
|
||||
msgstr "Marcas de tiempo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Exportar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Traducir"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Cambiar el tamaño"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr "Buscar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr "Mostrar/Ocultar barra de búsqueda (Ctrl+F)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr "Encontrar:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr "Introducir texto para encontrar..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr "Coincidencia anterior (Mayús+Intro)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr "Siguiente coincidencia (Enter)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr "Limpiar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr "Controles de reproducción:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr "Segmento de bucle"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
"Activar/desactivar la reproducción en bucle al hacer clic en segmentos de la "
|
||||
"transcripción"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr "Seguir audio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
|
|
@ -657,75 +661,148 @@ msgstr ""
|
|||
"transcripción. Cuando está activado, se desplaza automáticamente al texto "
|
||||
"actual."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr "Desplácese hasta Actual"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr "Desplazarse hasta el texto hablado actualmente"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr "1 de 100+ coincidencias"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr "1 de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr " coincidencias"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr "No se encontraron coincidencias"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr " de 100+ coincidencias"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr " de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Clave de API requerida"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Ingrese la clave API de OpenAI en las preferencias"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Opciones de cambio de tamaño"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Longitud deseada de los subtítulos"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Opciones de fusión"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Fusión por hueco"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Dividido por puntuación"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Dividido por la longitud máxima"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Fusión"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
# automatic translation
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Cancelar transcripción"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
# automatic translation
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Guardar archivo"
|
||||
|
||||
# automatic translation
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: buzz\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-11-09 20:22+0200\n"
|
||||
"Language-Team: (Italiano) Albano Battistella <albanobattistella@gmail.com>\n"
|
||||
"Language: it_IT\n"
|
||||
|
|
@ -555,65 +555,69 @@ msgstr "Visualizza"
|
|||
msgid "Timestamps"
|
||||
msgstr "Timestamp"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Esporta"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Tradurre"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Ridimensionare"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr "Trova"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr "Mostra/Nascondi barra di ricerca (Ctrl+F)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr "Trova:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr "Inserisci il testo per trovare..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr "Corrispondenza precedente (Maiusc+Invio)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr "Prossima corrispondenza (Invio)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr "Elimina"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr "Controlli di riproduzione:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr "Ciclo di segmento"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
"Abilita/disabilita il loop quando si fa clic sui segmenti della trascrizione"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr "Segui Audio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
|
|
@ -622,75 +626,146 @@ msgstr ""
|
|||
"trascrizione. Quando abilitato, scorre automaticamente fino al testo "
|
||||
"corrente."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr "Scorri fino al Corrente"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr "Scorrere fino al testo attualmente pronunciato"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr "1 di 100+ corrispondenze"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr "1 di"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr "corrispondenze"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr "Nessuna corrispondenza trovata"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr " di oltre 100 corrispondenze"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr " di "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Chiave API richiesta"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Inserisci la chiave API OpenAI nelle preferenze"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Opzioni di ridimensionamento"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Lunghezza desiderata dei sottotitoli"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Opzioni di unione"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Unito per spazio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Diviso per punteggiatura"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Diviso per lunghezza massima"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Unione"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Inizio trascrizione..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Salva file"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Salva file"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: nunawa <71294849+nunawa@users.noreply.github.com>\n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -548,139 +548,214 @@ msgstr "表示"
|
|||
msgid "Timestamps"
|
||||
msgstr "タイムスタンプ"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "出力"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "翻訳"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "リサイズ"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "APIキーが必要"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "設定画面でOpenAI APIキーを入力してください"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
#, fuzzy
|
||||
msgid "Resize Options"
|
||||
msgstr "リサイズ"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "希望する字幕の長さ"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "文字起こしをキャンセルする"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "ファイルを保存"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "ファイルを保存"
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@
|
|||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"PO-Revision-Date: 2025-11-28 16:50+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 13:02+0200\n"
|
||||
"PO-Revision-Date: 2025-11-23 12:58+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: lv_LV\n"
|
||||
|
|
@ -558,64 +557,68 @@ msgstr "Skats"
|
|||
msgid "Timestamps"
|
||||
msgstr "Laiks"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Eksportēt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Tulkot"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Mainīt garumu"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr "Noteikt runātājus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr "Meklēt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr "Rādīt/Slēpt meklēšanas joslu (Ctrl+F)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr "Meklēt:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr "Ievadiet meklējamo..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr "Iepriekšējais rezultāts (Shift+Enter)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr "Nākamais rezultāts (Enter)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr "Notīrīt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr "Atskaņošanas iespējas:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr "Atkārtot segmentu"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr "Nosaka vai atkārtot izvēlēto segmentu"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr "Sekot audio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
|
|
@ -623,75 +626,144 @@ msgstr ""
|
|||
"Nosaka vai atskaņojot audio iezīmētajam segmentam vajadzētu automātiski "
|
||||
"sekot tam kas tiek atskaņots."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr "Pāriet uz tekošo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr "Pāriet uz šobrīd atskaņojamo tesktu"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr "1 no 100+ "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr "1 no "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr " "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr "Nekas nav atrasts"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr " no 100+"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr " no "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "API atslēgas kļūda"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Lūdzu ievadiet OpenAI API atslēgu iestatījumos"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Garuma maiņas iestatījumi"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Vēlamais teksta garums"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Apvienošanas iestatījumi"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Apvienot pēc attāluma"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Dalīt pie pieturzīmēm"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Dalīt pie maksimālā garuma"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Apvienot"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr "1/8 Apkopo transkripcijas"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr "2/8 Ielādē audio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr "3/8 Ielādē identifikācijas modeli"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr "4/8 Apstrādā audio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "5/8 Sagatavo transkripcijas"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr "6/8 Nosaka runātājus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr "0/0 Kļūda nosakot runātājus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr "7/8 Marķē runātāju teikumus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr "8/8 Runātāju noteikšana pabeigta"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr "1. solis: Runātāju noteikšana"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr "Noteikt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr "Gatavs noteikt runātājus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr "Audio datne nav atrasta"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr "2. solis: Runātāju identifikācija"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr "Atskaņot paraugu"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr "Apvienot secīgus runātāja teikumus"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
msgid "Save"
|
||||
msgstr "Saglabāt"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Saglabāt failu"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-03-20 18:30+0100\n"
|
||||
"Last-Translator: Heimen Stoffels <vistausss@fastmail.com>\n"
|
||||
"Language-Team: none\n"
|
||||
|
|
@ -552,138 +552,213 @@ msgstr "Bekijken"
|
|||
msgid "Timestamps"
|
||||
msgstr "Tijdstippen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Exporteren"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Vertalen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Grootte"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Api-sleutel vereist"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Voer de OpenAI-api-sleutel in in de instellingen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Grootteopties"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Voorkeurslengte van ondertiteling"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Samenvoegopties"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Samenvoegen op basis van tussenruimte"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Splitsen op basis van leestekens"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Splitsen op basis van max. lengte"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Samenvoegen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Transcriptie wissen"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Bestand opslaan"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Bestand opslaan"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2024-03-17 20:50+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -561,138 +561,213 @@ msgstr ""
|
|||
msgid "Timestamps"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Anuluj transkrypcję"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Zapisz plik"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
#, fuzzy
|
||||
msgid "Save File"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Buzz\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2025-11-01 17:43-0300\n"
|
||||
"Last-Translator: Paulo Schopf <pschopf@gmail.com>\n"
|
||||
"Language-Team: none\n"
|
||||
|
|
@ -552,64 +552,68 @@ msgstr "Visualizar"
|
|||
msgid "Timestamps"
|
||||
msgstr "Marcações de tempo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Exportar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Traduzir"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "Redimensionar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr "Procurar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr "Mostrar/Ocultar a Barra de Pesquisa"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr "Procurar:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr "Digite o texto a procurar..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr "Encontro prévio (Shift+Enter)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr "Póximo encontro (Enter)"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr "Limpar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr "Controles de Reprodução:"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr "Segmento de Loop"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr "Habilitar/desabilitar loop ao clicar em segmentos de transcrição"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr "Siga o Áudio"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
|
|
@ -617,75 +621,146 @@ msgstr ""
|
|||
"Ativar/desativar a opção de seguir a posição atual do áudio na transcrição. "
|
||||
"Quando ativado, rola automaticamente para o texto atual."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr "Rolar para o Atual"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr "Role até o texto falado no momento"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr "1 de 100+ encontros"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr "1 de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr " encontros"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr "Nada encontrado"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr " de 100+ encontros"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr " de "
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Chave API Necessária"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Insira a chave API OpenAI nas preferências"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr "Opções de Redimensionamento"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "Duração desejada da legenda"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "Opções de Mesclagem"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "Mesclar por intervalo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "Dividir por pontuação"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "Dividir por tamanho máximo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "Mesclar"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Iniciando transcrição..."
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Salvar Arquivo"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Salvar Arquivo"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Yevhen Popok <xalt7x.service@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
|
|
@ -550,138 +550,213 @@ msgstr "Вигляд"
|
|||
msgid "Timestamps"
|
||||
msgstr "Позначки часу"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "Експорт"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "Перекласти"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "Потрібен API-ключ"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "Будь ласка, введіть API-ключ OpenAI в налаштуваннях"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "Скасувати транскрипцію"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "Зберегти файл"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
msgid "Save File"
|
||||
msgstr "Зберегти файл"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2023-05-01 15:45+0800\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: lamb \n"
|
||||
|
|
@ -562,139 +562,214 @@ msgstr "查看"
|
|||
msgid "Timestamps"
|
||||
msgstr "时间戳"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr "导出"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr "翻译"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr "调整大小"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr "需要API Key"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr "请在偏好设置中输入OpenAI API Key"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
#, fuzzy
|
||||
msgid "Resize Options"
|
||||
msgstr "调整大小"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr "所需字幕长度"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr "合并选项"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr "按间隔合并"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr "按标点符号拆分"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr "按最大长度拆分"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr "合并"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "取消识别"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "保存文件"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
#, fuzzy
|
||||
msgid "Save File"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-11-28 16:49+0200\n"
|
||||
"POT-Creation-Date: 2025-11-23 12:55+0200\n"
|
||||
"PO-Revision-Date: 2023-05-01 15:45+0800\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Lamb\n"
|
||||
|
|
@ -557,138 +557,213 @@ msgstr ""
|
|||
msgid "Timestamps"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:211
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:215
|
||||
msgid "Export"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:230
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:234
|
||||
msgid "Translate"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:240
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:177
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:244
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:175
|
||||
msgid "Resize"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:252
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:257
|
||||
msgid "Identify Speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:269
|
||||
msgid "Find"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:255
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:272
|
||||
msgid "Show/Hide Search Bar (Ctrl+F)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:320
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:337
|
||||
msgid "Find:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:326
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:343
|
||||
msgid "Enter text to find..."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:339
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:356
|
||||
msgid "Previous match (Shift+Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:347
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:364
|
||||
msgid "Next match (Enter)"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:355
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:372
|
||||
msgid "Clear"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:382
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:399
|
||||
msgid "Playback Controls:"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:387
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:404
|
||||
msgid "Loop Segment"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:389
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:406
|
||||
msgid "Enable/disable looping when clicking on transcript segments"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:395
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:412
|
||||
msgid "Follow Audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:397
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:414
|
||||
msgid ""
|
||||
"Enable/disable following the current audio position in the transcript. When "
|
||||
"enabled, automatically scrolls to current text."
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:444
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:461
|
||||
msgid "Scroll to Current"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:446
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:463
|
||||
msgid "Scroll to the currently spoken text"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:768
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:785
|
||||
msgid "1 of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
msgid "1 of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:770
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:787
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:775
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:792
|
||||
msgid "No matches found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:834
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:851
|
||||
msgid " of 100+ matches"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:836
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:853
|
||||
msgid " of "
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1191
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1208
|
||||
msgid "API Key Required"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1192
|
||||
#: buzz/widgets/transcription_viewer/transcription_viewer_widget.py:1209
|
||||
msgid "Please enter OpenAI API Key in preferences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:159
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:157
|
||||
msgid "Resize Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:170
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:168
|
||||
msgid "Desired subtitle length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:195
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:193
|
||||
msgid "Merge Options"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:206
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:204
|
||||
msgid "Merge by gap"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:214
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:212
|
||||
msgid "Split by punctuation"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:222
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:220
|
||||
msgid "Split by max length"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:234
|
||||
#: buzz/widgets/transcription_viewer/transcription_resizer_widget.py:232
|
||||
msgid "Merge"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:92
|
||||
msgid "1/8 Collecting transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:106
|
||||
msgid "2/8 Loading audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:115
|
||||
msgid "3/8 Loading alignment model"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:121
|
||||
msgid "4/8 Processing audio"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:133
|
||||
#, fuzzy
|
||||
msgid "5/8 Preparing transcripts"
|
||||
msgstr "取消錄製"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:151
|
||||
msgid "6/8 Identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:160
|
||||
msgid "0/0 Error identifying speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:168
|
||||
msgid "7/8 Mapping speakers to transcripts"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:207
|
||||
msgid "8/8 Identification done"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:243
|
||||
msgid "Step 1: Identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:255
|
||||
msgid "Identify"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:265
|
||||
msgid "Ready to identify speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:267
|
||||
msgid "Audio file not found"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:283
|
||||
msgid "Step 2: Name speakers"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:298
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:391
|
||||
msgid "Play sample"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:313
|
||||
msgid "Merge speaker sentences"
|
||||
msgstr ""
|
||||
|
||||
#: buzz/widgets/transcription_viewer/speaker_identification_widget.py:318
|
||||
#, fuzzy
|
||||
msgid "Save"
|
||||
msgstr "檔案"
|
||||
|
||||
#: buzz/widgets/transcription_viewer/export_transcription_menu.py:82
|
||||
#, fuzzy
|
||||
msgid "Save File"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import sys
|
|||
import logging
|
||||
import subprocess
|
||||
import json
|
||||
import tempfile
|
||||
from typing import List
|
||||
from buzz.assets import APP_BASE_DIR
|
||||
from buzz.transcriber.transcriber import Segment, Task, FileTranscriptionTask
|
||||
|
|
@ -58,9 +57,7 @@ class WhisperCpp:
|
|||
file_to_process = task.file_path
|
||||
|
||||
if file_ext not in supported_formats:
|
||||
# Create temporary WAV file
|
||||
temp_dir = tempfile.gettempdir()
|
||||
temp_file = os.path.join(temp_dir, f"buzz_temp_{os.path.basename(task.file_path)}.wav")
|
||||
temp_file = task.file_path + ".wav"
|
||||
|
||||
logging.info(f"Converting {task.file_path} to WAV format")
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ class ResizeIcon(Icon):
|
|||
def __init__(self, parent: QWidget):
|
||||
super().__init__(get_path("assets/resize_black.svg"), parent)
|
||||
|
||||
class SpeakerIdentificationIcon(Icon):
|
||||
def __init__(self, parent: QWidget):
|
||||
super().__init__(get_path("assets/speaker-identification.svg"), parent)
|
||||
|
||||
class VisibilityIcon(Icon):
|
||||
def __init__(self, parent: QWidget):
|
||||
super().__init__(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,504 @@
|
|||
import re
|
||||
import os
|
||||
import logging
|
||||
import faster_whisper
|
||||
import torch
|
||||
import random
|
||||
from typing import Optional
|
||||
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
|
||||
from PyQt6.QtCore import Qt, QThread, QObject, pyqtSignal, QUrl, QTimer
|
||||
from PyQt6.QtGui import QFont
|
||||
from PyQt6.QtWidgets import (
|
||||
QWidget,
|
||||
QFormLayout,
|
||||
QVBoxLayout,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QProgressBar,
|
||||
QPushButton,
|
||||
QCheckBox,
|
||||
QGroupBox,
|
||||
QSpacerItem,
|
||||
QSizePolicy,
|
||||
QLayout,
|
||||
)
|
||||
from buzz.locale import _
|
||||
from buzz.db.entity.transcription import Transcription
|
||||
from buzz.db.service.transcription_service import TranscriptionService
|
||||
from buzz.paths import file_path_as_title
|
||||
from buzz.settings.settings import Settings
|
||||
from buzz.widgets.line_edit import LineEdit
|
||||
from buzz.transcriber.transcriber import Segment
|
||||
|
||||
from ctc_forced_aligner.ctc_forced_aligner import (
|
||||
generate_emissions,
|
||||
get_alignments,
|
||||
get_spans,
|
||||
load_alignment_model,
|
||||
postprocess_results,
|
||||
preprocess_text,
|
||||
)
|
||||
from whisper_diarization.helpers import (
|
||||
get_realigned_ws_mapping_with_punctuation,
|
||||
get_sentences_speaker_mapping,
|
||||
get_words_speaker_mapping,
|
||||
langs_to_iso,
|
||||
punct_model_langs,
|
||||
)
|
||||
from deepmultilingualpunctuation.deepmultilingualpunctuation import PunctuationModel
|
||||
from whisper_diarization.diarization import MSDDDiarizer
|
||||
|
||||
SENTENCE_END = re.compile(r'.*[.!?。!?]')
|
||||
|
||||
class IdentificationWorker(QObject):
|
||||
finished = pyqtSignal(list)
|
||||
progress_update = pyqtSignal(str)
|
||||
|
||||
def __init__(self, transcription, transcription_service):
|
||||
super().__init__()
|
||||
self.transcription = transcription
|
||||
self.transcription_service = transcription_service
|
||||
|
||||
def get_transcript(self, audio, **kwargs) -> dict:
|
||||
buzz_segments = self.transcription_service.get_transcription_segments(
|
||||
transcription_id=self.transcription.id_as_uuid
|
||||
)
|
||||
|
||||
segments = []
|
||||
words = []
|
||||
text = ""
|
||||
for buzz_segment in buzz_segments:
|
||||
words.append({
|
||||
'word': buzz_segment.text + " ",
|
||||
'start': buzz_segment.start_time / 100,
|
||||
'end': buzz_segment.end_time / 100,
|
||||
})
|
||||
text += buzz_segment.text + " "
|
||||
|
||||
if SENTENCE_END.match(buzz_segment.text):
|
||||
segments.append({
|
||||
'text': text,
|
||||
'words': words
|
||||
})
|
||||
words = []
|
||||
text = ""
|
||||
|
||||
return {
|
||||
'language': self.transcription.language,
|
||||
'segments': segments
|
||||
}
|
||||
|
||||
def run(self):
|
||||
self.progress_update.emit(_("1/8 Collecting transcripts"))
|
||||
|
||||
# Step 1 - Get transcript
|
||||
# TODO - Add detected language to the transcript, detect and store separately in metadata
|
||||
# Will also be relevant for template parsing of transcript file names
|
||||
# - See diarize.py for example on how to get this info from whisper transcript, maybe other whisper models also have it
|
||||
language = self.transcription.language if self.transcription.language else "en"
|
||||
|
||||
segments = self.transcription_service.get_transcription_segments(
|
||||
transcription_id=self.transcription.id_as_uuid
|
||||
)
|
||||
|
||||
full_transcript = "".join(segment.text for segment in segments)
|
||||
|
||||
self.progress_update.emit(_("2/8 Loading audio"))
|
||||
audio_waveform = faster_whisper.decode_audio(self.transcription.file)
|
||||
|
||||
# Step 2 - Forced alignment
|
||||
force_cpu = os.getenv("BUZZ_FORCE_CPU", "false")
|
||||
use_cuda = torch.cuda.is_available() and force_cpu == "false"
|
||||
device = "cuda" if use_cuda else "cpu"
|
||||
torch_dtype = torch.float16 if use_cuda else torch.float32
|
||||
|
||||
self.progress_update.emit(_("3/8 Loading alignment model"))
|
||||
alignment_model, alignment_tokenizer = load_alignment_model(
|
||||
device,
|
||||
dtype=torch_dtype,
|
||||
)
|
||||
|
||||
self.progress_update.emit(_("4/8 Processing audio"))
|
||||
emissions, stride = generate_emissions(
|
||||
alignment_model,
|
||||
torch.from_numpy(audio_waveform)
|
||||
.to(alignment_model.dtype)
|
||||
.to(alignment_model.device),
|
||||
batch_size=8,
|
||||
)
|
||||
|
||||
del alignment_model
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
self.progress_update.emit(_("5/8 Preparing transcripts"))
|
||||
tokens_starred, text_starred = preprocess_text(
|
||||
full_transcript,
|
||||
romanize=True,
|
||||
language=langs_to_iso[language],
|
||||
)
|
||||
|
||||
segments, scores, blank_token = get_alignments(
|
||||
emissions,
|
||||
tokens_starred,
|
||||
alignment_tokenizer,
|
||||
)
|
||||
|
||||
spans = get_spans(tokens_starred, segments, blank_token)
|
||||
|
||||
word_timestamps = postprocess_results(text_starred, spans, stride, scores)
|
||||
|
||||
# Step 3 - Diarization
|
||||
self.progress_update.emit(_("6/8 Identifying speakers"))
|
||||
|
||||
try:
|
||||
diarizer_model = MSDDDiarizer(device)
|
||||
speaker_ts = diarizer_model.diarize(torch.from_numpy(audio_waveform).unsqueeze(0))
|
||||
|
||||
except Exception as e:
|
||||
self.progress_update.emit(_("0/0 Error identifying speakers"))
|
||||
logging.error(f"Error during diarization: {e}")
|
||||
return
|
||||
finally:
|
||||
del diarizer_model
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
# Step 4 - Reading timestamps <> Speaker Labels mapping
|
||||
self.progress_update.emit(_("7/8 Mapping speakers to transcripts"))
|
||||
|
||||
wsm = get_words_speaker_mapping(word_timestamps, speaker_ts, "start")
|
||||
|
||||
if language in punct_model_langs:
|
||||
# restoring punctuation in the transcript to help realign the sentences
|
||||
punct_model = PunctuationModel(model="kredor/punctuate-all")
|
||||
|
||||
words_list = list(map(lambda x: x["word"], wsm))
|
||||
|
||||
labled_words = punct_model.predict(words_list, chunk_size=230)
|
||||
|
||||
ending_puncts = ".?!。!?"
|
||||
model_puncts = ".,;:!?。!?"
|
||||
|
||||
# We don't want to punctuate U.S.A. with a period. Right?
|
||||
is_acronym = lambda x: re.fullmatch(r"\b(?:[a-zA-Z]\.){2,}", x)
|
||||
|
||||
for word_dict, labeled_tuple in zip(wsm, labled_words):
|
||||
word = word_dict["word"]
|
||||
if (
|
||||
word
|
||||
and labeled_tuple[1] in ending_puncts
|
||||
and (word[-1] not in model_puncts or is_acronym(word))
|
||||
):
|
||||
word += labeled_tuple[1]
|
||||
if word.endswith(".."):
|
||||
word = word.rstrip(".")
|
||||
word_dict["word"] = word
|
||||
|
||||
else:
|
||||
logging.warning(
|
||||
f"Punctuation restoration is not available for {language} language."
|
||||
" Using the original punctuation."
|
||||
)
|
||||
|
||||
wsm = get_realigned_ws_mapping_with_punctuation(wsm)
|
||||
ssm = get_sentences_speaker_mapping(wsm, speaker_ts)
|
||||
|
||||
self.progress_update.emit(_("8/8 Identification done"))
|
||||
self.finished.emit(ssm)
|
||||
|
||||
|
||||
class SpeakerIdentificationWidget(QWidget):
|
||||
resize_button_clicked = pyqtSignal()
|
||||
transcription: Transcription
|
||||
settings = Settings()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
transcription: Transcription,
|
||||
transcription_service: TranscriptionService,
|
||||
parent: Optional["QWidget"] = None,
|
||||
flags: Qt.WindowType = Qt.WindowType.Widget,
|
||||
transcriptions_updated_signal: Optional[pyqtSignal] = None,
|
||||
) -> None:
|
||||
super().__init__(parent, flags)
|
||||
self.transcription = transcription
|
||||
self.transcription_service = transcription_service
|
||||
self.transcriptions_updated_signal = transcriptions_updated_signal
|
||||
|
||||
self.identification_result = None
|
||||
|
||||
self.thread = None
|
||||
self.worker = None
|
||||
|
||||
self.setMinimumWidth(650)
|
||||
self.setMinimumHeight(400)
|
||||
|
||||
self.setWindowTitle(file_path_as_title(transcription.file))
|
||||
|
||||
layout = QFormLayout(self)
|
||||
layout.setSizeConstraint(QLayout.SizeConstraint.SetMinAndMaxSize)
|
||||
|
||||
# Step 1: Identify speakers
|
||||
step_1_label = QLabel(_("Step 1: Identify speakers"), self)
|
||||
font = step_1_label.font()
|
||||
font.setWeight(QFont.Weight.Bold)
|
||||
step_1_label.setFont(font)
|
||||
layout.addRow(step_1_label)
|
||||
|
||||
step_1_group_box = QGroupBox(self)
|
||||
step_1_group_box.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
step_1_layout = QVBoxLayout(step_1_group_box)
|
||||
|
||||
self.step_1_row = QHBoxLayout()
|
||||
|
||||
self.step_1_button = QPushButton(_("Identify"))
|
||||
self.step_1_button.setMinimumWidth(200)
|
||||
self.step_1_button.clicked.connect(self.on_identify_button_clicked)
|
||||
|
||||
# Progress container with label and bar
|
||||
progress_container = QVBoxLayout()
|
||||
|
||||
self.progress_label = QLabel(self)
|
||||
if os.path.isfile(self.transcription.file):
|
||||
self.progress_label.setText(_("Ready to identify speakers"))
|
||||
else:
|
||||
self.progress_label.setText(_("Audio file not found"))
|
||||
self.step_1_button.setEnabled(False)
|
||||
|
||||
self.progress_bar = QProgressBar(self)
|
||||
self.progress_bar.setMinimumWidth(400)
|
||||
self.progress_bar.setRange(0, 8)
|
||||
self.progress_bar.setValue(0)
|
||||
|
||||
progress_container.addWidget(self.progress_label)
|
||||
progress_container.addWidget(self.progress_bar)
|
||||
|
||||
self.step_1_row.addLayout(progress_container)
|
||||
|
||||
self.step_1_row.addWidget(self.step_1_button, alignment=Qt.AlignmentFlag.AlignTop)
|
||||
|
||||
step_1_layout.addLayout(self.step_1_row)
|
||||
|
||||
layout.addRow(step_1_group_box)
|
||||
|
||||
# Spacer
|
||||
spacer = QSpacerItem(0, 10, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
||||
layout.addItem(spacer)
|
||||
|
||||
# Step 2: Name speakers
|
||||
step_2_label = QLabel(_("Step 2: Name speakers"), self)
|
||||
font = step_2_label.font()
|
||||
font.setWeight(QFont.Weight.Bold)
|
||||
step_2_label.setFont(font)
|
||||
layout.addRow(step_2_label)
|
||||
|
||||
self.step_2_group_box = QGroupBox(self)
|
||||
self.step_2_group_box.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
|
||||
self.step_2_group_box.setEnabled(False)
|
||||
step_2_layout = QVBoxLayout(self.step_2_group_box)
|
||||
|
||||
self.speaker_preview_row = QVBoxLayout()
|
||||
|
||||
self.speaker_0_input = LineEdit("Speaker 0", self)
|
||||
|
||||
self.speaker_0_preview_button = QPushButton(_("Play sample"))
|
||||
self.speaker_0_preview_button.setMinimumWidth(200)
|
||||
self.speaker_0_preview_button.clicked.connect(lambda: self.on_speaker_preview("Speaker 0"))
|
||||
|
||||
speaker_0_layout = QHBoxLayout()
|
||||
speaker_0_layout.addWidget(self.speaker_0_input)
|
||||
speaker_0_layout.addWidget(self.speaker_0_preview_button)
|
||||
|
||||
self.speaker_preview_row.addLayout(speaker_0_layout)
|
||||
|
||||
step_2_layout.addLayout(self.speaker_preview_row)
|
||||
|
||||
layout.addRow(self.step_2_group_box)
|
||||
|
||||
# Save button
|
||||
self.merge_speaker_sentences = QCheckBox(_("Merge speaker sentences"))
|
||||
self.merge_speaker_sentences.setChecked(True)
|
||||
self.merge_speaker_sentences.setEnabled(False)
|
||||
self.merge_speaker_sentences.setMinimumWidth(250)
|
||||
|
||||
self.save_button = QPushButton(_("Save"))
|
||||
self.save_button.setEnabled(False)
|
||||
self.save_button.clicked.connect(self.on_save_button_clicked)
|
||||
|
||||
layout.addRow(self.merge_speaker_sentences)
|
||||
layout.addRow(self.save_button)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
# Invisible preview player
|
||||
url = QUrl.fromLocalFile(self.transcription.file)
|
||||
self.player = QMediaPlayer()
|
||||
self.audio_output = QAudioOutput()
|
||||
self.player.setAudioOutput(self.audio_output)
|
||||
self.player.setSource(url)
|
||||
self.player_timer = None
|
||||
|
||||
def on_identify_button_clicked(self):
|
||||
self.step_1_button.setEnabled(False)
|
||||
|
||||
self.thread = QThread()
|
||||
self.worker = IdentificationWorker(
|
||||
self.transcription,
|
||||
self.transcription_service
|
||||
)
|
||||
self.worker.moveToThread(self.thread)
|
||||
self.thread.started.connect(self.worker.run)
|
||||
self.worker.finished.connect(self.thread.quit)
|
||||
self.worker.finished.connect(self.worker.deleteLater)
|
||||
self.thread.finished.connect(self.thread.deleteLater)
|
||||
self.worker.finished.connect(self.on_identification_finished)
|
||||
self.worker.progress_update.connect(self.on_progress_update)
|
||||
|
||||
self.thread.start()
|
||||
|
||||
def on_progress_update(self, progress):
|
||||
self.progress_label.setText(progress)
|
||||
|
||||
progress_value = 0
|
||||
if progress and progress[0].isdigit():
|
||||
progress_value = int(progress[0])
|
||||
self.progress_bar.setValue(progress_value)
|
||||
else:
|
||||
logging.error(f"Invalid progress format: {progress}")
|
||||
|
||||
if progress_value == 8:
|
||||
self.step_2_group_box.setEnabled(True)
|
||||
self.merge_speaker_sentences.setEnabled(True)
|
||||
self.save_button.setEnabled(True)
|
||||
|
||||
def on_identification_finished(self, result):
|
||||
self.identification_result = result
|
||||
|
||||
unique_speakers = {entry['speaker'] for entry in result}
|
||||
|
||||
while self.speaker_preview_row.count():
|
||||
item = self.speaker_preview_row.takeAt(0)
|
||||
widget = item.widget()
|
||||
if widget:
|
||||
widget.deleteLater()
|
||||
else:
|
||||
layout = item.layout()
|
||||
if layout:
|
||||
while layout.count():
|
||||
sub_item = layout.takeAt(0)
|
||||
sub_widget = sub_item.widget()
|
||||
if sub_widget:
|
||||
sub_widget.deleteLater()
|
||||
|
||||
for speaker in sorted(unique_speakers):
|
||||
speaker_input = LineEdit(speaker, self)
|
||||
speaker_input.setMinimumWidth(200)
|
||||
|
||||
speaker_preview_button = QPushButton(_("Play sample"))
|
||||
speaker_preview_button.setMinimumWidth(200)
|
||||
speaker_preview_button.clicked.connect(lambda checked, s=speaker: self.on_speaker_preview(s))
|
||||
|
||||
speaker_layout = QHBoxLayout()
|
||||
speaker_layout.addWidget(speaker_input)
|
||||
speaker_layout.addWidget(speaker_preview_button)
|
||||
|
||||
self.speaker_preview_row.addLayout(speaker_layout)
|
||||
|
||||
def on_speaker_preview(self, speaker_id):
|
||||
if self.player_timer:
|
||||
self.player_timer.stop()
|
||||
|
||||
speaker_records = [record for record in self.identification_result if record['speaker'] == speaker_id]
|
||||
|
||||
if speaker_records:
|
||||
random_record = random.choice(speaker_records)
|
||||
|
||||
start_time = random_record['start_time']
|
||||
end_time = random_record['end_time']
|
||||
|
||||
self.player.setPosition(int(start_time))
|
||||
self.player.play()
|
||||
|
||||
self.player_timer = QTimer(self)
|
||||
self.player_timer.setSingleShot(True)
|
||||
self.player_timer.timeout.connect(self.player.stop)
|
||||
self.player_timer.start(min(end_time, 10 * 1000)) # 10 seconds
|
||||
|
||||
def on_save_button_clicked(self):
|
||||
speaker_names = []
|
||||
for i in range(self.speaker_preview_row.count()):
|
||||
item = self.speaker_preview_row.itemAt(i)
|
||||
if item.layout():
|
||||
for j in range(item.layout().count()):
|
||||
sub_item = item.layout().itemAt(j)
|
||||
widget = sub_item.widget()
|
||||
if isinstance(widget, LineEdit):
|
||||
speaker_names.append(widget.text())
|
||||
|
||||
unique_speakers = {entry['speaker'] for entry in self.identification_result}
|
||||
original_speakers = sorted(unique_speakers)
|
||||
speaker_mapping = dict(zip(original_speakers, speaker_names))
|
||||
|
||||
segments = []
|
||||
if self.merge_speaker_sentences.isChecked():
|
||||
previous_segment = None
|
||||
|
||||
for entry in self.identification_result:
|
||||
speaker_name = speaker_mapping.get(entry['speaker'], entry['speaker'])
|
||||
|
||||
if previous_segment and previous_segment['speaker'] == speaker_name:
|
||||
previous_segment['end_time'] = entry['end_time']
|
||||
previous_segment['text'] += " " + entry['text']
|
||||
else:
|
||||
if previous_segment:
|
||||
segment = Segment(
|
||||
start=previous_segment['start_time'],
|
||||
end=previous_segment['end_time'],
|
||||
text=f"{previous_segment['speaker']}: {previous_segment['text']}"
|
||||
)
|
||||
segments.append(segment)
|
||||
previous_segment = {
|
||||
'start_time': entry['start_time'],
|
||||
'end_time': entry['end_time'],
|
||||
'speaker': speaker_name,
|
||||
'text': entry['text']
|
||||
}
|
||||
|
||||
if previous_segment:
|
||||
segment = Segment(
|
||||
start=previous_segment['start_time'],
|
||||
end=previous_segment['end_time'],
|
||||
text=f"{previous_segment['speaker']}: {previous_segment['text']}"
|
||||
)
|
||||
segments.append(segment)
|
||||
else:
|
||||
for entry in self.identification_result:
|
||||
speaker_name = speaker_mapping.get(entry['speaker'], entry['speaker'])
|
||||
segment = Segment(
|
||||
start=entry['start_time'],
|
||||
end=entry['end_time'],
|
||||
text=f"{speaker_name}: {entry['text']}"
|
||||
)
|
||||
segments.append(segment)
|
||||
|
||||
new_transcript_id = self.transcription_service.copy_transcription(
|
||||
self.transcription.id_as_uuid
|
||||
)
|
||||
|
||||
self.transcription_service.update_transcription_as_completed(new_transcript_id, segments)
|
||||
|
||||
# TODO - See if we can get rows in the transcription viewer to be of variable height
|
||||
# If text is longer they should expand
|
||||
if self.transcriptions_updated_signal:
|
||||
self.transcriptions_updated_signal.emit(new_transcript_id)
|
||||
|
||||
self.player.stop()
|
||||
|
||||
if self.player_timer:
|
||||
self.player_timer.stop()
|
||||
|
||||
self.close()
|
||||
|
||||
def closeEvent(self, event):
|
||||
self.hide()
|
||||
|
||||
super().closeEvent(event)
|
||||
|
|
@ -37,8 +37,7 @@ from buzz.widgets.preferences_dialog.models.file_transcription_preferences impor
|
|||
SENTENCE_END = re.compile(r'.*[.!?。!?]')
|
||||
|
||||
class TranscriptionWorker(QObject):
|
||||
finished = pyqtSignal()
|
||||
result_ready = pyqtSignal(list)
|
||||
finished = pyqtSignal(list)
|
||||
|
||||
def __init__(self, transcription, transcription_options, transcription_service, regroup_string: str):
|
||||
super().__init__()
|
||||
|
|
@ -85,7 +84,7 @@ class TranscriptionWorker(QObject):
|
|||
if self.transcription_options.extract_speech and os.path.exists(speech_path):
|
||||
transcription_file = str(speech_path)
|
||||
transcription_file_exists = True
|
||||
# TODO - Fix VAD and Silence suppression that fails to work/download VAd model in compilded form on Mac and Windows
|
||||
# TODO - Fix VAD and Silence suppression that fails to work/download Vad model in compilded form on Mac and Windows
|
||||
|
||||
try:
|
||||
result = stable_whisper.transcribe_any(
|
||||
|
|
@ -113,8 +112,7 @@ class TranscriptionWorker(QObject):
|
|||
)
|
||||
)
|
||||
|
||||
self.result_ready.emit(segments)
|
||||
self.finished.emit()
|
||||
self.finished.emit(segments)
|
||||
|
||||
|
||||
class TranscriptionResizerWidget(QWidget):
|
||||
|
|
@ -336,7 +334,7 @@ class TranscriptionResizerWidget(QWidget):
|
|||
self.worker.finished.connect(self.thread.quit)
|
||||
self.worker.finished.connect(self.worker.deleteLater)
|
||||
self.thread.finished.connect(self.thread.deleteLater)
|
||||
self.worker.result_ready.connect(self.on_transcription_completed)
|
||||
self.worker.finished.connect(self.on_transcription_completed)
|
||||
|
||||
self.thread.start()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import logging
|
||||
import platform
|
||||
from typing import Optional
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -38,6 +39,7 @@ from buzz.widgets.icon import (
|
|||
ResizeIcon,
|
||||
ScrollToCurrentIcon,
|
||||
VisibilityIcon,
|
||||
SpeakerIdentificationIcon,
|
||||
)
|
||||
from buzz.translator import Translator
|
||||
from buzz.widgets.text_display_box import TextDisplayBox
|
||||
|
|
@ -59,6 +61,10 @@ from buzz.widgets.transcription_viewer.transcription_view_mode_tool_button impor
|
|||
)
|
||||
from buzz.widgets.transcription_viewer.transcription_resizer_widget import TranscriptionResizerWidget
|
||||
|
||||
# Underlying libs do not support intel Macs
|
||||
if not (platform.system() == "Darwin" and platform.machine() == "x86_64"):
|
||||
from buzz.widgets.transcription_viewer.speaker_identification_widget import SpeakerIdentificationWidget
|
||||
|
||||
|
||||
class TranscriptionViewerWidget(QWidget):
|
||||
resize_button_clicked = pyqtSignal()
|
||||
|
|
@ -85,6 +91,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.setWindowTitle(file_path_as_title(transcription.file))
|
||||
|
||||
self.transcription_resizer_dialog = None
|
||||
self.speaker_identification_dialog = None
|
||||
self.transcriptions_updated_signal = transcriptions_updated_signal
|
||||
|
||||
self.translation_thread = None
|
||||
|
|
@ -98,7 +105,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
# Loop functionality
|
||||
self.segment_looping_enabled = self.settings.settings.value("transcription_viewer/segment_looping_enabled", False, type=bool)
|
||||
|
||||
|
||||
# UI visibility preferences
|
||||
self.playback_controls_visible = self.settings.settings.value("transcription_viewer/playback_controls_visible", False, type=bool)
|
||||
self.find_widget_visible = self.settings.settings.value("transcription_viewer/find_widget_visible", False, type=bool)
|
||||
|
|
@ -165,18 +172,18 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Create a better current segment display that handles long text
|
||||
self.current_segment_frame = QFrame()
|
||||
self.current_segment_frame.setFrameStyle(QFrame.Shape.NoFrame)
|
||||
|
||||
|
||||
segment_layout = QVBoxLayout(self.current_segment_frame)
|
||||
segment_layout.setContentsMargins(4, 4, 4, 4) # Minimal margins for clean appearance
|
||||
segment_layout.setSpacing(0) # No spacing between elements
|
||||
|
||||
|
||||
# Text display - centered with scroll capability (no header label)
|
||||
self.current_segment_text = QLabel("")
|
||||
self.current_segment_text.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop)
|
||||
self.current_segment_text.setWordWrap(True)
|
||||
self.current_segment_text.setStyleSheet("color: #666; line-height: 1.2; margin: 0; padding: 4px;")
|
||||
self.current_segment_text.setMinimumHeight(60) # Ensure minimum height for text
|
||||
|
||||
|
||||
# Make it scrollable for long text
|
||||
self.current_segment_scroll_area = QScrollArea()
|
||||
self.current_segment_scroll_area.setWidget(self.current_segment_text)
|
||||
|
|
@ -185,13 +192,13 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.current_segment_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
||||
self.current_segment_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
|
||||
self.current_segment_scroll_area.setStyleSheet("QScrollBar:vertical { width: 12px; } QScrollBar::handle:vertical { background: #ccc; border-radius: 6px; }")
|
||||
|
||||
|
||||
# Ensure the text label can expand to show all content
|
||||
self.current_segment_text.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
|
||||
|
||||
|
||||
# Add scroll area to layout (simplified single-widget layout)
|
||||
segment_layout.addWidget(self.current_segment_scroll_area)
|
||||
|
||||
|
||||
# Initially hide the frame until there's content
|
||||
self.current_segment_frame.hide()
|
||||
|
||||
|
|
@ -247,6 +254,19 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
toolbar.addWidget(resize_button)
|
||||
|
||||
# Underlying libs do not support intel Macs
|
||||
if not (platform.system() == "Darwin" and platform.machine() == "x86_64"):
|
||||
speaker_identification_button = QToolButton()
|
||||
speaker_identification_button.setText(_("Identify Speakers"))
|
||||
speaker_identification_button.setObjectName("speaker_identification_button")
|
||||
speaker_identification_button.setIcon(SpeakerIdentificationIcon(self))
|
||||
speaker_identification_button.setToolButtonStyle(
|
||||
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
|
||||
)
|
||||
speaker_identification_button.clicked.connect(self.on_speaker_identification_button_clicked)
|
||||
|
||||
toolbar.addWidget(speaker_identification_button)
|
||||
|
||||
# Add Find button
|
||||
self.find_button = QToolButton()
|
||||
self.find_button.setText(_("Find"))
|
||||
|
|
@ -267,14 +287,14 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
# Table widget should take the majority of the space
|
||||
layout.addWidget(self.table_widget, 1) # Stretch factor 1 (majority)
|
||||
|
||||
|
||||
# Loop controls section (minimal space)
|
||||
self.create_loop_controls()
|
||||
layout.addWidget(self.loop_controls_frame, 0) # Stretch factor 0 (minimal)
|
||||
|
||||
|
||||
# Audio player (minimal space)
|
||||
layout.addWidget(self.audio_player, 0) # Stretch factor 0 (minimal)
|
||||
|
||||
|
||||
# Text display box (minimal space)
|
||||
layout.addWidget(self.text_display_box, 0) # Stretch factor 0 (minimal)
|
||||
|
||||
|
|
@ -291,7 +311,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
# Restore UI state from settings
|
||||
self.restore_ui_state()
|
||||
|
||||
|
||||
# Restore geometry from settings
|
||||
self.load_geometry()
|
||||
|
||||
|
|
@ -302,7 +322,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Restore playback controls visibility
|
||||
if self.playback_controls_visible:
|
||||
self.show_loop_controls()
|
||||
|
||||
|
||||
# Restore find widget visibility
|
||||
if self.find_widget_visible:
|
||||
self.show_search_bar()
|
||||
|
|
@ -312,28 +332,28 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.search_frame = QFrame()
|
||||
self.search_frame.setFrameStyle(QFrame.Shape.StyledPanel)
|
||||
self.search_frame.setMaximumHeight(60)
|
||||
|
||||
|
||||
search_layout = QHBoxLayout(self.search_frame)
|
||||
search_layout.setContentsMargins(10, 5, 10, 5)
|
||||
|
||||
|
||||
# Find label
|
||||
search_label = QLabel(_("Find:"))
|
||||
search_label.setStyleSheet("font-weight: bold;")
|
||||
search_layout.addWidget(search_label)
|
||||
|
||||
|
||||
# Find input - make it wider for better usability
|
||||
self.search_input = QLineEdit()
|
||||
self.search_input.setPlaceholderText(_("Enter text to find..."))
|
||||
self.search_input.textChanged.connect(self.on_search_text_changed)
|
||||
self.search_input.returnPressed.connect(self.search_next)
|
||||
self.search_input.setMinimumWidth(300) # Increased from 200 to 300
|
||||
|
||||
|
||||
# Add keyboard shortcuts for search navigation
|
||||
from PyQt6.QtGui import QKeySequence
|
||||
self.search_input.installEventFilter(self)
|
||||
|
||||
|
||||
search_layout.addWidget(self.search_input)
|
||||
|
||||
|
||||
# Search buttons - make them consistent height and remove hardcoded font sizes
|
||||
self.search_prev_button = QPushButton("↑")
|
||||
self.search_prev_button.setToolTip(_("Previous match (Shift+Enter)"))
|
||||
|
|
@ -342,7 +362,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.search_prev_button.setMaximumWidth(40)
|
||||
self.search_prev_button.setMinimumHeight(30) # Ensure consistent height
|
||||
search_layout.addWidget(self.search_prev_button)
|
||||
|
||||
|
||||
self.search_next_button = QPushButton("↓")
|
||||
self.search_next_button.setToolTip(_("Next match (Enter)"))
|
||||
self.search_next_button.clicked.connect(self.search_next)
|
||||
|
|
@ -350,21 +370,21 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.search_next_button.setMaximumWidth(40)
|
||||
self.search_next_button.setMinimumHeight(30) # Ensure consistent height
|
||||
search_layout.addWidget(self.search_next_button)
|
||||
|
||||
|
||||
# Clear button - make it bigger to accommodate different language translations
|
||||
self.clear_search_button = QPushButton(_("Clear"))
|
||||
self.clear_search_button.clicked.connect(self.clear_search)
|
||||
self.clear_search_button.setMaximumWidth(80) # Increased from 60 to 80
|
||||
self.clear_search_button.setMinimumHeight(30) # Ensure consistent height
|
||||
search_layout.addWidget(self.clear_search_button)
|
||||
|
||||
|
||||
# Results label
|
||||
self.search_results_label = QLabel("")
|
||||
self.search_results_label.setStyleSheet("color: #666;")
|
||||
search_layout.addWidget(self.search_results_label)
|
||||
|
||||
|
||||
search_layout.addStretch()
|
||||
|
||||
|
||||
# Initially hide the search bar
|
||||
self.search_frame.hide()
|
||||
|
||||
|
|
@ -373,23 +393,23 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.loop_controls_frame = QFrame()
|
||||
self.loop_controls_frame.setFrameStyle(QFrame.Shape.StyledPanel)
|
||||
self.loop_controls_frame.setMaximumHeight(50)
|
||||
|
||||
|
||||
loop_layout = QHBoxLayout(self.loop_controls_frame)
|
||||
loop_layout.setContentsMargins(10, 5, 10, 5)
|
||||
loop_layout.setSpacing(8) # Add some spacing between elements for better visual separation
|
||||
|
||||
|
||||
# Loop controls label
|
||||
loop_label = QLabel(_("Playback Controls:"))
|
||||
loop_label.setStyleSheet("font-weight: bold;")
|
||||
loop_layout.addWidget(loop_label)
|
||||
|
||||
|
||||
# Loop toggle button
|
||||
self.loop_toggle = QCheckBox(_("Loop Segment"))
|
||||
self.loop_toggle.setChecked(self.segment_looping_enabled)
|
||||
self.loop_toggle.setToolTip(_("Enable/disable looping when clicking on transcript segments"))
|
||||
self.loop_toggle.toggled.connect(self.on_loop_toggle_changed)
|
||||
loop_layout.addWidget(self.loop_toggle)
|
||||
|
||||
|
||||
# Follow audio toggle button
|
||||
self.follow_audio_enabled = self.settings.settings.value("transcription_viewer/follow_audio_enabled", False, type=bool)
|
||||
self.follow_audio_toggle = QCheckBox(_("Follow Audio"))
|
||||
|
|
@ -397,19 +417,19 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.follow_audio_toggle.setToolTip(_("Enable/disable following the current audio position in the transcript. When enabled, automatically scrolls to current text."))
|
||||
self.follow_audio_toggle.toggled.connect(self.on_follow_audio_toggle_changed)
|
||||
loop_layout.addWidget(self.follow_audio_toggle)
|
||||
|
||||
|
||||
# Visual separator
|
||||
separator1 = QFrame()
|
||||
separator1.setFrameShape(QFrame.Shape.VLine)
|
||||
separator1.setFrameShadow(QFrame.Shadow.Sunken)
|
||||
separator1.setMaximumHeight(20)
|
||||
loop_layout.addWidget(separator1)
|
||||
|
||||
|
||||
# Speed controls
|
||||
speed_label = QLabel("Speed:")
|
||||
speed_label.setStyleSheet("font-weight: bold;")
|
||||
loop_layout.addWidget(speed_label)
|
||||
|
||||
|
||||
self.speed_combo = QComboBox()
|
||||
self.speed_combo.setEditable(True)
|
||||
self.speed_combo.addItems(["0.5x", "0.75x", "1x", "1.25x", "1.5x", "2x"])
|
||||
|
|
@ -417,29 +437,29 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.speed_combo.currentTextChanged.connect(self.on_speed_changed)
|
||||
self.speed_combo.setMaximumWidth(80)
|
||||
loop_layout.addWidget(self.speed_combo)
|
||||
|
||||
|
||||
self.speed_down_btn = QPushButton("-")
|
||||
self.speed_down_btn.setMaximumWidth(40) # Match search button width
|
||||
self.speed_down_btn.setMinimumHeight(30) # Match search button height
|
||||
self.speed_down_btn.clicked.connect(self.decrease_speed)
|
||||
loop_layout.addWidget(self.speed_down_btn)
|
||||
|
||||
|
||||
self.speed_up_btn = QPushButton("+")
|
||||
self.speed_up_btn.setMaximumWidth(40) # Match speed down button width
|
||||
self.speed_up_btn.setMinimumHeight(30) # Match search button height
|
||||
self.speed_up_btn.clicked.connect(self.increase_speed)
|
||||
loop_layout.addWidget(self.speed_up_btn)
|
||||
|
||||
|
||||
# Initialize speed control with current value from audio player
|
||||
self.initialize_speed_control()
|
||||
|
||||
|
||||
# Visual separator
|
||||
separator2 = QFrame()
|
||||
separator2.setFrameShape(QFrame.Shape.VLine)
|
||||
separator2.setFrameShadow(QFrame.Shadow.Sunken)
|
||||
separator2.setMaximumHeight(20)
|
||||
loop_layout.addWidget(separator2)
|
||||
|
||||
|
||||
# Scroll to current button
|
||||
self.scroll_to_current_button = QPushButton(_("Scroll to Current"))
|
||||
self.scroll_to_current_button.setIcon(ScrollToCurrentIcon(self))
|
||||
|
|
@ -448,16 +468,16 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.scroll_to_current_button.setMinimumHeight(30)
|
||||
self.scroll_to_current_button.setStyleSheet("QPushButton { padding: 4px 8px; }") # Better padding
|
||||
loop_layout.addWidget(self.scroll_to_current_button)
|
||||
|
||||
|
||||
loop_layout.addStretch()
|
||||
|
||||
|
||||
# Initially hide the loop controls frame
|
||||
self.loop_controls_frame.hide()
|
||||
|
||||
def show_loop_controls(self):
|
||||
"""Show the loop controls when audio is playing"""
|
||||
self.loop_controls_frame.show()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.playback_controls_visible = True
|
||||
self.settings.settings.setValue("transcription_viewer/playback_controls_visible", self.playback_controls_visible)
|
||||
|
|
@ -465,7 +485,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
def hide_loop_controls(self):
|
||||
"""Hide the loop controls when audio is not playing"""
|
||||
self.loop_controls_frame.hide()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.playback_controls_visible = False
|
||||
self.settings.settings.setValue("transcription_viewer/playback_controls_visible", self.playback_controls_visible)
|
||||
|
|
@ -600,7 +620,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
def on_audio_playback_state_changed(self, state):
|
||||
"""Handle audio playback state changes to automatically show/hide playback controls"""
|
||||
from PyQt6.QtMultimedia import QMediaPlayer
|
||||
|
||||
|
||||
if state == QMediaPlayer.PlaybackState.PlayingState:
|
||||
# Show playback controls when audio starts playing
|
||||
if self.view_mode == ViewMode.TIMESTAMPS:
|
||||
|
|
@ -630,25 +650,25 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Extract the numeric value from speed text (e.g., "1.5x" -> 1.5)
|
||||
clean_text = speed_text.replace('x', '').strip()
|
||||
speed_value = float(clean_text)
|
||||
|
||||
|
||||
# Clamp the speed value to valid range
|
||||
speed_value = max(0.1, min(5.0, speed_value))
|
||||
|
||||
|
||||
# Update the combo box text to show the clamped value
|
||||
if not speed_text.endswith('x'):
|
||||
speed_text = f"{speed_value:.2f}x"
|
||||
|
||||
|
||||
# Block signals to prevent recursion
|
||||
self.speed_combo.blockSignals(True)
|
||||
self.speed_combo.setCurrentText(speed_text)
|
||||
self.speed_combo.blockSignals(False)
|
||||
|
||||
|
||||
# Set the playback rate on the audio player
|
||||
self.audio_player.media_player.setPlaybackRate(speed_value)
|
||||
|
||||
|
||||
# Save the new rate to settings
|
||||
self.settings.set_value(self.settings.Key.AUDIO_PLAYBACK_RATE, speed_value)
|
||||
|
||||
|
||||
except ValueError:
|
||||
logging.warning(f"Invalid speed value: {speed_text}")
|
||||
# Reset to current valid value
|
||||
|
|
@ -680,14 +700,14 @@ class TranscriptionViewerWidget(QWidget):
|
|||
"""Set the playback speed programmatically"""
|
||||
# Clamp the speed value to valid range
|
||||
speed = max(0.1, min(5.0, speed))
|
||||
|
||||
|
||||
# Update the combo box
|
||||
speed_text = f"{speed:.2f}x"
|
||||
self.speed_combo.setCurrentText(speed_text)
|
||||
|
||||
|
||||
# Set the playback rate on the audio player
|
||||
self.audio_player.media_player.setPlaybackRate(speed)
|
||||
|
||||
|
||||
# Save the new rate to settings
|
||||
self.settings.set_value(self.settings.Key.AUDIO_PLAYBACK_RATE, speed)
|
||||
|
||||
|
|
@ -707,49 +727,49 @@ class TranscriptionViewerWidget(QWidget):
|
|||
"""Perform the actual search based on current view mode"""
|
||||
self.search_results = []
|
||||
self.current_search_index = 0
|
||||
|
||||
|
||||
if self.view_mode == ViewMode.TIMESTAMPS:
|
||||
self.search_in_table()
|
||||
else: # TEXT or TRANSLATION mode
|
||||
self.search_in_text()
|
||||
|
||||
|
||||
self.update_search_ui()
|
||||
|
||||
def search_in_table(self):
|
||||
"""Search in the table view (segments)"""
|
||||
segments = self.table_widget.segments()
|
||||
search_text_lower = self.search_text.lower()
|
||||
|
||||
|
||||
# Limit search results to avoid performance issues with very long segments
|
||||
max_results = 100
|
||||
|
||||
|
||||
for i, segment in enumerate(segments):
|
||||
if len(self.search_results) >= max_results:
|
||||
break
|
||||
|
||||
|
||||
text = segment.value("text").lower()
|
||||
if search_text_lower in text:
|
||||
self.search_results.append(("table", i, segment))
|
||||
|
||||
|
||||
# Also search in translations if available
|
||||
if self.has_translations:
|
||||
for i, segment in enumerate(segments):
|
||||
if len(self.search_results) >= max_results:
|
||||
break
|
||||
|
||||
|
||||
translation = segment.value("translation").lower()
|
||||
if search_text_lower in translation:
|
||||
self.search_results.append(("table", i, segment))
|
||||
self.search_results.append(("table", i, segment))
|
||||
|
||||
def search_in_text(self):
|
||||
"""Search in the text display box"""
|
||||
text = self.text_display_box.toPlainText()
|
||||
search_text_lower = self.search_text.lower()
|
||||
text_lower = text.lower()
|
||||
|
||||
|
||||
# Limit search results to avoid performance issues with very long text
|
||||
max_results = 100
|
||||
|
||||
|
||||
start = 0
|
||||
result_count = 0
|
||||
while True:
|
||||
|
|
@ -780,9 +800,9 @@ class TranscriptionViewerWidget(QWidget):
|
|||
"""Highlight the current search match"""
|
||||
if not self.search_results:
|
||||
return
|
||||
|
||||
|
||||
match_type, match_data, _ = self.search_results[self.current_search_index]
|
||||
|
||||
|
||||
if match_type == "table":
|
||||
# Highlight in table
|
||||
self.highlight_table_match(match_data)
|
||||
|
|
@ -802,10 +822,10 @@ class TranscriptionViewerWidget(QWidget):
|
|||
cursor = QTextCursor(self.text_display_box.document())
|
||||
cursor.setPosition(start_pos)
|
||||
cursor.setPosition(start_pos + len(self.search_text), QTextCursor.MoveMode.KeepAnchor)
|
||||
|
||||
|
||||
# Set the cursor to highlight the text
|
||||
self.text_display_box.setTextCursor(cursor)
|
||||
|
||||
|
||||
# Ensure the highlighted text is visible
|
||||
self.text_display_box.ensureCursorVisible()
|
||||
|
||||
|
|
@ -813,7 +833,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
"""Go to next search result"""
|
||||
if not self.search_results:
|
||||
return
|
||||
|
||||
|
||||
self.current_search_index = (self.current_search_index + 1) % len(self.search_results)
|
||||
self.highlight_current_match()
|
||||
self.update_search_results_label()
|
||||
|
|
@ -822,7 +842,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
"""Go to previous search result"""
|
||||
if not self.search_results:
|
||||
return
|
||||
|
||||
|
||||
self.current_search_index = (self.current_search_index - 1) % len(self.search_results)
|
||||
self.highlight_current_match()
|
||||
self.update_search_results_label()
|
||||
|
|
@ -845,13 +865,13 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
self.search_prev_button.setEnabled(False)
|
||||
self.search_next_button.setEnabled(False)
|
||||
|
||||
|
||||
# Clear text highlighting
|
||||
if self.view_mode in (ViewMode.TEXT, ViewMode.TRANSLATION):
|
||||
cursor = QTextCursor(self.text_display_box.document())
|
||||
cursor.clearSelection()
|
||||
self.text_display_box.setTextCursor(cursor)
|
||||
|
||||
|
||||
# Keep search bar visible but clear the input
|
||||
self.search_input.setFocus()
|
||||
|
||||
|
|
@ -861,7 +881,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.find_button.setChecked(False) # Sync button state
|
||||
self.clear_search()
|
||||
self.search_input.clearFocus()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.find_widget_visible = False
|
||||
self.settings.settings.setValue("transcription_viewer/find_widget_visible", False)
|
||||
|
|
@ -869,11 +889,11 @@ class TranscriptionViewerWidget(QWidget):
|
|||
def setup_shortcuts(self):
|
||||
"""Set up keyboard shortcuts"""
|
||||
from PyQt6.QtGui import QShortcut, QKeySequence
|
||||
|
||||
|
||||
# Search shortcut (Ctrl+F)
|
||||
search_shortcut = QShortcut(QKeySequence(self.shortcuts.get(Shortcut.SEARCH_TRANSCRIPT)), self)
|
||||
search_shortcut.activated.connect(self.focus_search_input)
|
||||
|
||||
|
||||
# Scroll to current text shortcut (Ctrl+G)
|
||||
scroll_to_current_shortcut = QShortcut(QKeySequence(self.shortcuts.get(Shortcut.SCROLL_TO_CURRENT_TEXT)), self)
|
||||
scroll_to_current_shortcut.activated.connect(self.on_scroll_to_current_button_clicked)
|
||||
|
|
@ -912,7 +932,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.find_button.setChecked(True) # Sync button state
|
||||
self.search_input.setFocus()
|
||||
self.search_input.selectAll()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.find_widget_visible = True
|
||||
self.settings.settings.setValue("transcription_viewer/find_widget_visible", True)
|
||||
|
|
@ -923,7 +943,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.hide_search_bar()
|
||||
else:
|
||||
self.show_search_bar()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.find_widget_visible = self.search_frame.isVisible()
|
||||
self.settings.settings.setValue("transcription_viewer/find_widget_visible", self.find_widget_visible)
|
||||
|
|
@ -934,7 +954,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.find_button.setChecked(True)
|
||||
self.search_input.setFocus()
|
||||
self.search_input.selectAll()
|
||||
|
||||
|
||||
# Save the visibility state to settings
|
||||
self.find_widget_visible = True
|
||||
self.settings.settings.setValue("transcription_viewer/find_widget_visible", True)
|
||||
|
|
@ -942,7 +962,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
def eventFilter(self, obj, event):
|
||||
"""Event filter to handle keyboard shortcuts in search input"""
|
||||
from PyQt6.QtCore import QEvent, Qt
|
||||
|
||||
|
||||
if obj == self.search_input and event.type() == QEvent.Type.KeyPress:
|
||||
# The event is already a QKeyEvent, no need to create a new one
|
||||
if event.key() == Qt.Key.Key_Return and event.modifiers() == Qt.KeyboardModifier.ShiftModifier:
|
||||
|
|
@ -999,7 +1019,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.loop_controls_frame.hide()
|
||||
# Hide current segment display in translation mode
|
||||
self.current_segment_frame.hide()
|
||||
|
||||
|
||||
# Refresh search if there's active search text
|
||||
if self.search_text:
|
||||
self.perform_search()
|
||||
|
|
@ -1007,7 +1027,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
def on_view_mode_changed(self, view_mode: ViewMode) -> None:
|
||||
self.view_mode = view_mode
|
||||
self.reset_view()
|
||||
|
||||
|
||||
# Refresh search if there's active search text
|
||||
if self.search_text:
|
||||
self.perform_search()
|
||||
|
|
@ -1091,17 +1111,17 @@ class TranscriptionViewerWidget(QWidget):
|
|||
if current_segment is not None:
|
||||
self.current_segment_text.setText(current_segment.value("text"))
|
||||
self.current_segment_frame.show() # Show the frame when there's a current segment
|
||||
|
||||
|
||||
# Force the text label to recalculate its size
|
||||
self.current_segment_text.adjustSize()
|
||||
|
||||
|
||||
# Resize the frame to fit the text content
|
||||
self.resize_current_segment_frame()
|
||||
|
||||
|
||||
# Ensure the scroll area updates properly and shows scrollbars when needed
|
||||
self.current_segment_scroll_area.updateGeometry()
|
||||
self.current_segment_scroll_area.verticalScrollBar().setVisible(True) # Ensure scrollbar is visible
|
||||
|
||||
|
||||
# Update highlighting based on follow audio and loop settings
|
||||
if self.follow_audio_enabled:
|
||||
# Follow audio mode: highlight the current segment based on audio position
|
||||
|
|
@ -1143,30 +1163,30 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Calculate the height needed for the text area
|
||||
line_height = self.current_segment_text.fontMetrics().lineSpacing()
|
||||
max_visible_lines = 3 # Fixed at 3 lines for consistency and clean UI
|
||||
|
||||
|
||||
# Calculate the height needed for the maximum visible lines (25% larger)
|
||||
text_height = line_height * max_visible_lines * 1.25
|
||||
|
||||
|
||||
# Add some vertical margins/padding
|
||||
margins = 8 # Increased from 2 to 8 for better spacing
|
||||
|
||||
|
||||
# Calculate total height needed (no header height anymore)
|
||||
total_height = text_height + margins
|
||||
|
||||
|
||||
# Convert to integer since Qt methods expect int values
|
||||
total_height = int(total_height)
|
||||
|
||||
|
||||
# Set maximum height to ensure consistent sizing, but allow minimum to be flexible
|
||||
self.current_segment_frame.setMaximumHeight(total_height)
|
||||
self.current_segment_frame.setMinimumHeight(total_height)
|
||||
|
||||
|
||||
# Convert text_height to integer since Qt methods expect int values
|
||||
text_height = int(text_height)
|
||||
|
||||
|
||||
# Allow the scroll area to be flexible in height for proper scrolling
|
||||
self.current_segment_scroll_area.setMinimumHeight(text_height)
|
||||
self.current_segment_scroll_area.setMaximumHeight(text_height)
|
||||
|
||||
|
||||
# Allow the text label to size naturally for proper scrolling
|
||||
self.current_segment_text.setMinimumHeight(text_height)
|
||||
|
||||
|
|
@ -1220,12 +1240,27 @@ class TranscriptionViewerWidget(QWidget):
|
|||
|
||||
self.transcription_resizer_dialog.show()
|
||||
|
||||
def on_speaker_identification_button_clicked(self):
|
||||
# Underlying libs do not support intel Macs
|
||||
if not (platform.system() == "Darwin" and platform.machine() == "x86_64"):
|
||||
self.speaker_identification_dialog = SpeakerIdentificationWidget(
|
||||
transcription=self.transcription,
|
||||
transcription_service=self.transcription_service,
|
||||
transcriptions_updated_signal=self.transcriptions_updated_signal,
|
||||
)
|
||||
|
||||
self.transcriptions_updated_signal.connect(self.close)
|
||||
|
||||
self.speaker_identification_dialog.show()
|
||||
|
||||
pass
|
||||
|
||||
def on_loop_toggle_changed(self, enabled: bool):
|
||||
"""Handle loop toggle state change"""
|
||||
self.segment_looping_enabled = enabled
|
||||
# Save preference to settings
|
||||
self.settings.settings.setValue("transcription_viewer/segment_looping_enabled", enabled)
|
||||
|
||||
|
||||
if enabled:
|
||||
# If looping is re-enabled and we have a selected segment, return to it
|
||||
if self.currently_selected_segment is not None:
|
||||
|
|
@ -1235,21 +1270,21 @@ class TranscriptionViewerWidget(QWidget):
|
|||
if segment.value("id") == self.currently_selected_segment.value("id"):
|
||||
# Highlight and scroll to the selected segment
|
||||
self.table_widget.highlight_and_scroll_to_row(i)
|
||||
|
||||
|
||||
# Get the segment timing
|
||||
start_time = self.currently_selected_segment.value("start_time")
|
||||
end_time = self.currently_selected_segment.value("end_time")
|
||||
|
||||
|
||||
# Set the loop range for the selected segment
|
||||
self.audio_player.set_range((start_time, end_time))
|
||||
|
||||
|
||||
# If audio is currently playing and outside the range, jump to the start
|
||||
current_pos = self.audio_player.position_ms
|
||||
playback_state = self.audio_player.media_player.playbackState()
|
||||
if (playback_state == QMediaPlayer.PlaybackState.PlayingState and
|
||||
if (playback_state == QMediaPlayer.PlaybackState.PlayingState and
|
||||
(current_pos < start_time or current_pos > end_time)):
|
||||
self.audio_player.set_position(start_time)
|
||||
|
||||
|
||||
break
|
||||
else:
|
||||
# Clear any existing range if looping is disabled
|
||||
|
|
@ -1260,7 +1295,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
self.follow_audio_enabled = enabled
|
||||
# Save preference to settings
|
||||
self.settings.settings.setValue("transcription_viewer/follow_audio_enabled", enabled)
|
||||
|
||||
|
||||
if enabled:
|
||||
# When follow audio is first enabled, automatically scroll to current position
|
||||
# This gives immediate feedback that the feature is working
|
||||
|
|
@ -1310,17 +1345,17 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Only scroll if we're in timestamps view mode (table is visible)
|
||||
if self.view_mode != ViewMode.TIMESTAMPS:
|
||||
return
|
||||
|
||||
|
||||
current_pos = self.audio_player.position_ms
|
||||
segments = self.table_widget.segments()
|
||||
|
||||
|
||||
# Find the current segment based on audio position
|
||||
current_segment = next(
|
||||
(segment for segment in segments
|
||||
(segment for segment in segments
|
||||
if segment.value("start_time") <= current_pos < segment.value("end_time")),
|
||||
None
|
||||
)
|
||||
|
||||
|
||||
if current_segment is not None:
|
||||
# Find the row index and scroll to it
|
||||
for i, segment in enumerate(segments):
|
||||
|
|
@ -1329,7 +1364,7 @@ class TranscriptionViewerWidget(QWidget):
|
|||
# Method 1: Use the table widget's built-in scrolling method
|
||||
self.table_widget.highlight_and_scroll_to_row(i)
|
||||
break
|
||||
|
||||
|
||||
except Exception as e:
|
||||
pass # Silently handle any errors
|
||||
|
||||
|
|
@ -1346,6 +1381,9 @@ class TranscriptionViewerWidget(QWidget):
|
|||
if self.transcription_resizer_dialog:
|
||||
self.transcription_resizer_dialog.close()
|
||||
|
||||
if self.speaker_identification_dialog:
|
||||
self.speaker_identification_dialog.close()
|
||||
|
||||
self.translator.stop()
|
||||
self.translation_thread.quit()
|
||||
|
||||
|
|
|
|||
1
ctc_forced_aligner
Submodule
1
ctc_forced_aligner
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1f0a5f860d3d9daf3d94edb1c7d18f90d1702e5b
|
||||
1
deepmultilingualpunctuation
Submodule
1
deepmultilingualpunctuation
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 5a0dd7f4fd56687f59405aa8eba1144393d8b74b
|
||||
33
demucs/.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
33
demucs/.github/ISSUE_TEMPLATE/bug.md
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
name: 🐛 Bug Report
|
||||
about: Submit a bug report to help us improve
|
||||
labels: 'bug'
|
||||
---
|
||||
|
||||
## 🐛 Bug Report
|
||||
|
||||
(A clear and concise description of what the bug is)
|
||||
|
||||
## To Reproduce
|
||||
|
||||
(Write your steps here:)
|
||||
|
||||
1. Step 1...
|
||||
1. Step 2...
|
||||
1. Step 3...
|
||||
|
||||
## Expected behavior
|
||||
|
||||
(Write what you thought would happen.)
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
(Write what happened. Add screenshots, if applicable.)
|
||||
|
||||
## Your Environment
|
||||
|
||||
<!-- Include as many relevant details about the environment you experienced the bug in -->
|
||||
|
||||
- Python and PyTorch version:
|
||||
- Operating system and version (desktop or mobile):
|
||||
- Hardware (gpu or cpu, amount of RAM etc.):
|
||||
10
demucs/.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
10
demucs/.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: "❓Questions/Help/Support"
|
||||
about: If you have a question about the paper, code or algorithm, please ask here!
|
||||
labels: question
|
||||
|
||||
---
|
||||
|
||||
## ❓ Questions
|
||||
|
||||
(Please ask your question here.)
|
||||
36
demucs/.github/workflows/linter.yml
vendored
Normal file
36
demucs/.github/workflows/linter.yml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: linter
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'facebookresearch/demucs' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: env
|
||||
key: env-${{ hashFiles('**/requirements.txt', '.github/workflows/*') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python3 -m venv env
|
||||
. env/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install '.[dev]'
|
||||
|
||||
|
||||
- name: Run linter
|
||||
run: |
|
||||
. env/bin/activate
|
||||
make linter
|
||||
36
demucs/.github/workflows/tests.yml
vendored
Normal file
36
demucs/.github/workflows/tests.yml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
name: tests
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'facebookresearch/demucs' || github.event_name == 'workflow_dispatch' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: env
|
||||
key: env-${{ hashFiles('**/requirements.txt', '.github/workflows/*') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ffmpeg
|
||||
python3 -m venv env
|
||||
. env/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Run separation test
|
||||
run: |
|
||||
. env/bin/activate
|
||||
make test_eval
|
||||
17
demucs/.gitignore
vendored
Normal file
17
demucs/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
*.egg-info
|
||||
__pycache__
|
||||
Session.vim
|
||||
/build
|
||||
/dist
|
||||
/lab
|
||||
/metadata
|
||||
/notebooks
|
||||
/outputs
|
||||
/release
|
||||
/release_models
|
||||
/separated
|
||||
/tests
|
||||
/trash
|
||||
/misc
|
||||
/mdx
|
||||
.mypy_cache
|
||||
76
demucs/CODE_OF_CONDUCT.md
Normal file
76
demucs/CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at <opensource-conduct@fb.com>. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
23
demucs/CONTRIBUTING.md
Normal file
23
demucs/CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Contributing to Demucs
|
||||
|
||||
## Pull Requests
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need
|
||||
to do this once to work on any of Facebook's open source projects.
|
||||
|
||||
Complete your CLA here: <https://code.facebook.com/cla>
|
||||
|
||||
Demucs is the implementation of a research paper.
|
||||
Therefore, we do not plan on accepting many pull requests for new features.
|
||||
We certainly welcome them for bug fixes.
|
||||
|
||||
|
||||
## Issues
|
||||
|
||||
We use GitHub issues to track public bugs. Please ensure your description is
|
||||
clear and has sufficient instructions to be able to reproduce the issue.
|
||||
|
||||
|
||||
## License
|
||||
By contributing to this repository, you agree that your contributions will be licensed
|
||||
under the LICENSE file in the root directory of this source tree.
|
||||
153
demucs/Demucs.ipynb
Normal file
153
demucs/Demucs.ipynb
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"colab_type": "text",
|
||||
"id": "Be9yoh-ILfRr"
|
||||
},
|
||||
"source": [
|
||||
"# Hybrid Demucs\n",
|
||||
"\n",
|
||||
"Feel free to use the Colab version:\n",
|
||||
"https://colab.research.google.com/drive/1dC9nVxk3V_VPjUADsnFu8EiT-xnU1tGH?usp=sharing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 139
|
||||
},
|
||||
"colab_type": "code",
|
||||
"executionInfo": {
|
||||
"elapsed": 12277,
|
||||
"status": "ok",
|
||||
"timestamp": 1583778134659,
|
||||
"user": {
|
||||
"displayName": "Marllus Lustosa",
|
||||
"photoUrl": "https://lh3.googleusercontent.com/a-/AOh14GgLl2RbW64ZyWz3Y8IBku0zhHCMnt7fz7fEl0LTdA=s64",
|
||||
"userId": "14811735256675200480"
|
||||
},
|
||||
"user_tz": 180
|
||||
},
|
||||
"id": "kOjIPLlzhPfn",
|
||||
"outputId": "c75f17ec-b576-4105-bc5b-c2ac9c1018a3"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -U demucs\n",
|
||||
"# or for local development, if you have a clone of Demucs\n",
|
||||
"# pip install -e ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {},
|
||||
"colab_type": "code",
|
||||
"id": "5lYOzKKCKAbJ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# You can use the `demucs` command line to separate tracks\n",
|
||||
"!demucs test.mp3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# You can also load directly the pretrained models,\n",
|
||||
"# for instance for the MDX 2021 winning model of Track A:\n",
|
||||
"from demucs import pretrained\n",
|
||||
"model = pretrained.get_model('mdx')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Because `model` is a bag of 4 models, you cannot directly call it on your data,\n",
|
||||
"# but the `apply_model` will know what to do of it.\n",
|
||||
"import torch\n",
|
||||
"from demucs.apply import apply_model\n",
|
||||
"x = torch.randn(1, 2, 44100 * 10) # ten seconds of white noise for the demo\n",
|
||||
"out = apply_model(model, x)[0] # shape is [S, C, T] with S the number of sources\n",
|
||||
"\n",
|
||||
"# So let see, where is all the white noise content is going ?\n",
|
||||
"for name, source in zip(model.sources, out):\n",
|
||||
" print(name, source.std() / x.std())\n",
|
||||
"# The outputs are quite weird to be fair, not what I would have expected."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# now let's take a single model from the bag, and let's test it on a pure cosine\n",
|
||||
"freq = 440 # in Hz\n",
|
||||
"sr = model.samplerate\n",
|
||||
"t = torch.arange(10 * sr).float() / sr\n",
|
||||
"x = torch.cos(2 * 3.1416 * freq * t).expand(1, 2, -1)\n",
|
||||
"sub_model = model.models[3]\n",
|
||||
"out = sub_model(x)[0]\n",
|
||||
"\n",
|
||||
"# Same question where does it go?\n",
|
||||
"for name, source in zip(model.sources, out):\n",
|
||||
" print(name, source.std() / x.std())\n",
|
||||
" \n",
|
||||
"# Well now it makes much more sense, all the energy is going\n",
|
||||
"# in the `other` source.\n",
|
||||
"# Feel free to try lower pitch (try 80 Hz) to see what happens !"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# For training or more fun, refer to the Demucs README on our repo\n",
|
||||
"# https://github.com/facebookresearch/demucs/tree/main/demucs"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"accelerator": "GPU",
|
||||
"colab": {
|
||||
"authorship_tag": "ABX9TyM9xpVr1M86NRcjtQ7g9tCx",
|
||||
"collapsed_sections": [],
|
||||
"name": "Demucs.ipynb",
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
||||
21
demucs/LICENSE
Normal file
21
demucs/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
13
demucs/MANIFEST.in
Normal file
13
demucs/MANIFEST.in
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
recursive-exclude env *
|
||||
recursive-include conf *.yaml
|
||||
include Makefile
|
||||
include LICENSE
|
||||
include demucs.png
|
||||
include outputs.tar.gz
|
||||
include test.mp3
|
||||
include requirements.txt
|
||||
include requirements_minimal.txt
|
||||
include mypy.ini
|
||||
include demucs/py.typed
|
||||
include demucs/remote/*.txt
|
||||
include demucs/remote/*.yaml
|
||||
36
demucs/Makefile
Normal file
36
demucs/Makefile
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
all: linter tests
|
||||
|
||||
linter:
|
||||
flake8 demucs
|
||||
mypy demucs
|
||||
|
||||
tests: test_train test_eval
|
||||
|
||||
test_train: tests/musdb
|
||||
_DORA_TEST_PATH=/tmp/demucs python3 -m dora run --clear \
|
||||
dset.musdb=./tests/musdb dset.segment=4 dset.shift=2 epochs=2 model=demucs \
|
||||
demucs.depth=2 demucs.channels=4 test.sdr=false misc.num_workers=0 test.workers=0 \
|
||||
test.shifts=0
|
||||
|
||||
test_eval:
|
||||
python3 -m demucs -n demucs_unittest test.mp3
|
||||
python3 -m demucs -n demucs_unittest --two-stems=vocals test.mp3
|
||||
python3 -m demucs -n demucs_unittest --mp3 test.mp3
|
||||
python3 -m demucs -n demucs_unittest --flac --int24 test.mp3
|
||||
python3 -m demucs -n demucs_unittest --int24 --clip-mode clamp test.mp3
|
||||
python3 -m demucs -n demucs_unittest --segment 8 test.mp3
|
||||
python3 -m demucs.api -n demucs_unittest --segment 8 test.mp3
|
||||
python3 -m demucs --list-models
|
||||
|
||||
tests/musdb:
|
||||
test -e tests || mkdir tests
|
||||
python3 -c 'import musdb; musdb.DB("tests/tmp", download=True)'
|
||||
musdbconvert tests/tmp tests/musdb
|
||||
|
||||
dist:
|
||||
python3 setup.py sdist
|
||||
|
||||
clean:
|
||||
rm -r dist build *.egg-info
|
||||
|
||||
.PHONY: linter dist test_train test_eval
|
||||
319
demucs/README.md
Normal file
319
demucs/README.md
Normal file
|
|
@ -0,0 +1,319 @@
|
|||
# Demucs Music Source Separation
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
**This is the officially maintained Demucs** now that I (Alexandre Défossez) have left Meta to join [Kyutai](https://twitter.com/kyutai_labs).
|
||||
Note that I'm not actively working on Demucs anymore, so expect slow replies and no new feature for now.
|
||||
|
||||
|
||||
|
||||
This is the 4th release of Demucs (v4), featuring Hybrid Transformer based source separation.
|
||||
**For the classic Hybrid Demucs (v3):** [Go this commit][demucs_v3].
|
||||
If you are experiencing issues and want the old Demucs back, please file an issue, and then you can get back to Demucs v3 with
|
||||
`git checkout v3`. You can also go [Demucs v2][demucs_v2].
|
||||
|
||||
|
||||
Demucs is a state-of-the-art music source separation model, currently capable of separating
|
||||
drums, bass, and vocals from the rest of the accompaniment.
|
||||
Demucs is based on a U-Net convolutional architecture inspired by [Wave-U-Net][waveunet].
|
||||
The v4 version features [Hybrid Transformer Demucs][htdemucs], a hybrid spectrogram/waveform separation model using Transformers.
|
||||
It is based on [Hybrid Demucs][hybrid_paper] (also provided in this repo), with the innermost layers
|
||||
replaced by a cross-domain Transformer Encoder. This Transformer uses self-attention within each domain,
|
||||
and cross-attention across domains.
|
||||
The model achieves a SDR of 9.00 dB on the MUSDB HQ test set. Moreover, when using sparse attention
|
||||
kernels to extend its receptive field and per source fine-tuning, we achieve state-of-the-art 9.20 dB of SDR.
|
||||
|
||||
Samples are available [on our sample page](https://ai.honu.io/papers/htdemucs/index.html).
|
||||
Checkout [our paper][htdemucs] for more information.
|
||||
It has been trained on the [MUSDB HQ][musdb] dataset + an extra training dataset of 800 songs.
|
||||
This model separates drums, bass and vocals and other stems for any song.
|
||||
|
||||
|
||||
As Hybrid Transformer Demucs is brand new, it is not activated by default, you can activate it in the usual
|
||||
commands described hereafter with `-n htdemucs_ft`.
|
||||
The single, non fine-tuned model is provided as `-n htdemucs`, and the retrained baseline
|
||||
as `-n hdemucs_mmi`. The Sparse Hybrid Transformer model decribed in our paper is not provided as its
|
||||
requires custom CUDA code that is not ready for release yet.
|
||||
We are also releasing an experimental 6 sources model, that adds a `guitar` and `piano` source.
|
||||
Quick testing seems to show okay quality for `guitar`, but a lot of bleeding and artifacts for the `piano` source.
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="./demucs.png" alt="Schema representing the structure of Hybrid Transformer Demucs,
|
||||
with a dual U-Net structure, one branch for the temporal domain,
|
||||
and one branch for the spectral domain. There is a cross-domain Transformer between the Encoders and Decoders."
|
||||
width="800px"></p>
|
||||
|
||||
|
||||
|
||||
## Important news if you are already using Demucs
|
||||
|
||||
See the [release notes](./docs/release.md) for more details.
|
||||
|
||||
- 22/02/2023: added support for the [SDX 2023 Challenge](https://www.aicrowd.com/challenges/sound-demixing-challenge-2023),
|
||||
see the dedicated [doc page](./docs/sdx23.md)
|
||||
- 07/12/2022: Demucs v4 now on PyPI. **htdemucs** model now used by default. Also releasing
|
||||
a 6 sources models (adding `guitar` and `piano`, although the latter doesn't work so well at the moment).
|
||||
- 16/11/2022: Added the new **Hybrid Transformer Demucs v4** models.
|
||||
Adding support for the [torchaudio implementation of HDemucs](https://pytorch.org/audio/stable/tutorials/hybrid_demucs_tutorial.html).
|
||||
- 30/08/2022: added reproducibility and ablation grids, along with an updated version of the paper.
|
||||
- 17/08/2022: Releasing v3.0.5: Set split segment length to reduce memory. Compatible with pyTorch 1.12.
|
||||
- 24/02/2022: Releasing v3.0.4: split into two stems (i.e. karaoke mode).
|
||||
Export as float32 or int24.
|
||||
- 17/12/2021: Releasing v3.0.3: bug fixes (thanks @keunwoochoi), memory drastically
|
||||
reduced on GPU (thanks @famzah) and new multi-core evaluation on CPU (`-j` flag).
|
||||
- 12/11/2021: Releasing **Demucs v3** with hybrid domain separation. Strong improvements
|
||||
on all sources. This is the model that won Sony MDX challenge.
|
||||
- 11/05/2021: Adding support for MusDB-HQ and arbitrary wav set, for the MDX challenge. For more information
|
||||
on joining the challenge with Demucs see [the Demucs MDX instructions](docs/mdx.md)
|
||||
|
||||
|
||||
## Comparison with other models
|
||||
|
||||
We provide hereafter a summary of the different metrics presented in the paper.
|
||||
You can also compare Hybrid Demucs (v3), [KUIELAB-MDX-Net][kuielab], [Spleeter][spleeter], Open-Unmix, Demucs (v1), and Conv-Tasnet on one of my favorite
|
||||
songs on my [soundcloud playlist][soundcloud].
|
||||
|
||||
### Comparison of accuracy
|
||||
|
||||
`Overall SDR` is the mean of the SDR for each of the 4 sources, `MOS Quality` is a rating from 1 to 5
|
||||
of the naturalness and absence of artifacts given by human listeners (5 = no artifacts), `MOS Contamination`
|
||||
is a rating from 1 to 5 with 5 being zero contamination by other sources. We refer the reader to our [paper][hybrid_paper],
|
||||
for more details.
|
||||
|
||||
| Model | Domain | Extra data? | Overall SDR | MOS Quality | MOS Contamination |
|
||||
|------------------------------|-------------|-------------------|-------------|-------------|-------------------|
|
||||
| [Wave-U-Net][waveunet] | waveform | no | 3.2 | - | - |
|
||||
| [Open-Unmix][openunmix] | spectrogram | no | 5.3 | - | - |
|
||||
| [D3Net][d3net] | spectrogram | no | 6.0 | - | - |
|
||||
| [Conv-Tasnet][demucs_v2] | waveform | no | 5.7 | - | |
|
||||
| [Demucs (v2)][demucs_v2] | waveform | no | 6.3 | 2.37 | 2.36 |
|
||||
| [ResUNetDecouple+][decouple] | spectrogram | no | 6.7 | - | - |
|
||||
| [KUIELAB-MDX-Net][kuielab] | hybrid | no | 7.5 | **2.86** | 2.55 |
|
||||
| [Band-Spit RNN][bandsplit] | spectrogram | no | **8.2** | - | - |
|
||||
| **Hybrid Demucs (v3)** | hybrid | no | 7.7 | **2.83** | **3.04** |
|
||||
| [MMDenseLSTM][mmdenselstm] | spectrogram | 804 songs | 6.0 | - | - |
|
||||
| [D3Net][d3net] | spectrogram | 1.5k songs | 6.7 | - | - |
|
||||
| [Spleeter][spleeter] | spectrogram | 25k songs | 5.9 | - | - |
|
||||
| [Band-Spit RNN][bandsplit] | spectrogram | 1.7k (mixes only) | **9.0** | - | - |
|
||||
| **HT Demucs f.t. (v4)** | hybrid | 800 songs | **9.0** | - | - |
|
||||
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
You will need at least Python 3.8. See `requirements_minimal.txt` for requirements for separation only,
|
||||
and `environment-[cpu|cuda].yml` (or `requirements.txt`) if you want to train a new model.
|
||||
|
||||
### For Windows users
|
||||
|
||||
Everytime you see `python3`, replace it with `python.exe`. You should always run commands from the
|
||||
Anaconda console.
|
||||
|
||||
### For musicians
|
||||
|
||||
If you just want to use Demucs to separate tracks, you can install it with
|
||||
|
||||
```bash
|
||||
python3 -m pip install -U demucs
|
||||
```
|
||||
|
||||
For bleeding edge versions, you can install directly from this repo using
|
||||
```bash
|
||||
python3 -m pip install -U git+https://github.com/facebookresearch/demucs#egg=demucs
|
||||
```
|
||||
|
||||
Advanced OS support are provided on the following page, **you must read the page for your OS before posting an issues**:
|
||||
- **If you are using Windows:** [Windows support](docs/windows.md).
|
||||
- **If you are using macOS:** [macOS support](docs/mac.md).
|
||||
- **If you are using Linux:** [Linux support](docs/linux.md).
|
||||
|
||||
### For machine learning scientists
|
||||
|
||||
If you have anaconda installed, you can run from the root of this repository:
|
||||
|
||||
```bash
|
||||
conda env update -f environment-cpu.yml # if you don't have GPUs
|
||||
conda env update -f environment-cuda.yml # if you have GPUs
|
||||
conda activate demucs
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
This will create a `demucs` environment with all the dependencies installed.
|
||||
|
||||
You will also need to install [soundstretch/soundtouch](https://www.surina.net/soundtouch/soundstretch.html): on macOS you can do `brew install sound-touch`,
|
||||
and on Ubuntu `sudo apt-get install soundstretch`. This is used for the
|
||||
pitch/tempo augmentation.
|
||||
|
||||
|
||||
### Running in Docker
|
||||
|
||||
Thanks to @xserrat, there is now a Docker image definition ready for using Demucs. This can ensure all libraries are correctly installed without interfering with the host OS. See his repo [Docker Facebook Demucs](https://github.com/xserrat/docker-facebook-demucs) for more information.
|
||||
|
||||
|
||||
### Running from Colab
|
||||
|
||||
I made a Colab to easily separate track with Demucs. Note that
|
||||
transfer speeds with Colab are a bit slow for large media files,
|
||||
but it will allow you to use Demucs without installing anything.
|
||||
|
||||
[Demucs on Google Colab](https://colab.research.google.com/drive/1dC9nVxk3V_VPjUADsnFu8EiT-xnU1tGH?usp=sharing)
|
||||
|
||||
### Web Demo
|
||||
|
||||
Integrated to [Hugging Face Spaces](https://huggingface.co/spaces) with [Gradio](https://github.com/gradio-app/gradio). See demo: [](https://huggingface.co/spaces/akhaliq/demucs)
|
||||
|
||||
### Graphical Interface
|
||||
|
||||
@CarlGao4 has released a GUI for Demucs: [CarlGao4/Demucs-Gui](https://github.com/CarlGao4/Demucs-Gui). Downloads for Windows and macOS is available [here](https://github.com/CarlGao4/Demucs-Gui/releases). Use [FossHub mirror](https://fosshub.com/Demucs-GUI.html) to speed up your download.
|
||||
|
||||
@Anjok07 is providing a self contained GUI in [UVR (Ultimate Vocal Remover)](https://github.com/facebookresearch/demucs/issues/334) that supports Demucs.
|
||||
|
||||
### Other providers
|
||||
|
||||
Audiostrip is providing free online separation with Demucs on their website [https://audiostrip.co.uk/](https://audiostrip.co.uk/).
|
||||
|
||||
[MVSep](https://mvsep.com/) also provides free online separation, select `Demucs3 model B` for the best quality.
|
||||
|
||||
[Neutone](https://neutone.space/) provides a realtime Demucs model in their free VST/AU plugin that can be used in your favorite DAW.
|
||||
|
||||
|
||||
## Separating tracks
|
||||
|
||||
In order to try Demucs, you can just run from any folder (as long as you properly installed it)
|
||||
|
||||
```bash
|
||||
demucs PATH_TO_AUDIO_FILE_1 [PATH_TO_AUDIO_FILE_2 ...] # for Demucs
|
||||
# If you used `pip install --user` you might need to replace demucs with python3 -m demucs
|
||||
python3 -m demucs --mp3 --mp3-bitrate BITRATE PATH_TO_AUDIO_FILE_1 # output files saved as MP3
|
||||
# use --mp3-preset to change encoder preset, 2 for best quality, 7 for fastest
|
||||
# If your filename contain spaces don't forget to quote it !!!
|
||||
demucs "my music/my favorite track.mp3"
|
||||
# You can select different models with `-n` mdx_q is the quantized model, smaller but maybe a bit less accurate.
|
||||
demucs -n mdx_q myfile.mp3
|
||||
# If you only want to separate vocals out of an audio, use `--two-stems=vocals` (You can also set to drums or bass)
|
||||
demucs --two-stems=vocals myfile.mp3
|
||||
```
|
||||
|
||||
|
||||
If you have a GPU, but you run out of memory, please use `--segment SEGMENT` to reduce length of each split. `SEGMENT` should be changed to a integer describing the length of each segment in seconds.
|
||||
A segment length of at least 10 is recommended (the bigger the number is, the more memory is required, but quality may increase). Note that the Hybrid Transformer models only support a maximum segment length of 7.8 seconds.
|
||||
Creating an environment variable `PYTORCH_NO_CUDA_MEMORY_CACHING=1` is also helpful. If this still does not help, please add `-d cpu` to the command line. See the section hereafter for more details on the memory requirements for GPU acceleration.
|
||||
|
||||
Separated tracks are stored in the `separated/MODEL_NAME/TRACK_NAME` folder. There you will find four stereo wav files sampled at 44.1 kHz: `drums.wav`, `bass.wav`,
|
||||
`other.wav`, `vocals.wav` (or `.mp3` if you used the `--mp3` option).
|
||||
|
||||
All audio formats supported by `torchaudio` can be processed (i.e. wav, mp3, flac, ogg/vorbis on Linux/macOS, etc.). On Windows, `torchaudio` has limited support, so we rely on `ffmpeg`, which should support pretty much anything.
|
||||
Audio is resampled on the fly if necessary.
|
||||
The output will be a wav file encoded as int16.
|
||||
You can save as float32 wav files with `--float32`, or 24 bits integer wav with `--int24`.
|
||||
You can pass `--mp3` to save as mp3 instead, and set the bitrate (in kbps) with `--mp3-bitrate` (default is 320).
|
||||
|
||||
It can happen that the output would need clipping, in particular due to some separation artifacts.
|
||||
Demucs will automatically rescale each output stem so as to avoid clipping. This can however break
|
||||
the relative volume between stems. If instead you prefer hard clipping, pass `--clip-mode clamp`.
|
||||
You can also try to reduce the volume of the input mixture before feeding it to Demucs.
|
||||
|
||||
|
||||
Other pre-trained models can be selected with the `-n` flag.
|
||||
The list of pre-trained models is:
|
||||
- `htdemucs`: first version of Hybrid Transformer Demucs. Trained on MusDB + 800 songs. Default model.
|
||||
- `htdemucs_ft`: fine-tuned version of `htdemucs`, separation will take 4 times more time
|
||||
but might be a bit better. Same training set as `htdemucs`.
|
||||
- `htdemucs_6s`: 6 sources version of `htdemucs`, with `piano` and `guitar` being added as sources.
|
||||
Note that the `piano` source is not working great at the moment.
|
||||
- `hdemucs_mmi`: Hybrid Demucs v3, retrained on MusDB + 800 songs.
|
||||
- `mdx`: trained only on MusDB HQ, winning model on track A at the [MDX][mdx] challenge.
|
||||
- `mdx_extra`: trained with extra training data (**including MusDB test set**), ranked 2nd on the track B
|
||||
of the [MDX][mdx] challenge.
|
||||
- `mdx_q`, `mdx_extra_q`: quantized version of the previous models. Smaller download and storage
|
||||
but quality can be slightly worse.
|
||||
- `SIG`: where `SIG` is a single model from the [model zoo](docs/training.md#model-zoo).
|
||||
|
||||
The `--two-stems=vocals` option allows separating vocals from the rest of the accompaniment (i.e., karaoke mode).
|
||||
`vocals` can be changed to any source in the selected model.
|
||||
This will mix the files after separating the mix fully, so this won't be faster or use less memory.
|
||||
|
||||
The `--shifts=SHIFTS` performs multiple predictions with random shifts (a.k.a the *shift trick*) of the input and average them. This makes prediction `SHIFTS` times
|
||||
slower. Don't use it unless you have a GPU.
|
||||
|
||||
The `--overlap` option controls the amount of overlap between prediction windows. Default is 0.25 (i.e. 25%) which is probably fine.
|
||||
It can probably be reduced to 0.1 to improve a bit speed.
|
||||
|
||||
|
||||
The `-j` flag allow to specify a number of parallel jobs (e.g. `demucs -j 2 myfile.mp3`).
|
||||
This will multiply by the same amount the RAM used so be careful!
|
||||
|
||||
### Memory requirements for GPU acceleration
|
||||
|
||||
If you want to use GPU acceleration, you will need at least 3GB of RAM on your GPU for `demucs`. However, about 7GB of RAM will be required if you use the default arguments. Add `--segment SEGMENT` to change size of each split. If you only have 3GB memory, set SEGMENT to 8 (though quality may be worse if this argument is too small). Creating an environment variable `PYTORCH_NO_CUDA_MEMORY_CACHING=1` can help users with even smaller RAM such as 2GB (I separated a track that is 4 minutes but only 1.5GB is used), but this would make the separation slower.
|
||||
|
||||
If you do not have enough memory on your GPU, simply add `-d cpu` to the command line to use the CPU. With Demucs, processing time should be roughly equal to 1.5 times the duration of the track.
|
||||
|
||||
## Calling from another Python program
|
||||
|
||||
The main function provides an `opt` parameter as a simple API. You can just pass the parsed command line as this parameter:
|
||||
```python
|
||||
# Assume that your command is `demucs --mp3 --two-stems vocals -n mdx_extra "track with space.mp3"`
|
||||
# The following codes are same as the command above:
|
||||
import demucs.separate
|
||||
demucs.separate.main(["--mp3", "--two-stems", "vocals", "-n", "mdx_extra", "track with space.mp3"])
|
||||
|
||||
# Or like this
|
||||
import demucs.separate
|
||||
import shlex
|
||||
demucs.separate.main(shlex.split('--mp3 --two-stems vocals -n mdx_extra "track with space.mp3"'))
|
||||
```
|
||||
|
||||
To use more complicated APIs, see [API docs](docs/api.md)
|
||||
|
||||
## Training Demucs
|
||||
|
||||
If you want to train (Hybrid) Demucs, please follow the [training doc](docs/training.md).
|
||||
|
||||
## MDX Challenge reproduction
|
||||
|
||||
In order to reproduce the results from the Track A and Track B submissions, checkout the [MDX Hybrid Demucs submission repo][mdx_submission].
|
||||
|
||||
|
||||
|
||||
## How to cite
|
||||
|
||||
```
|
||||
@inproceedings{rouard2022hybrid,
|
||||
title={Hybrid Transformers for Music Source Separation},
|
||||
author={Rouard, Simon and Massa, Francisco and D{\'e}fossez, Alexandre},
|
||||
booktitle={ICASSP 23},
|
||||
year={2023}
|
||||
}
|
||||
|
||||
@inproceedings{defossez2021hybrid,
|
||||
title={Hybrid Spectrogram and Waveform Source Separation},
|
||||
author={D{\'e}fossez, Alexandre},
|
||||
booktitle={Proceedings of the ISMIR 2021 Workshop on Music Source Separation},
|
||||
year={2021}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Demucs is released under the MIT license as found in the [LICENSE](LICENSE) file.
|
||||
|
||||
[hybrid_paper]: https://arxiv.org/abs/2111.03600
|
||||
[waveunet]: https://github.com/f90/Wave-U-Net
|
||||
[musdb]: https://sigsep.github.io/datasets/musdb.html
|
||||
[openunmix]: https://github.com/sigsep/open-unmix-pytorch
|
||||
[mmdenselstm]: https://arxiv.org/abs/1805.02410
|
||||
[demucs_v2]: https://github.com/facebookresearch/demucs/tree/v2
|
||||
[demucs_v3]: https://github.com/facebookresearch/demucs/tree/v3
|
||||
[spleeter]: https://github.com/deezer/spleeter
|
||||
[soundcloud]: https://soundcloud.com/honualx/sets/source-separation-in-the-waveform-domain
|
||||
[d3net]: https://arxiv.org/abs/2010.01733
|
||||
[mdx]: https://www.aicrowd.com/challenges/music-demixing-challenge-ismir-2021
|
||||
[kuielab]: https://github.com/kuielab/mdx-net-submission
|
||||
[decouple]: https://arxiv.org/abs/2109.05418
|
||||
[mdx_submission]: https://github.com/adefossez/mdx21_demucs
|
||||
[bandsplit]: https://arxiv.org/abs/2209.15174
|
||||
[htdemucs]: https://arxiv.org/abs/2211.08553
|
||||
|
|
@ -1 +0,0 @@
|
|||
Inlined demucs https://github.com/adefossez/demucs
|
||||
304
demucs/conf/config.yaml
Normal file
304
demucs/conf/config.yaml
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
defaults:
|
||||
- _self_
|
||||
- dset: musdb44
|
||||
- svd: default
|
||||
- variant: default
|
||||
- override hydra/hydra_logging: colorlog
|
||||
- override hydra/job_logging: colorlog
|
||||
|
||||
dummy:
|
||||
dset:
|
||||
musdb: /checkpoint/defossez/datasets/musdbhq
|
||||
musdb_samplerate: 44100
|
||||
use_musdb: true # set to false to not use musdb as training data.
|
||||
wav: # path to custom wav dataset
|
||||
wav2: # second custom wav dataset
|
||||
segment: 11
|
||||
shift: 1
|
||||
train_valid: false
|
||||
full_cv: true
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
normalize: true
|
||||
metadata: ./metadata
|
||||
sources: ['drums', 'bass', 'other', 'vocals']
|
||||
valid_samples: # valid dataset size
|
||||
backend: null # if provided select torchaudio backend.
|
||||
|
||||
test:
|
||||
save: False
|
||||
best: True
|
||||
workers: 2
|
||||
every: 20
|
||||
split: true
|
||||
shifts: 1
|
||||
overlap: 0.25
|
||||
sdr: true
|
||||
metric: 'loss' # metric used for best model selection on the valid set, can also be nsdr
|
||||
nonhq: # path to non hq MusDB for evaluation
|
||||
|
||||
epochs: 360
|
||||
batch_size: 64
|
||||
max_batches: # limit the number of batches per epoch, useful for debugging
|
||||
# or if your dataset is gigantic.
|
||||
optim:
|
||||
lr: 3e-4
|
||||
momentum: 0.9
|
||||
beta2: 0.999
|
||||
loss: l1 # l1 or mse
|
||||
optim: adam
|
||||
weight_decay: 0
|
||||
clip_grad: 0
|
||||
|
||||
seed: 42
|
||||
debug: false
|
||||
valid_apply: true
|
||||
flag:
|
||||
save_every:
|
||||
weights: [1., 1., 1., 1.] # weights over each source for the training/valid loss.
|
||||
|
||||
augment:
|
||||
shift_same: false
|
||||
repitch:
|
||||
proba: 0.2
|
||||
max_tempo: 12
|
||||
remix:
|
||||
proba: 1
|
||||
group_size: 4
|
||||
scale:
|
||||
proba: 1
|
||||
min: 0.25
|
||||
max: 1.25
|
||||
flip: true
|
||||
|
||||
continue_from: # continue from other XP, give the XP Dora signature.
|
||||
continue_pretrained: # signature of a pretrained XP, this cannot be a bag of models.
|
||||
pretrained_repo: # repo for pretrained model (default is official AWS)
|
||||
continue_best: true
|
||||
continue_opt: false
|
||||
|
||||
misc:
|
||||
num_workers: 10
|
||||
num_prints: 4
|
||||
show: false
|
||||
verbose: false
|
||||
|
||||
# List of decay for EMA at batch or epoch level, e.g. 0.999.
|
||||
# Batch level EMA are kept on GPU for speed.
|
||||
ema:
|
||||
epoch: []
|
||||
batch: []
|
||||
|
||||
use_train_segment: true # to remove
|
||||
model_segment: # override the segment parameter for the model, usually 4 times the training segment.
|
||||
model: demucs # see demucs/train.py for the possibilities, and config for each model hereafter.
|
||||
demucs: # see demucs/demucs.py for a detailed description
|
||||
# Channels
|
||||
channels: 64
|
||||
growth: 2
|
||||
# Main structure
|
||||
depth: 6
|
||||
rewrite: true
|
||||
lstm_layers: 0
|
||||
# Convolutions
|
||||
kernel_size: 8
|
||||
stride: 4
|
||||
context: 1
|
||||
# Activations
|
||||
gelu: true
|
||||
glu: true
|
||||
# Normalization
|
||||
norm_groups: 4
|
||||
norm_starts: 4
|
||||
# DConv residual branch
|
||||
dconv_depth: 2
|
||||
dconv_mode: 1 # 1 = branch in encoder, 2 = in decoder, 3 = in both.
|
||||
dconv_comp: 4
|
||||
dconv_attn: 4
|
||||
dconv_lstm: 4
|
||||
dconv_init: 1e-4
|
||||
# Pre/post treatment
|
||||
resample: true
|
||||
normalize: false
|
||||
# Weight init
|
||||
rescale: 0.1
|
||||
|
||||
hdemucs: # see demucs/hdemucs.py for a detailed description
|
||||
# Channels
|
||||
channels: 48
|
||||
channels_time:
|
||||
growth: 2
|
||||
# STFT
|
||||
nfft: 4096
|
||||
wiener_iters: 0
|
||||
end_iters: 0
|
||||
wiener_residual: false
|
||||
cac: true
|
||||
# Main structure
|
||||
depth: 6
|
||||
rewrite: true
|
||||
hybrid: true
|
||||
hybrid_old: false
|
||||
# Frequency Branch
|
||||
multi_freqs: []
|
||||
multi_freqs_depth: 3
|
||||
freq_emb: 0.2
|
||||
emb_scale: 10
|
||||
emb_smooth: true
|
||||
# Convolutions
|
||||
kernel_size: 8
|
||||
stride: 4
|
||||
time_stride: 2
|
||||
context: 1
|
||||
context_enc: 0
|
||||
# normalization
|
||||
norm_starts: 4
|
||||
norm_groups: 4
|
||||
# DConv residual branch
|
||||
dconv_mode: 1
|
||||
dconv_depth: 2
|
||||
dconv_comp: 4
|
||||
dconv_attn: 4
|
||||
dconv_lstm: 4
|
||||
dconv_init: 1e-3
|
||||
# Weight init
|
||||
rescale: 0.1
|
||||
|
||||
# Torchaudio implementation of HDemucs
|
||||
torch_hdemucs:
|
||||
# Channels
|
||||
channels: 48
|
||||
growth: 2
|
||||
# STFT
|
||||
nfft: 4096
|
||||
# Main structure
|
||||
depth: 6
|
||||
freq_emb: 0.2
|
||||
emb_scale: 10
|
||||
emb_smooth: true
|
||||
# Convolutions
|
||||
kernel_size: 8
|
||||
stride: 4
|
||||
time_stride: 2
|
||||
context: 1
|
||||
context_enc: 0
|
||||
# normalization
|
||||
norm_starts: 4
|
||||
norm_groups: 4
|
||||
# DConv residual branch
|
||||
dconv_depth: 2
|
||||
dconv_comp: 4
|
||||
dconv_attn: 4
|
||||
dconv_lstm: 4
|
||||
dconv_init: 1e-3
|
||||
|
||||
htdemucs: # see demucs/htdemucs.py for a detailed description
|
||||
# Channels
|
||||
channels: 48
|
||||
channels_time:
|
||||
growth: 2
|
||||
# STFT
|
||||
nfft: 4096
|
||||
wiener_iters: 0
|
||||
end_iters: 0
|
||||
wiener_residual: false
|
||||
cac: true
|
||||
# Main structure
|
||||
depth: 4
|
||||
rewrite: true
|
||||
# Frequency Branch
|
||||
multi_freqs: []
|
||||
multi_freqs_depth: 3
|
||||
freq_emb: 0.2
|
||||
emb_scale: 10
|
||||
emb_smooth: true
|
||||
# Convolutions
|
||||
kernel_size: 8
|
||||
stride: 4
|
||||
time_stride: 2
|
||||
context: 1
|
||||
context_enc: 0
|
||||
# normalization
|
||||
norm_starts: 4
|
||||
norm_groups: 4
|
||||
# DConv residual branch
|
||||
dconv_mode: 1
|
||||
dconv_depth: 2
|
||||
dconv_comp: 8
|
||||
dconv_init: 1e-3
|
||||
# Before the Transformer
|
||||
bottom_channels: 0
|
||||
# CrossTransformer
|
||||
# ------ Common to all
|
||||
# Regular parameters
|
||||
t_layers: 5
|
||||
t_hidden_scale: 4.0
|
||||
t_heads: 8
|
||||
t_dropout: 0.0
|
||||
t_layer_scale: True
|
||||
t_gelu: True
|
||||
# ------------- Positional Embedding
|
||||
t_emb: sin
|
||||
t_max_positions: 10000 # for the scaled embedding
|
||||
t_max_period: 10000.0
|
||||
t_weight_pos_embed: 1.0
|
||||
t_cape_mean_normalize: True
|
||||
t_cape_augment: True
|
||||
t_cape_glob_loc_scale: [5000.0, 1.0, 1.4]
|
||||
t_sin_random_shift: 0
|
||||
# ------------- norm before a transformer encoder
|
||||
t_norm_in: True
|
||||
t_norm_in_group: False
|
||||
# ------------- norm inside the encoder
|
||||
t_group_norm: False
|
||||
t_norm_first: True
|
||||
t_norm_out: True
|
||||
# ------------- optim
|
||||
t_weight_decay: 0.0
|
||||
t_lr:
|
||||
# ------------- sparsity
|
||||
t_sparse_self_attn: False
|
||||
t_sparse_cross_attn: False
|
||||
t_mask_type: diag
|
||||
t_mask_random_seed: 42
|
||||
t_sparse_attn_window: 400
|
||||
t_global_window: 100
|
||||
t_sparsity: 0.95
|
||||
t_auto_sparsity: False
|
||||
# Cross Encoder First (False)
|
||||
t_cross_first: False
|
||||
# Weight init
|
||||
rescale: 0.1
|
||||
|
||||
svd: # see svd.py for documentation
|
||||
penalty: 0
|
||||
min_size: 0.1
|
||||
dim: 1
|
||||
niters: 2
|
||||
powm: false
|
||||
proba: 1
|
||||
conv_only: false
|
||||
convtr: false
|
||||
bs: 1
|
||||
|
||||
quant: # quantization hyper params
|
||||
diffq: # diffq penalty, typically 1e-4 or 3e-4
|
||||
qat: # use QAT with a fixed number of bits (not as good as diffq)
|
||||
min_size: 0.2
|
||||
group_size: 8
|
||||
|
||||
dora:
|
||||
dir: outputs
|
||||
exclude: ["misc.*", "slurm.*", 'test.reval', 'flag', 'dset.backend']
|
||||
|
||||
slurm:
|
||||
time: 4320
|
||||
constraint: volta32gb
|
||||
setup: ['module load cudnn/v8.4.1.50-cuda.11.6 NCCL/2.11.4-6-cuda.11.6 cuda/11.6']
|
||||
|
||||
# Hydra config
|
||||
hydra:
|
||||
job_logging:
|
||||
formatters:
|
||||
colorlog:
|
||||
datefmt: "%m-%d %H:%M:%S"
|
||||
19
demucs/conf/dset/aetl.yaml
Normal file
19
demucs/conf/dset/aetl.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# @package _global_
|
||||
|
||||
# automix dataset with Musdb, extra training data and the test set of Musdb.
|
||||
# This used even more remixes than auto_extra_test.
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/aetl
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
epochs: 320
|
||||
max_batches: 500
|
||||
|
||||
augment:
|
||||
shift_same: true
|
||||
scale:
|
||||
proba: 0.
|
||||
remix:
|
||||
proba: 0
|
||||
repitch:
|
||||
proba: 0
|
||||
18
demucs/conf/dset/auto_extra_test.yaml
Normal file
18
demucs/conf/dset/auto_extra_test.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# @package _global_
|
||||
|
||||
# automix dataset with Musdb, extra training data and the test set of Musdb.
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/automix_extra_test2
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
epochs: 320
|
||||
max_batches: 500
|
||||
|
||||
augment:
|
||||
shift_same: true
|
||||
scale:
|
||||
proba: 0.
|
||||
remix:
|
||||
proba: 0
|
||||
repitch:
|
||||
proba: 0
|
||||
20
demucs/conf/dset/auto_mus.yaml
Normal file
20
demucs/conf/dset/auto_mus.yaml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# @package _global_
|
||||
|
||||
# Automix dataset based on musdb train set.
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/automix_musdb
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
epochs: 360
|
||||
max_batches: 300
|
||||
test:
|
||||
every: 4
|
||||
|
||||
augment:
|
||||
shift_same: true
|
||||
scale:
|
||||
proba: 0.5
|
||||
remix:
|
||||
proba: 0
|
||||
repitch:
|
||||
proba: 0
|
||||
8
demucs/conf/dset/extra44.yaml
Normal file
8
demucs/conf/dset/extra44.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# @package _global_
|
||||
|
||||
# Musdb + extra tracks
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/allstems_44/
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
epochs: 320
|
||||
12
demucs/conf/dset/extra_mmi_goodclean.yaml
Normal file
12
demucs/conf/dset/extra_mmi_goodclean.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# @package _global_
|
||||
|
||||
# Musdb + extra tracks
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/allstems_44/
|
||||
wav2: /checkpoint/defossez/datasets/mmi44_goodclean
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
wav2_weight: null
|
||||
wav2_valid: false
|
||||
valid_samples: 100
|
||||
epochs: 1200
|
||||
12
demucs/conf/dset/extra_test.yaml
Normal file
12
demucs/conf/dset/extra_test.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# @package _global_
|
||||
|
||||
# Musdb + extra tracks + test set from musdb.
|
||||
dset:
|
||||
wav: /checkpoint/defossez/datasets/allstems_test_44/
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
epochs: 320
|
||||
max_batches: 700
|
||||
test:
|
||||
sdr: false
|
||||
every: 500
|
||||
5
demucs/conf/dset/musdb44.yaml
Normal file
5
demucs/conf/dset/musdb44.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# @package _global_
|
||||
|
||||
dset:
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
10
demucs/conf/dset/sdx23_bleeding.yaml
Normal file
10
demucs/conf/dset/sdx23_bleeding.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# @package _global_
|
||||
|
||||
# Musdb + extra tracks
|
||||
dset:
|
||||
wav: /shared/home/defossez/data/datasets/moisesdb23_bleeding_v1.0/
|
||||
use_musdb: false
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
backend: soundfile # must use soundfile as some mixture would clip with sox.
|
||||
epochs: 320
|
||||
10
demucs/conf/dset/sdx23_labelnoise.yaml
Normal file
10
demucs/conf/dset/sdx23_labelnoise.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# @package _global_
|
||||
|
||||
# Musdb + extra tracks
|
||||
dset:
|
||||
wav: /shared/home/defossez/data/datasets/moisesdb23_labelnoise_v1.0
|
||||
use_musdb: false
|
||||
samplerate: 44100
|
||||
channels: 2
|
||||
backend: soundfile # must use soundfile as some mixture would clip with sox.
|
||||
epochs: 320
|
||||
14
demucs/conf/svd/base.yaml
Normal file
14
demucs/conf/svd/base.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# @package _global_
|
||||
|
||||
svd:
|
||||
penalty: 0
|
||||
min_size: 1
|
||||
dim: 50
|
||||
niters: 4
|
||||
powm: false
|
||||
proba: 1
|
||||
conv_only: false
|
||||
convtr: false # ideally this should be true, but some models were trained with this to false.
|
||||
|
||||
optim:
|
||||
beta2: 0.9998
|
||||
14
demucs/conf/svd/base2.yaml
Normal file
14
demucs/conf/svd/base2.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# @package _global_
|
||||
|
||||
svd:
|
||||
penalty: 0
|
||||
min_size: 1
|
||||
dim: 100
|
||||
niters: 4
|
||||
powm: false
|
||||
proba: 1
|
||||
conv_only: false
|
||||
convtr: true
|
||||
|
||||
optim:
|
||||
beta2: 0.9998
|
||||
1
demucs/conf/svd/default.yaml
Normal file
1
demucs/conf/svd/default.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
# @package _global_
|
||||
1
demucs/conf/variant/default.yaml
Normal file
1
demucs/conf/variant/default.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
# @package _global_
|
||||
5
demucs/conf/variant/example.yaml
Normal file
5
demucs/conf/variant/example.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# @package _global_
|
||||
|
||||
model: hdemucs
|
||||
hdemucs:
|
||||
channels: 32
|
||||
19
demucs/conf/variant/finetune.yaml
Normal file
19
demucs/conf/variant/finetune.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# @package _global_
|
||||
|
||||
epochs: 4
|
||||
batch_size: 16
|
||||
optim:
|
||||
lr: 0.0006
|
||||
test:
|
||||
every: 1
|
||||
sdr: false
|
||||
dset:
|
||||
segment: 28
|
||||
shift: 2
|
||||
|
||||
augment:
|
||||
scale:
|
||||
proba: 0
|
||||
shift_same: true
|
||||
remix:
|
||||
proba: 0
|
||||
BIN
demucs/demucs.png
Normal file
BIN
demucs/demucs.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 331 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue