A free, no-account podcast player. Search Apple Podcasts, paste any RSS feed or YouTube link — stream, resume, queue and download episodes for offline listening. Vite + strict TypeScript frontend, optional Cloudflare Worker backend, installable as a PWA / Microsoft Store / Google Play app.
"Sinyal" design — warm charcoal surfaces, an amber "radio dial glow" accent, and a signature frequency-line waveform motif. Navigation is a bottom tab bar (mobile) / left sidebar (desktop) across four sections — Home (continue-listening + subscriptions), Search, Library (subscriptions/downloads) and Settings — with a full-screen Now Playing sheet for transport, sleep timer, speed and queue access.
▶ Live: https://iacbi.github.io/seseri/ · 🪟 Windows app: download the installer
Language / Dil: English · Türkçe
| 🔍 Podcast search | by name, Apple Podcasts link, or a direct RSS feed URL |
search by name (channels/playlists/videos appear in results) or paste a link; audio streams through the Worker (Innertube + range-aware proxy), which is ad-free and keeps playing with the screen off. There is no iframe fallback: a video with no resolvable audio stream says so rather than quietly playing ads that stop when the phone locks. Measured on podcast/talk content, ~95% of videos resolve to audio (scripts/yt-resolve-rate.cjs); music-label videos resolve far less often. Channels and playlists are listed through the same Innertube session — ~150 episodes on average against the deployed Worker, falling back to YouTube's Atom feed (newest ~15) when it cannot page, and saying so either way |
|
| 📥 Offline episodes | downloads live in the Cache API and play (and seek) with no connection; feeds are cached in IndexedDB and refresh in the background (stale-while-revalidate) |
| 🧾 Play queue | queue any episode as "up next" — the queue wins over list order; own page under Queue |
| 🎧 Mini transport | leaving a feed keeps playing; the persistent dock carries skip/play controls (plus prev/next & speed on wide screens) and a seekable progress line — the chevron expands the full Now Playing sheet |
| 🌊 Frequency-line scrubber | signature waveform motif — drag-to-seek hero scrubber in Now Playing, animated line on the mini player while playing |
| 🎛 Now Playing sheet | full-screen (mobile) / floating panel (desktop): play/pause, prev/next, skip, speed 0.5×–2.5×, sleep timer, resume position, episode notes |
| 🌙 Sleep timer | presets or any duration, or stop at the end of the episode; live countdown, +5 min, gentle fade-out, pauses with playback and survives a reload |
| 🖼 Sharp artwork | the right rendition is requested per surface, so covers are never upscaled from a thumbnail; the Now Playing background can pick up the cover's dominant colour (toggle in Settings → Appearance) |
| 🖥 Desktop layout | ≥900px swaps the tab bar for a persistent left sidebar (Home/Search/Library/Settings) |
| ⭐ Subscriptions | star podcasts; live in Library; OPML import/export + JSON backup |
| 🎨 Themes | Auto (system), Dark, Light, OLED Black; 7 accent colors (amber "dial glow" default) |
| 🌍 Multilingual | TR / EN / DE / FR / ES / AR / JA / RU (incl. RTL) |
| 📲 Installable | PWA with maskable/monochrome icons, shortcuts, store screenshots |
| ♿ Accessible | keyboard-operable views, aria-live status/busy states, focus management on navigation, prefers-reduced-motion |
Active while a podcast feed or the Now Playing sheet is open (not while typing in a field):
| Key | Action |
|---|---|
Space |
Play / pause |
← / → |
Seek back / forward |
↑ / ↓ |
Previous / next episode |
Home / End |
Jump to the start / end of the episode |
Esc |
Close the Now Playing sheet |
? |
Show the shortcut list |
npm install # once
npm run dev # http://localhost:5199
# optional backend (feed/iTunes proxy + YouTube resolution)
npm --prefix worker install # once
npm run worker:dev # http://127.0.0.1:8787The client tries the Worker first (VITE_API_BASE, see .env.development).
Falling back to public CORS proxies is opt-in (Settings → Privacy, off by
default): those operators would see every feed URL opened, and the app races
three of them and parses whichever answers first.
| Script | What it does |
|---|---|
npm run dev / build / preview |
Vite dev server / production build / serve dist |
npm test |
Vitest unit suites (parser, OPML, i18n completeness, proxy chain, formatters) |
npm run lint / typecheck / format |
ESLint · tsc --noEmit · Prettier |
npm run worker:dev / worker:test |
wrangler dev · Worker handler tests |
npm run verify |
lint + typecheck + tests + build + worker typecheck/tests |
node scripts/smoke-p3-offline.cjs |
headless-Edge smoke: download → offline reload → playback |
node scripts/smoke-p4-worker.cjs |
smoke: real RSS through the local Worker (needs worker:dev) |
node scripts/smoke-p5-mini.cjs |
smoke: mini player, queue, back-navigation |
node scripts/icons.cjs |
regenerate all PNG icons from public/icons/seseri.svg |
node scripts/store-shots.cjs |
regenerate manifest/store screenshots |
.
├── index.html # Vite entry (CSP, meta, manifest link)
├── src/
│ ├── app.ts # boot & wiring
│ ├── lib/ # format helpers, safe DOM/text utils, artwork rendition URLs (art.ts)
│ ├── feeds/ # iTunes / RSS / input parsing / proxy chain / resolveFeed /
│ │ # show notes (HTML→text), credential-URL guard for private feeds
│ ├── youtube/ # Worker client (list/search/audio) + Atom fallback
│ ├── player/ # audio engine, media session, sleep timer, offline downloads
│ ├── state/ # signals: settings, queue, now-playing, sleep timer
│ ├── storage/ # localStorage (legacy keys), IndexedDB, OPML
│ ├── ui/
│ │ ├── playback-controller.ts # headless playback session, shared by every view
│ │ ├── views/ # home, search, library, podcast, queue, settings, now-playing
│ │ ├── views.ts # view registry (show/hide, focus hand-off)
│ │ ├── nav.ts # tab bar / sidebar controller
│ │ ├── router.ts # ?podcast= / ?rss= / ?yt= / ?view= ↔ history
│ │ └── shell.ts, theme.ts, mini-player.ts, waveform.ts, art-tile.ts, ambient.ts,
│ │ sleep-control.ts, shortcuts.ts, number-prompt.ts, toast.ts, confirm.ts, …
│ ├── i18n/ # 8 languages, compile-time key completeness
│ ├── styles/
│ │ ├── tokens.css, themes.css, base.css, layout.css, controls.css,
│ │ │ overlays.css, signal-line.css # design-system layers
│ │ ├── views/ # one stylesheet per view (home, search, library, podcast,
│ │ │ # queue, settings, now-playing)
│ │ └── index.css # barrel import
│ └── sw.ts # service worker (injectManifest)
├── worker/ # Cloudflare Worker API (Hono): /v1/feed /v1/itunes /v1/yt/*
├── public/ # manifest, icons (incl. maskable/monochrome), screenshots,
│ # privacy-policy, 404
├── scripts/ # icon/screenshot generators + headless smoke tests
└── docs/ # TESTPLAN, STORE guide, reference screenshots
worker/ is a Cloudflare Worker (free tier friendly): RSS/iTunes proxying with
edge caching and SSRF guards, plus YouTube listing, search and stream
resolution from a single Innertube session. Deploy with npx wrangler deploy,
then set VITE_API_BASE to the workers.dev URL at build time. See
docs/STORE.md for the full release pipeline.
- Windows: a Tauri v2 shell (
desktop/) wraps the live site in WebView2 — a ~4 MB NSIS installer published on GitHub Releases; the app updates itself with every web deploy. - Google Play: TWA package produced from the live PWA with PWABuilder.
- Step-by-step release guide: docs/STORE.md.
No analytics, no accounts. Settings/progress stay in localStorage; downloads
stay in your browser's Cache API. Feed URLs that carry a private/subscriber
token (Patreon, Memberful, Substack-style) are never sent to the public CORS
proxies — they only go through the app's own Worker, and fail with a clear
message if none is configured; ordinary public feeds are unaffected. See
public/privacy-policy.html.
𝓐.𝓒.𝓑 — bozdogancanahmet@gmail.com · MIT © 2026
Ücretsiz, üyeliksiz podcast dinleyici. Apple Podcasts'te ara, RSS veya YouTube linki yapıştır — çal, kaldığın yerden devam et, kuyruğa ekle, bölümleri çevrimdışı dinlemek için indir. Vite + strict TypeScript ön yüz, isteğe bağlı Cloudflare Worker arka ucu; PWA / Microsoft Store / Google Play uygulaması olarak kurulabilir.
"Sinyal" tasarımı — sıcak antrasit yüzeyler, kehribar "radyo kadranı" vurgusu ve imza niteliğindeki frekans-çizgisi dalga-form motifi. Gezinme; alttan sekme çubuğu (mobil) / soldan kenar çubuğu (masaüstü) olmak üzere dört bölümden oluşur — Ana Sayfa (kaldığın yerden devam et + abonelikler), Ara, Kütüphane (abonelikler/indirilenler) ve Ayarlar — ayrıca oynatma, uyku zamanlayıcısı, hız ve kuyruğa erişim için tam ekran Şimdi Çalıyor paneli.
▶ Canlı: https://iacbi.github.io/seseri/ · 🪟 Windows uygulaması: kurulumu indir
| 🔍 Podcast arama | isim, Apple Podcasts linki veya doğrudan RSS URL'si |
isimle ara (kanal/playlist/videolar sonuçlarda listelenir) veya link yapıştır; ses Worker üzerinden akar (Innertube + range destekli proxy) — reklamsız ve ekran kapalıyken de çalar. Iframe yedeği yoktur: sesi çözülemeyen video bunu açıkça söyler, sessizce reklam çalıp telefon kilitlenince susmaz. Podcast/konuşma içeriğinde videoların ~%95'i sese çözülür (scripts/yt-resolve-rate.cjs); müzik videolarında oran çok daha düşüktür. Kanal/playlist listelemesi de aynı Innertube oturumundan gelir — canlı Worker'da ortalama ~150 bölüm; sayfalanamadığında YouTube Atom feed'ine (son ~15) düşer ve her iki durumda da bunu belirtir |
|
| 📥 Çevrimdışı bölümler | indirilenler Cache API'de yaşar, bağlantısız çalar ve sarar; feed'ler IndexedDB'de önbelleklenir, arka planda tazelenir |
| 🧾 Kuyruk | bölümü "sıradaki" olarak işaretle — kuyruk, liste sırasından önce gelir; kendi sayfası Kuyruk görünümünde |
| 🎧 Mini transport | feed'den çıkınca çalma sürer; kalıcı dock üzerinde atlama/oynat kontrolleri (geniş ekranda önceki/sonraki ve hız) ve dokunarak sarılabilir ilerleme çizgisi — ok simgesi tam Şimdi Çalıyor panelini açar |
| 🌊 Frekans-çizgisi dalga-form | imza motif — Şimdi Çalıyor panelinde sürüklenebilir kahraman dalga-form, çalarken mini oynatıcıda animasyonlu çizgi |
| 🎛 Şimdi Çalıyor paneli | tam ekran (mobil) / yüzen panel (masaüstü): oynat/duraklat, önceki/sonraki, atlama, 0.5×–2.5× hız, uyku zamanlayıcısı, kaldığın yerden devam etme, bölüm notları |
| 🌙 Uyku zamanlayıcısı | hazır süreler veya istediğin süre, ya da bölüm sonunda dur; canlı geri sayım, +5 dk, yumuşak sesle kısılma, duraklatınca durur ve sayfa yenilenince kaybolmaz |
| 🖼 Net kapak görselleri | her yüzey için doğru çözünürlük istenir, kapaklar küçük bir görselden büyütülmez; Şimdi Çalıyor arka planı kapağın baskın rengini alabilir (Ayarlar → Görünüm'den kapatılabilir) |
| 🖥 Masaüstü düzeni | ≥900px'te sekme çubuğu yerini kalıcı soldan kenar çubuğuna bırakır (Ana Sayfa/Ara/Kütüphane/Ayarlar) |
| ⭐ Abonelikler | yıldızla; Kütüphane'de yaşar; OPML içe/dışa aktarma + JSON yedek |
| 🎨 Temalar | Otomatik (sistem), Koyu, Açık, OLED Siyah; 7 vurgu rengi (varsayılan kehribar "kadran ışıltısı") |
| 🌍 Çok dilli | TR / EN / DE / FR / ES / AR / JA / RU (RTL dahil) |
| 📲 Kurulabilir | maskable/monochrome ikonlu PWA, kısayollar, mağaza görselleri |
| ♿ Erişilebilir | klavyeyle kullanılabilir görünümler, aria-live durum/busy, gezinmede odak yönetimi, prefers-reduced-motion |
Bir podcast feed'i ya da Şimdi Çalıyor paneli açıkken etkindir (bir alana yazarken değil):
| Tuş | İşlev |
|---|---|
Space |
Oynat / duraklat |
← / → |
Geri / ileri sar |
↑ / ↓ |
Önceki / sonraki bölüm |
Home / End |
Bölümün başına / sonuna git |
Esc |
Şimdi Çalıyor panelini kapat |
? |
Kısayol listesini göster |
npm install # bir kez
npm run dev # http://localhost:5199
# isteğe bağlı arka uç (feed/iTunes proxy + YouTube çözümleme)
npm --prefix worker install # bir kez
npm run worker:dev # http://127.0.0.1:8787İstemci önce Worker'ı dener (VITE_API_BASE, bkz. .env.development),
ulaşamazsa halka açık CORS proxy'lerine düşmek isteğe bağlıdır (Ayarlar →
Gizlilik, varsayılan kapalı): bu operatörler açılan her feed adresini görür ve
uygulama üçünü yarıştırıp ilk cevabı ayrıştırır.
- Windows:
desktop/altındaki Tauri v2 kabuğu canlı siteyi WebView2 içinde açar — ~4 MB'lık NSIS kurulumu GitHub Releases'te; uygulama her web dağıtımıyla kendini günceller. - Google Play: canlı PWA'dan PWABuilder ile TWA paketi.
- Adım adım rehber: docs/STORE.md.
Analitik yok, hesap yok. Ayarlar/ilerleme localStorage'da, indirilenler
tarayıcının Cache API'sinde kalır. Patreon / Memberful / Substack tarzı özel/
abone anahtarı taşıyan feed URL'leri herkese açık CORS proxy'lerine asla
gönderilmez — yalnızca uygulamanın kendi Worker'ı üzerinden geçer; Worker
yapılandırılmamışsa net bir hata mesajıyla başarısız olur. Sıradan herkese
açık feed'ler bundan etkilenmez. Bkz.
public/privacy-policy.html.
𝓐.𝓒.𝓑 — bozdogancanahmet@gmail.com · MIT © 2026