Geliştirici, API ve mobil
Dalgova bir radyo sitesinin üstüne sonradan eklenmiş paneller değil: rotasyon motoru, eşzamanlı akış hesabı, istek kuralları, reklam dağıtımı ve eğer-ise kuralları tek bir TypeScript çekirdeğinde. Site, yönetim paneli, DJ stüdyosu, reklam veren paneli ve mobil uygulama bu çekirdeği ve aynı API istemcisini paylaşır.
Paylaşılan çekirdek
// apps/web/src/lib/api.ts · apps/mobile/src/api.ts
export const api = new MockAdapter({ depo, kanal, tohum, cihaz }) // demo: tarayıcıda / cihazda
// export const api = new HttpAdapter({ taban, ws: 'wss://…/v1/olaylar', jeton }) // kurulum: tek satır
const d = useDurum() // okuma
await api.yap('istekGonder', { kanal: 'pop', parca: 'p007', takma, ithaf }) // yazma — web ve mobilde aynı
const s = simdiCalan(d, 'pop', Date.now()) // herkes aynı saniyeyi duyarAPI sözleşmesi
Okuyucu yayındaki openapi.yaml dosyasını tarayıcıda ayrıştırır: etiket grupları, şema gezgini, örnek istek/yanıt, tek tıkla curl. Güvenlik: Bearer JWT, rol kapsamları (yönetim, program, müzik, reklam, moderatör, stüdyo, reklam veren).
Gerçek zamanlı olay sözlüğü
Her değişiklik bir olaydır: { t: "islem", ad, arg, simdi, kim, idler }. Alan taraflar aynı saf işlemi aynı kimliklerle uygular; demoda sekmeler arasında BroadcastChannel, kurulumda wss://…/v1/olaylar.
| Olay | Örnek yük | Nerede görünür |
|---|---|---|
istekGonder | { kanal: 'pop', parca: 'p007', takma: 'Gece Kuşu', ithaf: 'Moda ekibine' } | Stüdyo istek kutusu · Panel › İstek hattı |
istekKarar | { istek: 'i…', karar: 'onayla', ithafOnay: true } | Site: “14:32’de çalacak” · dinleyici bildirimi · kuyruk |
anketBaslat | { soru: 'Akşam hangi kanal?', secenekler: ['Pop', 'Gece'], sureDk: 120 } | Site köşesinde kayan anket · Stüdyo canlı sonuç |
anketOyVer | { anket: 'a1', secenek: 's2' } | Stüdyo ve panelde oy sayısı |
sohbetGonder | { kanal: 'gece', takma: 'Liman', metin: 'Bu set çok iyi 🎧' } | Site sohbet odası · Stüdyo sohbet izleme · Moderasyon |
sohbetSil | { mesaj: 'm…', kim: 'Ece Tamer' } | Site ve stüdyodan anında kaybolur |
mikrofon | { kanal: 'pop', acik: true, dj: 'dj…' } | Site: CANLI — DJ stüdyoda · program kartı ışığı |
temaAyarla | { tema: { vurgu: '#F2683C' } } | Sitenin vurgu rengi anında |
kampanyaOlustur | { kampanya: { tur: 'spot', ad: '…', kanallar: ['pop'] } } | Panel › Reklam onay kuyruğu · yönetici bildirimi |
kampanyaKarar | { kampanya: 'k…', karar: 'onayla' } | Reklam veren bildirimi · otomasyon kuşağa yerleştirir |
kayitKaydet | { tablo: 'programlar', kayit: { id: '…', bas: '20:00' } } | Site yayın akışı ve geri sayım |
gec | { kanal: 'pop' } | Bütün dinleyicilerde sıradaki öğe başlar |
kuyrukEkle | { kanal: 'pop', tur: 'parca', ref: 'p011' } | Site “Sırada” listesi · stüdyo kuyruğu |
otomasyonAdimi | { dinleyici: 3, kanalDinleyici: { pop: 2 } } | Otomasyon günlüğü · reklam kuşakları · kurallar (lider sekme 4 sn’de bir) |
Diğer olaylar: sohbetTepkisohbetSikayetparcaBegenprogramHatirlatdinleyiciAyarbildirimOkubannerGosterimkuyrukSiralakuyrukSilreklamKusagiSimdidjMesajstudyoNotkayitSilparcaIceAktaranketBitirfaturaKessohbetGeriAlsohbetSustursohbetAyarKaydetistekKurallariKaydetrotasyonKaydetsablonKaydetayarKaydetkuralAktifsaglikOlaybildirimGonderbultenTaslakozelYayinPlanla
Canlı olay akışı tarayıcıda açılır.
Metadata dene
Akıştan gelen herhangi bir “Sanatçı - Parça” metnini yazın: başlık çözülür, iTunes Search API’de aranır, sanatçı + parça normalize edilerek güven skoru hesaplanır, kapaktan ışık paleti çıkarılır. Çalar aynı adımları her şarkı değişiminde uygular.
Gömülebilir çalar
Radyonuzu başka bir siteye (belediye, mekân, sponsor, blog) tek satırla koyun: canlı şarkı bilgisi ve kapakla kompakt çalar.
<iframe src="https://radyov1.briefikir.com.tr/gomulu?kanal=pop&tema=gece" title="Dalgova canlı yayın" width="100%" height="152" style="border:0;border-radius:18px;max-width:520px" allow="autoplay; encrypted-media" loading="lazy"></iframe>
<script src="https://radyov1.briefikir.com.tr/gomulu.js" data-kanal="pop" data-tema="gece" defer></script>
Mobil yol haritası
- Ortak çekirdek
Rotasyon, eşzamanlı akış, istek kuralları, program ve geri sayım hesapları — web ile paylaşılıyor; vitest testleri geçiyor.
- Expo iskeleti
Dinle, Kanallar, Akış ve İstek sekmeleri; AsyncStorage depolu aynı MockAdapter. Tip denetimi monorepo içinde geçiyor.
- 3Yerel çalar
react-native-track-player sürücüsü hazır eşlemeyle bağlanır: kilit ekranı, CarPlay / Android Auto, arka planda çalma, kulaklık düğmeleri.
- 4Bildirim ve mağaza
İstek onayı ve program hatırlatması için push (APNs/FCM), EAS derlemesi, TestFlight ve Play iç testi.
Teknik ekipler için sık sorulanlar
Kendi Icecast ya da Shoutcast yayınımızı bağlayabilir miyiz?
Evet. Yönetim paneli › Kanallar ekranında akış adresini (Icecast, Shoutcast ya da HLS) ve metadata kaynağını (ICY, Icecast status-json, Shoutcast v2 ya da özel JSON) girersiniz. Çalar o akışı çalar, başlığı “Sanatçı - Parça” olarak çözer ve kapağı güven skoruyla eşleştirir.
Mobil uygulama ayrı bir yazılım mı olacak?
Hayır. iOS ve Android uygulaması web ile aynı çekirdeği (rotasyon motoru, eşzamanlı akış hesabı, istek kuralları, program ve geri sayım hesapları) ve aynı API istemcisini kullanır. Yalnız ekran katmanı ve ses sürücüsü (react-native-track-player) yerel yazılır.
Paneller birbirini nasıl anında görüyor?
Her değişiklik bir işlemdir (istekKarar, temaAyarla, kampanyaKarar…). İşlem adı ve argümanı olay olarak yayılır; site, yönetim paneli, DJ stüdyosu ve reklam veren paneli aynı saf fonksiyonu uygular. Demoda sekmeler arası BroadcastChannel, kurulumda WebSocket kullanılır.
Apple kapaklarını kullanmak serbest mi?
iTunes Search API kapak ve 30 saniyelik önizlemeyi tanıtım amaçlı gösterime izin verir; kapak sunucuda depolanmaz, yanında Apple Music bağlantısı verilir. Eşleşme güveni düşükse istasyonun kendi lisanslı görseli gösterilir.
