### 1. Temel Teknoloji Yığını ve Kütüphaneler | Kategori | Kütüphane / Teknoloji | Neden Bu Tercih Edilmeli? | | :--- | :--- | :--- | | **State Management** | `flutter_riverpod` | SOLID'in Dependency Inversion (D) prensibini uygulamak ve servisleri izole etmek için en modern ve güvenli yöntem. | | **Cihaz Keşfi (mDNS)** | `nsd` veya `bonsoir` | Zero-config ağ keşfi için endüstri standardı. TV kendini yayınlar, telefon bulur. | | **Ağ İletişimi** | `shelf` (Local HTTP Server) | TV tarafında raw TCP socket yerine küçük bir REST API (HTTP Server) kurmak hata yönetimini ve loglamayı inanılmaz kolaylaştırır. | | **Video Oynatıcı** | `media_kit` | *Chewie/Video_player yerine kesinlikle bunu kullanmalısın.* libmpv tabanlıdır. HLS (.m3u8), MKV ve özel codec'leri Android TV'de kusursuz oynatır. | | **Link Yakalama** | `receive_sharing_intent` | Mobil cihazda tarayıcıdan "Paylaş" aksiyonunu dinlemek için. | | **Video Extraction** | `flutter_inappwebview` & `html` | Sayfa içindeki gizli `.m3u8` veya `.mp4` linklerini headless (gizli) bir tarayıcıda yakalamak için. | | **Lokal Depolama** | `shared_preferences` | Cihazın "TV" mi yoksa "Mobil" mi olduğunu ilk seçimden sonra hatırlamak için. | --- ### 2. Proje Klasör Yapısı (Clean Architecture) Kodun test edilebilir ve modüler olması için *Feature-First* (Özellik Odaklı) bir Clean Architecture yapısı kurmalıyız: ```text lib/ ├── core/ # Tüm projede ortak kullanılan yapılar │ ├── constants/ # Port numaraları, API endpoint'leri │ ├── error/ # Custom exception sınıfları │ └── network/ # Temel ağ arayüzleri ├── features/ │ ├── setup/ # Cihaz rolü (TV/Telefon) seçim ekranı │ ├── discovery/ # mDNS ile cihaz arama ve eşleşme (Mobil) │ ├── receiver/ # TV tarafı: Local server ve oynatıcı │ └── sender/ # Mobil taraf: Link yakalama ve gönderme └── main.dart # Riverpod ProviderScope ve Init işlemleri ``` Her `feature` (özellik) kendi içinde şu üç katmana ayrılmalıdır (SOLID uygulamasının kalbi): * **domain:** Sadece saf Dart kodları. Arayüzler (`abstract class`), entity'ler. * **data:** Dış dünyayla iletişim. API çağrıları, paket implementasyonları. * **presentation:** UI (Widget'lar) ve State (Riverpod Notifier'lar). --- ### 3. Kritik İş Akışları ve "Best Practice" Yöntemler #### A. İlk Açılış ve Rol Seçimi (Setup) Kullanıcı uygulamayı ilk açtığında karşısına iki dev buton çıkar: "Ben bir Telefonum (Gönderici)" ve "Ben bir TV'yim (Alıcı)". * **Best Practice:** Bu seçim yapıldığı an `SharedPreferences`'a kaydedilir (`role = 'sender' | 'receiver'`). Uygulamanın bir sonraki açılışında `main.dart` bu değeri okur ve kullanıcıyı doğrudan ilgili ana ekrana yönlendirir. #### B. Cihaz Eşleştirme (Discovery - mDNS) Bluetooth yerine aynı ağda **mDNS (Zero-conf)** kullanmak en stabil "Best Practice" yöntemdir. 1. **TV (Receiver):** Uygulama açılır açılmaz arka planda `nsd` ile bir servis kaydeder. Örnek servis adı: `FastWatcher._http._tcp`. Ayrıca `shelf` ile 8080 portunda bir HTTP server dinlemeye başlar (`POST /play`). 2. **Mobil (Sender):** "Eşleş" butonuna basıldığında ağı tarar. Bulunan cihazların IP'sini bir listeye koyar. Kullanıcı TV'sine dokunduğunda IP adresi telefona kaydedilir. #### C. İletişim Protokolü (HTTP üzerinden) Raw Socket'ler veriyi bölebilir veya bağlantı kopmalarında sorun yaratabilir. TV'de mini bir HTTP sunucusu kurmak çok daha "Solid" bir çözümdür. * **Mobil'in Gönderdiği Payload (JSON):** ```json { "url": "https://site.com/master.m3u8", "title": "The Instigators (Opsiyonel)", "timestamp": 1714415045 } ``` * **TV'nin Yanıtı:** `200 OK` (Başarıyla aldım, oynatmaya başlıyorum). #### D. Video Linki Ayrıştırma (Video Extraction) Tarayıcıdan paylaşılan link bir web sayfası olduğunda, içindeki asıl videoyu bulmak için şu hiyerarşi uygulanır: 1. **Headless WebView (En Garanti Yöntem):** Kullanıcı linki paylaştığında, arka planda gizli bir `InAppWebView` açılır. `onLoadResource` veya `shouldInterceptRequest` metodları ile ağ trafiği dinlenir. `.m3u8` veya `.mp4` uzantılı bir istek yakalandığı an sayfa kapatılır ve link TV'ye gönderilir. 2. **Open Graph & Meta Tags:** Sayfa HTML'i `html` paketi ile indirilir. `` veya `