<img src="assets/logo.svg" width="96" align="right" alt="VideoD logo"/>

# VideoD

**Chrome eklentili video indirici** — Windows

Chrome'da gezdiğiniz sayfalardaki videoları tespit eden bir eklenti ve bunları indiren
bir Windows (WPF) uygulaması. Parçalı akışlar (HLS `.m3u8` / DASH `.mpd`) dahil —
indirme motoru olarak `yt-dlp` + `ffmpeg` kullanır.

<br clear="right"/>

## Belgeler

| Doküman | İçerik |
|---|---|
| [docs/KURULUM.md](docs/KURULUM.md) | Kurulum — hazır paket ve kaynak koddan |
| [docs/KULLANIM.md](docs/KULLANIM.md) | Kullanım, ayarlar, sorun giderme |
| [docs/EKLENTI-KURULUMU.md](docs/EKLENTI-KURULUMU.md) | Yalnız eklenti kurulumu (zip içine de girer) |

## Hızlı başlangıç

**Hazır paketi indirdiyseniz:** `KUR.bat` → eklentiyi Chrome'a yükle. Bitti.
Ayrıntı için [KURULUM.md](docs/KURULUM.md).

**Kaynak koddan:**

```powershell
dotnet build desktop\VideoDownloader.sln
powershell -ExecutionPolicy Bypass -File scripts\setup-tools.ps1
powershell -ExecutionPolicy Bypass -File scripts\install-native-host.ps1
```

Sonra `chrome://extensions` → Geliştirici modu → **Paketlenmemiş öğe yükle** →
`extension` klasörü.

## Dağıtım paketi üretmek

```powershell
powershell -ExecutionPolicy Bypass -File scripts\build-release.ps1
```

`release\VideoD-1.0.0.zip` (~84 MB) oluşur. Uygulama self-contained derlenir —
karşı tarafta .NET kurulu olmasına gerek yoktur. Paket içeriği:

```
VideoD-1.0.0/
├── app/                              uygulama + köprü (self-contained)
├── VideoD-Chrome-Eklentisi.zip       eklenti (içinde KURULUM.md ile)
├── KUR.bat / KUR.ps1                 tek tıkla kurulum
├── setup-tools.ps1                   yt-dlp + ffmpeg indirici
└── KURULUM.md / KULLANIM.md          belgeler
```

## Mimari

```
Chrome Eklentisi ──▶ Native Messaging Host ──▶ WPF Uygulaması ──▶ yt-dlp + ffmpeg
(video tespiti)      (stdio ↔ named pipe)      (kuyruk + arayüz)   (indirme + birleştirme)
```

