Home/ Work/SpletnaTV
Lead dev · 2020 — 2023 · Streaming

SpletnaTV

Native Android and iOS apps for a Slovenian web TV service — live streams, VOD catalogue, multi-source video playback, and category-based browsing — all backed by WordPress REST API and the RTV SLO media platform.

Role Lead Developer
Duration 2020 → 2023
Platforms Android · iOS
Backend WordPress REST API · RTV SLO AVA
Domain Streaming · Media · Mobile
Platforms shipped
2 / 2
Android + iOS
Video sources
3
ExoPlayer · YouTube · RTV HLS
Content categories
8
browsable, paginated
Push infrastructure
FCM + PN
Firebase + custom broker

Overview

As lead developer on both platforms, I owned the full build — from architecture decisions and API integration down to player lifecycle and push notifications. SpletnaTV is a Slovenian web TV service offering live streams, a VOD catalogue, and content spanning eight editorial categories (news, sports, culture, music videos, children’s programming, and sign-language broadcasts).

The Android app — written in Kotlin with Jetpack Navigation — pulls content from a WordPress REST backend and surfaces it as a paginated, category-browsable feed. Tapping any item resolves the correct video source at runtime: a direct HLS/MP4 stream via ExoPlayer, a YouTube embed via the official YouTube Android Player API, or a DRM-protected recording from the RTV SLO AVA platform that requires a live JWT exchange before playback begins.

The iOS companion app was delivered in Swift 5 / UIKit targeting iOS 16.4, providing feature parity on Apple devices. Firebase (Analytics, Crashlytics, FCM) runs across Android, complemented by a secondary push notification broker for reliability on constrained devices.

Architecture

~/spletnatv/architecture/system-map.svg
01 — CLIENT APPSAndroid AppKotlin 1.3 · ExoPlayerRetrofit2 · OkHttp3iOS AppSwift 5 · UIKitiOS 16.4+API gateway layerWordPress REST API · wp-json/wp/v2/posts · categories · searchRTV SLO AVA · JWT token exchange → adaptive HLS (hls_sec)YouTube Data API · video ID extraction02 — MEDIA & CONTENT BACKENDSWordPress CMSposts · VOD catalogueRTV SLO AVADRM · HLS · JWTYouTubeembeds · Android APIFirebaseFCM · Analytics · CrashJsoup HTML sanitiser · Picasso image loader · debounced WP search · paginated feeds · push notifications (FCM + broker)03 — UTILITIES

Reading the diagram: Android (Kotlin/ExoPlayer) and iOS (Swift/UIKit) apps talk through a unified API gateway layer that wraps three backends: the WordPress CMS for posts and VOD metadata, the RTV SLO AVA platform for DRM-protected HLS streams (resolved via a two-step JWT exchange), and YouTube for embedded content. Firebase handles push, analytics, and crash reporting. A Jsoup sanitiser strips social widgets and iframes from WordPress HTML before it reaches the WebView.

Phone mockup

SpletnaTV🔍NOVICE
03 What I delivered · challenges solved

Six things shipped,
three hard ones solved.

Key contributions

  • Built the Android app end-to-end in Kotlin — navigation architecture, multi-source player logic, paginated feeds.
  • Integrated three video backends: ExoPlayer for direct HLS/MP4, YouTube Android Player API, and RTV SLO AVA for DRM-secured streams with JWT token exchange.
  • Wired the WordPress REST API (/wp-json/wp/v2/) for posts, categories, and full-text search with debounce.
  • Connected RTV SLO's AVA platform (api.rtvslo.si/ava/) — fetching JWT tokens per recording and resolving the adaptive hls_sec stream URL.
  • Built debounced real-time search (1 s delay, 3-character minimum) over the WP API.
  • Configured Firebase Analytics, Crashlytics, and FCM push notifications; integrated a second push broker for custom delivery.
  • Delivered the iOS companion app in Swift 5 / UIKit targeting iOS 16.4.

Challenges solved

  • Three heterogeneous video sources — a direct CDN stream, YouTube embeds, and DRM-protected RTV SLO content — required branching player logic in a single detail screen.
  • RTV SLO streams required a two-step token dance: fetch a JWT via one endpoint, then resolve the adaptive HLS URL via a second — all before the user taps play.
  • WordPress content contained mixed HTML (iframes, gallery blocks, social share widgets) that needed server-side stripping with Jsoup before rendering in a WebView.
The hardest part wasn't streaming — it was unifying three completely different video sources behind a single tap. Each had its own auth model, URL format, and failure mode.
Davor Majc, Lead Developer / SpletnaTV
04 Tech stack

What's under the hood.

KotlinSwiftExoPlayerYouTube Player APIRetrofit2OkHttp3JsoupPicassoWordPress REST APIHLSFirebase FCMJetpack Navigation
Let's talk

Pripravljeni popraviti, zgraditi
ali skalirati?

30 minut, z mano osebno. Preberem vaš sistem kot dnevniško datoteko in povem, kaj bi naredil najprej. Brez prezentacij, brez prodajnega lijaka.

Davor Majc, ustanovitelj, Numen

What you get on call
→ enostranska diagnostika
→ 2–3 obliki rešitve, razvrščeni po učinku
→ okvirni strošek + časovnica za vsako
→ da/ne — ali sem prava izbira
+386 40 828 474 · Blejska Dobrava, SI