mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 10:56:10 +00:00
The two local model boxes handed over a flat list sorted by size and left every choice in it to the reader. For whisper that interleaved the models: large-v3-turbo-q5_0 landed between the two medium quantisations, half a screen from the turbo model it is a copy of. For cleanup it was forty repository ids, half of which answer with nothing at all because what they publish is split across files or larger than the cap, and an empty box read as though the click had not registered. Now each box says what the machine is, groups the list by model, and marks the row to take: - whisper rows are grouped by model, with the quantisations and the English-only files under the model they are a copy of, and every row says its bit depth rather than leaving q5_1 and Q4_K_M and BF16 to be decoded. - the recommendation follows the machine. Under 4 GB it is small-q5_1; with a graphics interface and 15 GB it is large-v3-q5_0, which is worth about two and a half points of word error in the languages that are not English; in between it is turbo, and a processor build where the Vulkan one belongs is not counted as a card. - a row larger than half the memory less a gigabyte says it is too big. - the publisher box holds the five suggestions until the switch beside it is turned on, and a line under it says in words what the chosen one is. - a publisher that answers with nothing says why instead of going blank. - the draft heads (dflash, dspark, eagle3) are no longer offered as models, and neither are the base models that sit beside their tuned twin.
270 lines
16 KiB
Markdown
270 lines
16 KiB
Markdown
# Dikte
|
||
|
||
`Ctrl+Space`'e bas, konuş, tekrar bas. Ses varsayılan olarak bu makinede yazıya
|
||
çevrilir, bir model transkripti temizler (ıı'lar, tekrarlar, eksik noktalama),
|
||
sonuç panoya kopyalanır ve o an yazdığın pencereye yapıştırılır.
|
||
|
||
KDE Plasma 6 / Wayland için yazıldı; GNOME X11'de, macOS'ta,
|
||
[Windows](README.windows.md)'ta ve klavyeyi okumasına izin veren diğer Linux
|
||
masaüstlerinde de çalışır. Sistem paketleri dışında bağımlılığı yok: sadece
|
||
Python standart kütüphanesi (3.11 veya üstü) ve PyQt6.
|
||
|
||
*[English README](README.md)*
|
||
|
||
<p align="center">
|
||
<img src="docs/settings-general.webp" width="820" alt="Dikte ayarları, Genel sekmesi">
|
||
</p>
|
||
|
||
| | |
|
||
|---|---|
|
||
| <img src="docs/settings-api.webp" width="410" alt="API ve modeller"> | <img src="docs/settings-cleanup.webp" width="410" alt="Temizleme kuralları"> |
|
||
| <img src="docs/settings-agent.webp" width="410" alt="Ajan"> | <img src="docs/settings-meeting.webp" width="410" alt="Toplantı"> |
|
||
| <img src="docs/settings-audio-file.webp" width="410" alt="Ses dosyası"> | <img src="docs/settings-shortcuts.webp" width="410" alt="Kısayollar"> |
|
||
|
||
## Kurulum
|
||
|
||
[Sürümler sayfasında](../../releases) bir AppImage, her Mac mimarisi için
|
||
birer disk imajı, bir de Windows kurulumu var. İlk ikisi ilk çalıştıklarında
|
||
kendi menü girdisini, oturum açılışını ve `dikte` komutunu yazar, makinede
|
||
zaten duran bir kuruluma dokunmazlar; `dikte integrate --remove` yazdıklarını
|
||
geri alır. AppImage yine de aşağıdaki sistem paketlerini ister: ses sunucusu,
|
||
pano ve klavye onlardan gelir. Disk imajı bir Apple sertifikasıyla imzalı
|
||
değil, bu yüzden ilk açılış reddedilir, Sistem Ayarları → Gizlilik ve Güvenlik
|
||
altından **Yine de Aç** demek gerekir; macOS her güncellemeden sonra mikrofonu
|
||
ve Erişilebilirliği yeniden sorar, checkout'tan kurmak bundan kurtarır.
|
||
Windows kurulumu yalnızca kendi hesabına kurar ve yanında bir ffmpeg taşır.
|
||
|
||
```sh
|
||
sudo pacman -S --needed pipewire-audio wl-clipboard ydotool ffmpeg python-pyqt6
|
||
systemctl --user enable --now ydotool # otomatik yapıştırma için
|
||
|
||
./install.sh # ya da: ./install.sh "Meta+Space" "Meta+Shift+Space"
|
||
dikte # ilk açılışta ayarlar penceresi gelir
|
||
```
|
||
|
||
Fedora'da paket adları farklı, Fedora'nın kendi depolarındaki `ffmpeg-free`
|
||
yetiyor çünkü Dikte video dosyasının yalnızca ses izini alıyor, `ydotool` da
|
||
bir adım fazla istiyor: sistem servisi olarak geliyor, soketi de root'a ait
|
||
kalıp oturumun erişemediği yerde durduğu için servis çalışırken bile otomatik
|
||
yapıştırma tutmuyor. Soketi istemcinin zaten baktığı yola al ve sahipliğini
|
||
devret:
|
||
|
||
```sh
|
||
sudo dnf install pipewire-utils wl-clipboard ydotool ffmpeg-free python3-pyqt6
|
||
sudo mkdir -p /etc/systemd/system/ydotool.service.d
|
||
printf '[Service]\nExecStart=\nExecStart=/usr/bin/ydotoold --socket-path=%s/.ydotool_socket --socket-own=%s:%s\n' \
|
||
"$XDG_RUNTIME_DIR" "$(id -u)" "$(id -g)" \
|
||
| sudo tee /etc/systemd/system/ydotool.service.d/override.conf >/dev/null
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now ydotool
|
||
```
|
||
|
||
Ubuntu/GNOME X11 için kayıt PulseAudio üzerinden, pano ve yapıştırma ise X11
|
||
araçlarıyla çalışır:
|
||
|
||
```sh
|
||
sudo apt install pulseaudio-utils xclip xdotool ffmpeg
|
||
```
|
||
|
||
macOS'ta da aynı `./install.sh` çalışır, işi `scripts/install-mac.sh`'a devreder;
|
||
`~/Applications` içine bir `Dikte.app`, `dikte` komutunu ve bir LaunchAgent
|
||
kurar:
|
||
|
||
```sh
|
||
brew install pyqt ffmpeg # pyqt Apple'ın 3.9'undan yeni bir Python'ı da getirir
|
||
|
||
./install.sh # ya da: ./install.sh "Ctrl+Option+Space" "Ctrl+Option+D"
|
||
open -a Dikte
|
||
```
|
||
|
||
macOS **Mikrofon** ve **Erişilebilirlik** izinlerini uygulama paketinin kimliğine
|
||
yazıyor, ikisini de ilk gerektiğinde soruyor. Varsayılan kısayol orada
|
||
`Ctrl+Option+Space`, çünkü `Ctrl+Space` giriş kaynağını değiştirmeye ayrılmış; ve
|
||
hiçbir şey için oturumu kapatman gerekmez, kombinasyonu Dikte çalışırken kendisi
|
||
tutar. PyQt6 pip'ten değil brew'dan geliyor, Homebrew'un Python'u içine
|
||
kurulmayı reddediyor; sanal ortam kullanacaksan
|
||
`DIKTE_PYTHON=…/venv/bin/python ./install.sh`.
|
||
|
||
Orada elle derlenmesi gereken tek parça yerel transkripsiyon: whisper.cpp'nin
|
||
macOS sürümü yok, Homebrew'unki de `WHISPER_BUILD_SERVER=OFF` ile derleniyor,
|
||
yani `whisper-cli` kuruluyor, Dikte'nin konuştuğu sunucu değil. Kendin derle
|
||
(`cmake -B build -DWHISPER_BUILD_SERVER=ON -DGGML_METAL=ON && cmake --build
|
||
build -j`) ve yolunu Ayarlar → API'ye yaz, ya da buluta çevir. Toplantı için
|
||
BlackHole veya Loopback gerekiyor (`brew install blackhole-2ch`); dikte için
|
||
gerekmiyor.
|
||
|
||
Windows da aynı şekilde çalışıyor, Dikte açıkken kombinasyonu sistemin kendi
|
||
kısayol servisi üzerinden tutuyor. Sürümler sayfasındaki kurulum kaydın
|
||
istediği ffmpeg'i de taşıyor ve yönetici istemiyor; checkout'tan ise `winget
|
||
install Gyan.FFmpeg`, `pip install PyQt6`, sonra `python -m dikte`, Başlat
|
||
Menüsü girdisi ve `dikte` komutu için de isteğe bağlı `install.ps1`. Orada
|
||
toplantı kaydı henüz yok, ayrıntılar [Windows README](README.windows.md)'sinde.
|
||
|
||
`install.sh` `dikte` komutunu, menü girdisini, oturum açılışında otomatik
|
||
başlatmayı ve iki global kısayolu kurar; tuşları iki argümanı, argüman
|
||
verilmezse ayarlarında duranlar. `./scripts/update.sh` son sürümü çeker ve
|
||
bunları yerine koyar; `./scripts/uninstall.sh` hepsini geri alır, `--purge`
|
||
demedikçe ayarlarına ve diktelerine dokunmaz. Dikte sürüm sayfasına günde bir
|
||
kez bakar ve yeni sürüm çıkmışsa tepsi menüsüne bir satır koyar; o satır bir şey
|
||
kurmaz, sayfayı açar. Genel sekmesi bu denetimi kapatır ya da anında çalıştırır.
|
||
|
||
Sesi yazıya çevirme ve temizleme, ayarlar penceresinde ayrı ayrı sağlayıcı
|
||
seçer; ikisi de varsayılan olarak burada, kendi modellerinle çalışır. Bulutu
|
||
seçersen sesi yazıya çevirme **OpenAI**, **Groq** ya da **OpenRouter**'da
|
||
(varsayılan `gpt-4o-transcribe`), temizleme OpenRouter'da
|
||
(`google/gemini-3.5-flash-lite`), **Google AI Studio**'da
|
||
(`gemini-3.5-flash-lite`), **OpenCode Go**'da (`deepseek-v4-flash`) ya da
|
||
kuruluysa Claude Code, Codex veya Antigravity'de çalışır. İlk üçü tek bir HTTP
|
||
isteği; üç CLI ise bunun için birer oturum açar, fazladan giden birkaç saniye de
|
||
oradan gelir. Anahtarları boş bırakırsan `OPENAI_API_KEY`, `GROQ_API_KEY`,
|
||
`OPENROUTER_API_KEY`, `GEMINI_API_KEY` ve `OPENCODE_API_KEY` kullanılır;
|
||
anahtarlar `~/.config/dikte/config.json` içinde, izinler 600, Mac'te ise
|
||
`~/Library/Application Support/Dikte` altında.
|
||
Temizlemeyi tamamen kapatabilirsin, o zaman ham transkript yapıştırılır; modelin
|
||
yanındaki kutudan düşünme seviyesini de seçebilirsin.
|
||
|
||
## Kullanım
|
||
|
||
| Ne | Nasıl |
|
||
| --- | --- |
|
||
| Kaydı başlat / bitir | `Ctrl+Space`, ya da tepsi simgesine tıkla |
|
||
| Kaydı duraklat / sürdür | Tepsi menüsü, `dikte pause`, ya da atadığın bir tuş |
|
||
| Kaydı iptal et | `Ctrl+Alt+Space`, tepsi menüsü, ya da `dikte cancel` |
|
||
| Ajana sesle komut ver | Tepsi menüsü → *Claude'a sor*, ya da `dikte ask` |
|
||
| Toplantıyı başlat / bitir | Tepsi menüsü → *Toplantı kaydet*, ya da `dikte meeting` |
|
||
| Ayarlar | Tepsi menüsü → *Ayarlar*, ya da `dikte settings` |
|
||
| Yeni sürüm var mı bak | Genel sekmesi → *Şimdi bak*, ya da `dikte update` |
|
||
| Güncelleme sonrası yeniden yükle | Tepsi menüsü → *Yeniden başlat*, ya da `dikte restart` |
|
||
| Çık | Tepsi menüsü → *Çık*, ya da `dikte quit` |
|
||
|
||
Ekranın köşesindeki gösterge kırmızı kayıt noktasını, canlı ses dalgasını ve
|
||
süreyi, ardından hangi aşamada olduğunu gösterir. Odak almaz. Önceki dikte daha
|
||
temizlenirken `Ctrl+Space`'e tekrar basmak yenisini başlatır; o da sırası
|
||
gelince, öndekinin ardından yazılıp yapıştırılır. Dikte ile ajana
|
||
verilen komut yalnızca mikrofon için birbirini bekler, o da tek aygıt olduğu
|
||
için; başka hiçbir şeyde beklemezler. Her birinin kendi göstergesi var, ikisi
|
||
birden ekrandayken ikincisi birincinin üstüne yerleşir.
|
||
|
||
Ayarlar penceresindeki her şeyin bir de komutu var; bir betik ya da bir ajan
|
||
yazılımın tamamını çalıştırabilsin diye: `dikte record --seconds 8` söyleneni
|
||
geri verir, `dikte transcribe konusma.mp4 --srt` altyazıyı yazar, ayarlar,
|
||
geçmiş ve toplantılar da yanlarında durur. Hepsini `dikte --help` sayar, hepsi
|
||
`--json` kabul eder, yalnızca mikrofona ihtiyacı olanlar uygulamanın açık
|
||
olmasını ister.
|
||
|
||
## Neler yapıyor
|
||
|
||
- **Her şey varsayılan olarak bu makinede çalışır.** Sesi yazıya çevirme
|
||
whisper.cpp, temizleme llama.cpp üzerinde; ikisini de önceden kurman gerekmez:
|
||
ayarlar penceresi programı ve modeli indirir, sha256'sını doğrular,
|
||
checksum'suz yayınlanmış bir indirmeyi reddeder, sen dikte ettikçe sunucuyu
|
||
ayakta tutar. Model listesi dosya boyutuna değil modele göre gruplanır ve bu
|
||
makinenin belleğine ve ekran kartına uyan satır işaretlenir. Derleme
|
||
destekliyorsa ekran kartına CUDA, ROCm ya da Vulkan
|
||
üzerinden ulaşılır. Anahtar yok, hesap yok, makineden çıkan bir şey yok.
|
||
x86_64 Linux'ta aynı düğme, whisper-server'ın Dikte'nin kendi yayınladığı
|
||
Vulkan derlemesini indirir; upstream'in Linux arşivi yalnızca işlemci için.
|
||
- **Sessizlik API'ye gitmez.** Sessize yakın bir ses verildiğinde model boş dize
|
||
döndürmez, bir cümle uydurur ("Altyazı M.K.", "Thanks for watching"). *O
|
||
kaydın kendi* gürültü tabanının 10 dB üstüne en az 0,3 saniye çıkan bir şey
|
||
yoksa kayıt atılır; ne kadar yüksek olursa olsun sabit fanı ya da cızırtıyı
|
||
eleyen de budur. Kaydın gürültülü ucu -55 dBFS altındaysa da atılır. Gösterge
|
||
ölçtüğü seviyeyi yazar, eşiği ona bakarak ayarlarsın.
|
||
- **Yanlış duyulan kelimeler düzeltilir.** Konuşma modelleri özel isimlerde sesçe
|
||
benzer bir şeye kayıyor; temizleme modelinden bunları bağlamdan onarması,
|
||
bağlam netleştirmiyorsa dokunmaması isteniyor. Temizleme kuralları sekmesine
|
||
yazdığın isimler transkripsiyon modeline ipucu, temizleme modeline sözlük
|
||
olarak gidiyor; "kuber netis"i tanımasını sağlayan da bu:
|
||
|
||
```
|
||
ham ıı bugün şey kuber netis üzerinde çalışan servisleri güncelledim
|
||
yani sonra grafanada bir panel açtım hani ve pay kut ile arayüzü
|
||
şey bitirdim işte
|
||
|
||
sonuç Bugün Kubernetes üzerinde çalışan servisleri güncelledim. Sonra
|
||
Grafana'da bir panel açtım ve PyQt ile arayüzü bitirdim.
|
||
```
|
||
- **Başarısız temizleme sessizce geçmez.** Dikte kaybolmasın diye ham transkript
|
||
yine yapıştırılır ama gösterge kehribar rengine döner ve nedenini söyler,
|
||
normal bir çalışma gibi görünmez.
|
||
- **Dikte bunun yerine bir komut da olabilir.** Kendi kısayolu transkripti
|
||
yapıştırmak yerine Claude Code'a (`claude -p`) gönderir ve oradan döneni
|
||
yapıştırır: cevabı ya da ne yapıldığını söyleyen bir cümle. Kendi açacağın
|
||
oturumun aynısıdır, yani skill'lerin ve bağlı servislerin oradadır; "bunu
|
||
perşembe üçe takvime koy" cümlesini Claude olmayan bir pencerede söyleyebilir
|
||
olmanı sağlayan da budur. Codex (`codex exec`) ile Antigravity (`agy -p`) da
|
||
aynı şekilde çalışır; ama Antigravity'ye Dikte bir izin kipi ya da sandbox
|
||
veremiyor, sormadan ne yapabileceğini kendi allow-rule'ları belirliyor.
|
||
OpenRouter ya da OpenCode Go ise hiçbiri kurulu olmayan bir makinede düz soru
|
||
cevap için duruyor. Sağlayıcı, model, izinler ve çalışma dizini Ayarlar → Ajan
|
||
sekmesinde; arka arkaya verilen komutlar tek bir konuşmada kalır.
|
||
- **Toplantılar** mikrofonla hoparlör çıkışından aynı anda kaydedilir; kimin ne
|
||
dediği tahmin edilmez, sesin hangi kanaldan geldiğiyle belli olur. İki taraf
|
||
ayrı ayrı yazıya çevrilip tek bir zaman damgalı transkriptte birleştirilir,
|
||
ardından Ayarlar → Toplantı sekmesinden seçtiğin ikinci bir model kendi
|
||
talimatıyla bunu tutanağa çevirir: kararlar, aksiyonlar, açık sorular. Sonuç
|
||
`~/.local/share/dikte/meetings` altına ve Ayarlar → Tutanaklar sekmesine
|
||
düşer. Yarıda kalan bir işlem ses kaydını saklar, yeniden denemede parası
|
||
ödenmiş transkriptin üstünden devam eder.
|
||
- **Ses ve video dosyaları** Ayarlar → Ses dosyası sekmesinde aynı modellerden
|
||
geçer; istersen `[dd:ss]` zaman damgalarıyla, uzun dosyalar ffmpeg ile
|
||
parçalanarak, sonuç `.txt` ya da `.srt` altyazı olarak kaydedilerek; temizleme
|
||
burada kendi kurallarıyla, altyazı için yazılmış haliyle çalışır: satırlar
|
||
yerinde kalır, hiçbir şey kısaltılmaz.
|
||
- **Geçmiş** Ayarlar → Geçmiş sekmesinde; boyut sınırı var, sağ tıklayıp
|
||
silebilirsin.
|
||
- **Türkçe ve İngilizce arayüz**, varsayılan olarak sistem dilini izler.
|
||
|
||
## Global kısayollar ve KDE'nin istediği oturum kapatma
|
||
|
||
KWin `kglobalshortcutsrc` dosyasını yalnızca açılışta okur, yani `install.sh`'ın
|
||
yazdığı kısayollar oturumu yeniden açana kadar tetiklenmez. O zamana kadar Ayarlar →
|
||
Kısayollar → **yerleşik dinleyici** `/dev/input` üzerinden kombinasyonu kendisi
|
||
yakalar. Tek farkı: tuşu yutmaz, yani `Ctrl+Space` odaktaki uygulamaya da iletilir
|
||
(bazı editörlerde otomatik tamamlama açılabilir). Dinleyici kullanıcının `input`
|
||
grubunda olmasını gerektirir: `sudo usermod -aG input $USER`. GNOME'da kısayol
|
||
kurulduğu anda çalışır; hiç kayıt defteri tutmayan masaüstlerinde (i3, XFCE,
|
||
sway ve çoğu diğeri) dinleyici mekanizmanın kendisidir: hiçbir şey kurulmaz,
|
||
oturum kapatmak gerekmez, tuşları masaüstünün sahiplenmesini istersen Ayarlar →
|
||
Kısayollar sekmesi bağlanacak komutu gösterir.
|
||
|
||
## Dosyalar
|
||
|
||
Aşağıdakilerin hepsi `dikte` paketinin içinde: `python3 -m dikte` bunu çalıştırır,
|
||
içindeki `__main__.py` de her başlatıcının ve kısayolun adlandırdığı dosyadır.
|
||
`scripts/` altında install-mac.sh, update.sh, uninstall.sh ve release.sh var;
|
||
`packaging/` release.sh'ın attığı etiketin yayımladığı AppImage'i, disk imajını
|
||
ve Windows kurulumunu derler; install.sh en üstte kalır, `tests/` içinde de her
|
||
modülün bir dosyası.
|
||
|
||
```
|
||
app.py giriş noktası, tepsi simgesi, durum makinesi
|
||
cli.py komut satırı: bütün fiiller ve verdikleri cevap
|
||
ipc.py yerel sokette bir istek, bir cevap
|
||
audio.py PCM kaydı: diktede pw-record, toplantıda ffmpeg
|
||
meeting.py kanal ayırma, konuşmacı etiketi, temizleme, tutanak
|
||
assistant.py dikteyi Claude Code, Codex, agy ya da sohbet modelinden geçirme
|
||
api.py transkript ve temizleme istekleri (yalnız stdlib)
|
||
cleanup.py transkripti kim temizler: bulutta bir model, burası, bir CLI
|
||
ggml.py whisper.cpp ve llama.cpp'yi indirip burada çalıştırma
|
||
hub.py GitHub ve Hugging Face'te bugün ne olduğu
|
||
update.py yeni sürüm çıkmış mı, çıkmışsa hangi sayfada
|
||
worker.py transkript → temizleme → pano → yapıştırma
|
||
vad.py kayıtta gerçekten konuşma var mı kararı
|
||
filetranscribe.py dosyadan transkript: ffmpeg, parçalama, zaman damgaları
|
||
overlay.py köşedeki gösterge
|
||
settings_ui.py ayarlar penceresi
|
||
hotkey.py masaüstünün kısayol kaydı, evdev dinleyici, Mac'te Carbon
|
||
paste.py wl-clipboard ve ydotool sarmalayıcıları, pbcopy ve CoreGraphics
|
||
trayicon.py tepsi simgeleri, ikon teması olmayan yerler için çizilmiş
|
||
integrate.py indirilen bir yapının indiği masaüstüne yazdıkları
|
||
i18n.py metin tablosu
|
||
```
|
||
|
||
Gösterge XWayland üzerinden çizilir; Wayland'da bir pencereyi belirli bir köşeye
|
||
yerleştirmenin yolu yok, `app.py` bu yüzden `QT_QPA_PLATFORM=xcb` ayarlar.
|
||
|
||
## Lisans
|
||
|
||
GPL-3.0, [LICENSE](LICENSE) dosyasına bak.
|