- **extension/** — Manifest V3 eklentisi. `webRequest` ile ağdaki `.m3u8`/`.mpd`/video
  isteklerini yakalar, `<video>` etiketlerini tarar, popup'tan indirme gönderir.
- **desktop/VideoDownloader.NativeHost** — Chrome'un başlattığı köprü. Chrome'un
  native messaging protokolünü (4 bayt uzunluk + JSON) konuşur, mesajı `VideoD.Pipe`
  adlı kanala iletir; uygulama kapalıysa başlatır.
- **desktop/VideoDownloader.App** — WPF arayüzü: indirme kuyruğu, ilerleme, hız/ETA,
  iptal, klasör seçimi. Her indirme için `yt-dlp`'yi alt süreç olarak çalıştırır
  (`--concurrent-fragments 8` ile parçalı indirmede paralellik).
- **tools/** — `yt-dlp.exe`, `ffmpeg.exe` (setup betiği indirir).

- **assets/** — logo kaynağı (`scripts\make-logo.ps1` ile yeniden üretilir).

Eklenti kimliği sabittir: `ebmnplmojihclcmmgadpoloaeokgacif` (manifest'teki `key`
alanı sayesinde). Native host kaydı yalnızca bu kimliğe izin verir.

## Kullanım

- Videolu bir sayfada videoyu oynatın; eklenti ikonunda yakalanan akış sayısı belirir.
- Popup'tan **İndir**'e basın → istek uygulamaya gider, uygulama kapalıysa otomatik açılır.
- **Bu sayfayı uygulamayla indir** düğmesi sayfa adresini yt-dlp'ye verir — YouTube
  gibi yt-dlp'nin tanıdığı sitelerde en sağlıklı yol budur.
- Uygulamadaki adres çubuğuna elle URL yapıştırıp da indirebilirsiniz.
- Varsayılan kayıt yeri: `İndirilenler\VideoD` (alt çubuktan değiştirilebilir).

## Otomatik hız merdiveni

Bazı sunucular 8 paralel bağlantıyı fazla agresif bulup engeller. Uygulama bu
durumda başarısız saymaz; kendiliğinden yavaşlayıp yeniden dener:

```
8 bağlantı  →  4 bağlantı  →  2 bağlantı  →  1 bağlantı
   (hızlı)                                    (en yavaş, en uyumlu)
```

2 ve altına inince istekler arasına bekleme de eklenir. Amaç: **hızlı ama
başarısız yerine, yavaş ama biten indirme.** Arayüzde hangi kademede olduğu yazar.

Merdiven yalnızca yavaşlamanın işe yarayabileceği hatalarda çalışır (429, 5xx,
bağlantı kopması, parça indirme hataları). Yavaşlamakla çözülmeyecek hatalarda
(DRM, 404, yetki, bot koruması) boşuna beklemez, ilk denemede durur.

Elle **Yeniden Dene** dediğinizde de kaldığı kademeden devam eder — sunucu 8'i
reddettiyse tekrar 8'den başlamaz.

### Tek bağlantı modu

Merdiveni hiç kullanmak istemiyorsanız üstteki **"Tek bağlantı (yavaş ama en
uyumlu)"** kutusunu işaretleyin. Doğrudan tek bağlantıyla, istekler arasında
beklemeyle indirir — sunucu korumalarına en az takılan mod.

**Not:** Tek bağlantı "oynatma hızında indirme" demek değildir. Video oynatması
beklenmez, segmentler arka arkaya çekilir; hız yine internet bağlantınız kadardır.
Ölçüm: 10.5 dakikalık bir test videosu tek bağlantıda ~1.4 MB/s ile yaklaşık
**1 dakikada** indi — yani gerçek süresinden ~10 kat hızlı. 1 saatlik bir ders
tek bağlantıda bile genelde birkaç dakika sürer, 40-50 dakika değil.

## Bir indirme başarısız olursa

Arayüzde her başarısız iş için iki düğme çıkar:

- **Günlük** — o işe ait tam yt-dlp çıktısını Not Defteri'nde açar
  (`%APPDATA%\VideoD\logs\` altında saklanır). Gerçek sebep buradadır.
- **Yeniden Dene** — `--continue` sayesinde **kaldığı yerden** devam eder,
  baştan başlamaz. Yarım dosyalar (`.part`) korunur.

Sık görülen hatalar arayüzde Türkçeleştirilir; ham hata mesajı aramanıza gerek yok:

| Belirti | Anlamı |
|---|---|
| "DRM korumalı — indirilemez" | Netflix/Disney+ gibi; aşılamaz, kapsam dışı |
| "Bot koruması (Cloudflare)" | Site otomatik erişimi engelliyor; aşılmaz. Sayfa yerine akışı deneyin |
| "Sunucu sayfaya erişimi reddetti (403)" | Sayfa düğmesi yerine listedeki HLS/DASH akışını seçin |
| "Site oturum açmanızı istiyor" | Videoyu tarayıcıda açıp eklentiden gönderin |
| "yt-dlp bu sayfayı tanımıyor" | Popup'taki M3U8/DASH satırındaki İndir'e basın |
| "Ağ bağlantısı koptu" | Yeniden Dene yeterli |

### Sayfa düğmesi mi, listedeki akış mı?

Popup'ta iki farklı yol var ve karıştırmak en sık yapılan hata:

- **"Bu sayfayı uygulamayla indir"** → sayfa adresini yt-dlp'ye verir. YouTube gibi
  yt-dlp'nin *tanıdığı* sitelerde en iyi sonucu verir. Tanımadığı sitelerde
  sayfayı çözemez ve 403 / "Unsupported URL" alırsınız.
- **Listedeki HLS/DASH satırının yanındaki "İndir"** → tarayıcının zaten yüklediği
  video akışını doğrudan ister. yt-dlp'nin siteyi tanımasına gerek kalmaz.

Sayfa düğmesi hata verirse **listedeki akışı deneyin.** Liste boşsa videoyu
tarayıcıda birkaç saniye oynatın (akış istekleri o zaman yakalanır) ve popup'ı
yeniden açın.

**Önemli:** Uygulamayı kapatırsanız süren indirmeler durur (artık kapatmadan önce
uyarı çıkar). Bu, daha önce "sebepsiz hata" gibi görünen durumun en sık nedeniydi.

## Kalite ve seçenekler

Üst çubuktaki açılır listeden: En iyi / 1080p / 720p / 480p / Sadece ses (MP3).
Seçim kaydedilir. Uzun videolarda "En iyi" bazen AV1 gibi çok büyük formatlar
seçebilir; 1080p veya 720p genelde daha hızlı iner ve her oynatıcıda açılır.

Altındaki üç kutu:

- **Chrome oturumumu kullan** — uygulamaya *elle yapıştırdığınız* adreslerde
  Chrome'un çerezlerini okur (giriş gerektiren ders platformları için).
  ⚠️ Chrome **tamamen kapalı** olmalı; açıkken çerez veritabanı kilitlidir ve
  yt-dlp okuyamaz. Bu yüzden eklentiden göndermek her zaman daha güvenilirdir —
  eklenti çerezi Chrome açıkken de, hatta daha isabetli şekilde aktarır.
- **Altyazıları da indir** — varsa altyazıyı indirip MP4'e gömer. Çevrimdışı
  izlerken işe yarar (`tr` ve `en` denenir).
- **Liste ise tamamını indir** — adres bir oynatma listesi/bölüm ise tek video
  yerine tamamını sıraya alır. Bir dersin tüm bölümlerini indirmek için.

## Çevrimdışı izleme için önerilen akış

İnternete eriştiğiniz yerde:

1. Kalite: **720p** (yerden kazandırır, her oynatıcıda açılır)
2. **Altyazıları da indir** işaretli
3. Ders sayfasını Chrome'da açın, videoyu başlatın
4. Eklenti popup'ından gönderin — oturum çerezi böyle en sağlıklı aktarılır
5. Birden çok bölüm varsa **Liste ise tamamını indir** işaretleyip ders/bölüm
   adresini gönderin

İndirme yarıda kalırsa panik yok: **Yeniden Dene** kaldığı yerden devam eder.

## Bilinmesi gerekenler

- **DRM korumalı içerik (Netflix, Disney+ vb.) indirilemez** ve bu uygulamanın
  kapsamı dışındadır. Şifre çözme tarayıcının kapalı CDM bileşeninde, korumalı
  bellek yolunda yapılır; ne eklenti ne de ekran kaydı bu içeriğe ulaşabilir
  (ekran kaydı siyah çıkar). Uygulama DRM tespit ederse bunu açıkça yazar.
- İçerik indirirken site kullanım şartlarına ve telif haklarına uymak size aittir.
- `keys/extension.pem` eklentinin özel anahtarıdır — paylaşmayın; kimlik sabitliği
  yalnızca manifest'teki public key ile sağlanır.
- Host günlüğü (eklenti ↔ uygulama köprüsü): `%APPDATA%\VideoD\host.log`
- İndirme günlükleri (her iş için ayrı): `%APPDATA%\VideoD\logs\`

## Geliştirme notları

- Eklenti dosyalarını değiştirince `chrome://extensions` → yenile düğmesi yeterli.
- C# tarafını değiştirince `dotnet build` yeterli; kayıt defteri yolları exe konumunu
  gösterdiği için yeniden kayıt gerekmez (exe yolu değişmedikçe).
- Yayın (tek klasör dağıtımı) için: `dotnet publish -c Release` sonrası
  `install-native-host.ps1` içindeki yolları publish klasörüne çevirin.
