Radyo Kutsal — Yayın API'si

Canlı ses + çalan parça meta verisi + senkron SRT transkript. Statik dosya + poll mimarisi: sunucuda kalıcı bağlantı yok, sadece CDN-dostu küçük dosyalar.

schemaVersion 1 · base: https://radyo.akil.cloud

Canlı önizleme (yükleniyor…)

Başlık
Bitiş (yerel)
Pozisyon / Süre
Transkript

Genel bakış

Üç adet salt-okunur uç nokta; hepsi GET, Access-Control-Allow-Origin: * (CORS açık), kimlik doğrulama yok. Tümü Apache tarafından statik servis edilir → minimum sunucu yükü, kolay önbellekleme.

Uç noktaİçerikContent-TypeÖnbellek
/radyo.m3u8Canlı ses (HLS, AAC, MPEG-TS segment)application/vnd.apple.mpegurlno-cache
/now.jsonÇalan parça meta verisiapplication/jsonno-cache
/current.srtÇalan parçanın SRT transkriptitext/plain; charset=utf-8parça başına değişir

Segment dosyaları (seg_*.ts) max-age=10 ile önbelleklenir; oynatıcı bunları otomatik çözer.

1 · Ses — /radyo.m3u8

GET Kayan pencereli HLS playlist (AAC 48 kHz stereo, ~4 sn'lik MPEG-TS segmentleri, son 6 segment). Safari yerel oynatır; Chrome/Firefox için hls.js.

<audio id="a" controls></audio>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1/dist/hls.min.js"></script>
<script>
  const a = document.getElementById('a');
  const src = 'https://radyo.akil.cloud/radyo.m3u8';
  if (a.canPlayType('application/vnd.apple.mpegurl')) a.src = src;       // Safari
  else if (window.Hls) { const h = new Hls(); h.loadSource(src); h.attachMedia(a); }
</script>

2 · Meta — /now.json

GET Çalan parçanın anlık durumu. ~2 sn'de bir güncellenir. İstemci 5–10 sn'de bir poll'lamalı; daha sık gerekmez (positionSec ile aradaki süre istemcide hesaplanır).

Şema

AlanTipAçıklama
schemaVersionnumberŞema sürümü (şu an 1).
serverTimestring (ISO-8601 UTC)positionSec'in geçerli olduğu an. Drift düzeltmesi için referans.
serverTimeLocalstringİstanbul saati HH:MM:SS (insan için).
isPlayingbooleanÇalma durumu. false ise zaman alanları null olabilir.
titlestringParça başlığı (boş olabilir).
startedAtstring|nullParçanın başladığı an (ISO UTC).
endsAtstring|nullParçanın biteceği an (ISO UTC).
endsAtLocalstringBitiş İstanbul saati HH:MM.
durationSecnumber|nullParça toplam süresi (sn).
positionSecnumberserverTime anındaki çalma pozisyonu (sn). SRT senkronu için anahtar.
remainingSecnumber|nullKalan süre (sn).
audioobject{ hls, codec, container, sampleRate, channels }.
transcriptobject{ available:boolean, srt:url, format:"srt" }.

Örnek

// /now.json

3 · Transkript — /current.srt

GET Çalan parçanın tam SRT'si (parça değişince atomik güncellenir). transcript.available=false ise içerik boştur. Parça başına bir kez indir (başlık/startedAt değişince yenile), sonra istemcide positionSec ile cue seç.

Senkron tarifi (uygulama/agent için)

HLS sesi ile SRT'yi hizalamak için sunucu saatine güvenmek gerekmez; positionSec yeterli:

// 1) now.json'u 5-10 sn'de bir cek; cektigin ani isaretle:
let basePos = data.positionSec, baseAt = Date.now();
let trackKey = data.title + '|' + data.startedAt;   // parca degisimini boyle anla

// 2) parca degistiyse current.srt'yi YENIDEN indir ve parse et (parca basina 1 kez):
if (trackKey !== lastKey) { srtCues = parseSrt(await (await fetch('/current.srt')).text()); lastKey = trackKey; }

// 3) her karede gecerli pozisyonu hesapla ve cue sec:
const elapsed = basePos + (Date.now() - baseAt) / 1000;            // sn
const cue = srtCues.find(c => elapsed >= c.startSec && elapsed < c.endSec);

SRT zamanları parça başından (0) itibarendir; elapsed de öyle → doğrudan karşılaştırılır. Drift, bir sonraki now.json poll'unda otomatik düzelir.

Notlar