ShowShark Server Features

ShowShark Server is a macOS application that manages a media library, transcodes video and audio on the fly, and streams content to ShowShark Client apps over the local network.


Networking

  • WebSocket over TLS (WSS) for secure client-server communication
  • Optional plain WebSocket (WS) listener for reverse proxy setups (e.g., Caddy or nginx terminating TLS upstream)
  • Configurable ports for both listeners (default WSS: 18080, plain WS: 18081)
  • Bonjour/mDNS service advertisement for automatic server discovery by clients
  • Persistent server UUID across restarts so clients can identify the server reliably
  • Protocol Buffers (SwiftProtobuf) for all message serialization
  • MessageEnvelope wrapper with request-response correlation IDs
  • 40+ distinct message types across authentication, browsing, playback, thumbnails, channels, library, and lyrics
  • interactiveVideo service class and TCP_NODELAY (Nagle disabled) on all listeners for low-latency streaming
  • Maximum 100 concurrent client connections, 5 per IP address
  • Sequential message receive loop per client with fire-and-forget Tasks for slow operations (playback, thumbnails)
  • HTTP polling server for watchOS clients: POST /login (HTTP Basic Auth, returns bearer token), POST /send (protobuf messages with synchronous responses), GET /poll (25-second long-poll with batched length-prefixed messages), 120-second inactivity timeout with automatic session eviction

Authentication & Security

  • Password-based authentication with device name and device identifier tracking
  • Per-IP authentication throttling with escalating delays (1s, 2s, 4s, 8s cap) on failed login attempts, auto-expiring after 15 minutes
  • Session management with per-connection tracking
  • Known device registration with last-connected timestamps
  • Self-signed TLS certificate generation and keychain storage

Media Library

Scanning & Indexing

  • Recursive media file discovery across configured filesystem locations
  • Movie, TV show, and music library scanning with automatic content classification
  • TV show episode filename parsing: s03e12, s01e01-03 (ranges), e12, 3x12 formats
  • Music filename parsing: 01 - Song Title.mp3, 01. Title.flac
  • Blu-ray disc (BDMV) directory detection and indexing
  • Image files and photo directories automatically excluded from library scanning
  • Duplicate detection via in-memory Set for O(1) path lookups
  • Incremental scanning: cast/genre linking only runs for newly created records

Database

  • SQLite database with actor-based thread safety
  • Tables: movies, shows, episodes, files, artists, albums, songs, genres, people, and linking tables
  • Movie ratings: G, PG, PG-13, R, NC-17, NR, Unrated
  • TV ratings: TV-Y, TV-Y7, TV-G, TV-PG, TV-14, TV-MA, NR
  • Consolidated schema with incremental migration support
  • UNIQUE indexes to prevent duplicate records
  • Batch query methods to eliminate N+1 query patterns

Library Maintenance

  • Orphaned file detection and user-confirmed cleanup
  • Deleted-location cleanup for removed media locations
  • Excluded-directory cleanup
  • Image file cleanup for incorrectly-indexed records
  • Cascading deletion: removing a file cascades to its parent movie/episode/show if no files remain
  • Automatic daily cleanup scheduler (3:00 AM)
  • Multi-field search across titles, overviews, genres, actors, and years (bitmask-controlled)
  • Cross-type results: movies, shows, genres, actors, artists, albums, songs, photo albums
  • Genre-scoped browsing by media type (Movies, TV Shows, Music) via GenreMediaType enum
  • Genre lists fetched in a single request via GetGenreListsRequest (movie, show, and music genres)
  • Music genre browsing with artist, album, and song queries (LIMIT 200, ordered by title)
  • Library stats endpoint (GetLibraryStatsRequest): aggregate counts for movies, shows, episodes, artists, albums, songs
  • Detail queries: movie detail with cast, show detail with seasons/episodes, episode detail, album detail with songs, artist detail with discography, genre media, actor filmography

Metadata Providers

TMDB (The Movie Database)

  • Bearer token authentication
  • Movie and TV show search, detail retrieval with credits
  • Poster and backdrop images
  • Top 10 cast members with profile photos, character names, and ordering
  • US content certification from release dates and content ratings endpoints
  • Genre extraction

OMDB (Open Movie Database)

  • API key authentication (accepts both keys and URLs)
  • Rotten Tomatoes scores
  • MPAA and TV ratings
  • Genre and cast names

Hybrid Metadata Strategy

  • TMDB for images, cast photos, genres + OMDB for Rotten Tomatoes scores and ratings
  • Fallback: TMDB certification endpoints when OMDB is unavailable
  • Rate limiting: 1 request/second per provider (token bucket)
  • Disk-based metadata cache

Music Metadata

  • MusicBrainz for artist and album identification
  • Cover Art Archive for high-quality album art
  • Last.fm as fallback for album art
  • ID3v2, Vorbis Comment, and FLAC tag extraction (artist, album, title, track number, disc number, genre, duration, embedded album art)

Lyrics

  • LRCLib integration for synced lyrics
  • LRC format parsing into timestamped lines
  • Plain text lyrics fallback
  • Song info resolution from DataStore when title/artist not provided in request
  • File-based lyrics caching

Person/Cast Metadata

  • Provider-agnostic storage: external_id + external_source (not TMDB-specific)
  • Person photos proxied through server via virtual path prefix to prevent direct client access to external APIs
  • SSRF protection on image proxying

Video Transcoding

Input Formats

  • Containers: MKV, MP4, MOV, AVI, WebM, MPEG-PS (.vob), MPEG-TS (.ts/.m2ts), plus auto-detect
  • Video codecs: H.264, H.265/HEVC, MPEG-1, MPEG-2, MPEG-4/DivX/Xvid, VC-1, VP8, VP9, AV1
  • Audio codecs: AAC, MP3, AC-3, E-AC-3, DTS, DTS-HD, DTS-HD Master Audio, Dolby TrueHD, FLAC, Vorbis, Opus, LPCM, WMA, MP1, MP2, ALAC

Output

  • Video: H.264 or H.265/HEVC via VideoToolbox hardware encoding (client-selectable)
  • Audio: AAC at 44.1kHz stereo
  • Client-configurable target bitrate, output dimensions (4K/1080p/720p), and encoding quality
  • Dynamic GOP sizing computed from source framerate (3-4 second intervals)

Audio Processing

  • DC offset removal via FIR high-pass filter (audiowsinclimit mode=high-pass cutoff=20 length=501)
  • Channel-aware surround-to-stereo downmix gain compensation: 1-2ch 1.0x, 3-4ch 1.8x, 5-6ch 2.5x, 7+ch 3.0x
  • Audio packet coalescing for all profiles (200ms target, 96KB max) — reduces audio sends from ~31/sec to ~5/sec
  • Float clamping, NaN replacement, E-AC-3 channel-mask muting
  • VBR MP3 special handling for accurate duration queries

Video Processing

  • PAR (pixel aspect ratio) correction to 1:1 via videoscale
  • PTS interpolation for B-frame videos with missing timestamps
  • Subtitle burn-in support (text and bitmap)
  • HDR content detection
  • NAL unit parsing: Annex-B to AVCC/HVCC conversion with VPS/SPS/PPS extraction
  • H.264 and H.265 keyframe detection for stream initialization

Streaming Pipeline

  • Full teardown-and-restart architecture: pause = stop + remember position; resume/seek = start at new position
  • Single code path for seek, resume, reconnection, and initial playback
  • Software pacing: audio and video streams paced to wall clock via PTS
  • Startup transport boost: 5-second initial burst for fast client buffer fill
  • Startup keyframe gating: video waits for first keyframe before emitting; audio gated until video anchor established
  • Adaptive startup buffer sizing computed from actual source framerate and audio packet cadence
  • Direct ClientConnection reference at stream start bypasses per-send actor chain (eliminates ~70 unnecessary actor context switches per second)
  • Nonisolated sendStreamData() on ClientConnection leverages NWConnection.send() thread safety for concurrent video/audio/subtitle Tasks
  • Realtime transcoding performance monitoring: stops session if throughput falls below 70% realtime
  • Legacy AVI compatibility profile for MPEG-4/XviD + MPEG audio containers

Adaptive Bitrate (ABR) Streaming

  • Buffer-based AIMD (Additive Increase / Multiplicative Decrease) controller adjusts encoder bitrate mid-session
  • Client sends PlaybackStatusReport every 2 seconds with buffer level and throughput estimate
  • Buffer zones: <0.5s critical (halve bitrate, bypasses cooldown), 0.5-1.5s low (15% decrease), 1.5-5.0s healthy (increase if throughput headroom, else hold), >5.0s high (15% increase, skips throughput ceiling)
  • Resolution-based max bitrate ceilings: 4K=20 Mbps, 1080p=10 Mbps, 720p=6 Mbps, 480p-and-below=3 Mbps
  • EWMA smoothing on decreases to prevent oscillation; direct application of increases for fast ramp-up
  • 100 kbps quantization, 5% minimum change threshold, 4-second cooldown between adjustments
  • Conservative 2 Mbps starting bitrate; fast connections ramp to ~10 Mbps in ~48 seconds
  • Quality parameter hardcoded to 0.5 server-side
  • target_bitrate=0 in StartPlaybackRequest enables adaptive mode (default); non-zero preserves fixed bitrate
  • Dynamic encoder bitrate adjustment via setEncoderBitrate() on named videoencoder GStreamer elements using g_object_set_property
  • BitrateChangeNotification sent back to client; live encoder bitrate shown in Status tab
  • Per-session ABR controllers keyed by session ID, cleaned up on stop/completion

Automatic Codec Selection

  • Server validates encoder availability via GStreamer element factory before accepting client codec preference
  • Auto-override HEVC to H.264 encoding when source uses software decoding (dav1d, vp9dec, avdec_mpeg2video, etc.) — VideoToolbox HEVC achieves only ~12 fps from CPU memory buffers vs ~162 fps for H.264
  • Override checks actual decoder string rather than maintaining a separate codec list — automatically correct when hardware decode support expands (e.g., AV1 on M3+)

Demo Mode

  • 15-minute stream limit for non-upgraded users
  • Structured end-of-stream notification with reason (DEMO_LIMIT)
  • Cancellable: if server is upgraded before timeout fires, limit is removed

HLS Transcoding (watchOS)

  • GStreamer-based HLS transcoding via GStreamerHLSSession for watchOS clients using AVPlayer
  • HTTP file server for HLS segment delivery with keep-alive connections
  • 2-second target segment duration for fast startup (~2s to first segment vs ~6s at default)
  • Output sized to 198x242 at 400 kbps with letterboxing (aspect ratio preserved via add-borders=true)
  • Real-time pacing via GStreamer clocksync element on video branch (paces pipeline at 1x speed)
  • Explicit demuxer and decoder chains per format (fixes DTS audio corruption from decodebin auto-plugging)
  • Format-specific demuxers: matroskademux for MKV, qtdemux for MP4, with explicit audio decoder chains (dcaparse+avdec_dca for DTS, aacparse+avdec_aac for AAC, etc.)
  • #EXT-X-PLAYLIST-TYPE:EVENT injected into playlists so AVPlayer buffers from start instead of chasing live edge
  • All segments retained on disk (max-files=0, playlist-length=10000) for slow client pacing
  • Wait for first HLS segment before returning URL to client (prevents initial 404s)
  • HLS sessions visible in server Status tab with codec, position, and progress tracking
  • Configurable HLS toggle and port in server Settings

Blu-ray Disc Playback

  • libbluray 1.3.4 integration via Swift actor wrapper for thread-safe C API access
  • BDMV directory detection: checks for BDMV/index.bdmv + BDMV/STREAM/ structure
  • Title scanning with 120-second minimum filter (excludes menus and trailers)
  • Content classification: movie (single or 2x longest title), TV season (multiple similar durations), ambiguous
  • Chapter, clip, video/audio/subtitle stream metadata extraction
  • Multi-clip seamless playback via appsrc feeding of M2TS data
  • M2TS PES pre-scan: detects first video IDR keyframe and audio positions before pipeline start
  • IDR cross-packet scanning: accumulates video PES payload across TS packets
  • Multi-codec keyframe detection: H.264, HEVC, MPEG-1/2, VC-1
  • Segment-direct A/V alignment using gst_segment_to_stream_time for domain-independent content time (eliminates ~1-2s desync from epoch-stripping)
  • Pre-IDR frame dropping to prevent corrupt leading frames after seeks
  • 192-byte M2TS packet handling (4-byte timestamp prefix + 188-byte TS packet)
  • BDMV-specific cache keys for thumbnails
  • Disc size caching to avoid repeated directory tree walks
  • Virtual path convention: #bdmv suffix with optional :titleN for specific titles

iCloud Photos Integration

  • Photos framework integration with authorization management
  • Album browsing: My Albums, Shared Albums, Smart Albums
  • Pagination for large albums (offset/limit)
  • Album search with case-insensitive substring matching (in-memory for Smart Albums)
  • High-quality image fetching with iCloud network access
  • Video export to temporary directory with hash-based filenames
  • EXIF metadata extraction: date taken, GPS coordinates
  • Automatic temp file cleanup on app startup

Thumbnail Generation

  • GStreamer-based video thumbnail generation at specified time offsets
  • Batch thumbnail generation: reuses single pipeline, seeks in sorted order
  • Serialized generation: only one GStreamer thumbnail pipeline runs at a time (FIFO queue)
  • Non-blocking: cache misses spawn background Tasks instead of blocking the message receive loop
  • Album art thumbnails served from DataStore
  • Image thumbnails via ImageIO with hardware-accelerated scaling and EXIF orientation support
  • Person photo thumbnails proxied from TMDB
  • iCloud photo thumbnails via PhotosManager
  • Photo metadata extraction: EXIF date, GPS coordinates (only for full-size views, never grid thumbnails)
  • Disk caching with SHA256-based keys in sharded subdirectories (256 hex-prefix dirs)
  • Consecutive failure detection (3 failures = likely EOS, stops batch)

Channels

Video Channels

  • Virtual TV channels with 24-hour scheduled programming from the media library
  • Content filtering: by genre, actor, movie title, show title, media path, content rating, media type
  • Blacklist support for excluding specific content
  • Programming scheduler with sorted (alphabetical) and randomized ordering modes
  • Anti-repetition logic to avoid scheduling the same content consecutively
  • Hourly schedule refresh via ProgrammingCoordinator
  • JSON persistence of schedules

Music Channels

  • Continuous music playback channels
  • Filtering by artist, album, song, and genre
  • Blacklist support for excluding specific songs

Photo Channels

  • Synchronized photo slideshow channels from filesystem folders and/or iCloud Photo Library albums
  • Deterministic scheduling via SplitMix64 PRNG with seeded shuffle
  • Configurable slide interval (5-60 seconds)
  • All clients show the same photo at the same time
  • Maximum 10,000 items per channel
  • Automatic seed rotation after full collection cycle
  • Hybrid source support: filesystem images + iCloud album assets

Channel Operations

  • CRUD operations for all channel types
  • Channels sorted alphabetically via localizedStandardCompare
  • Channel current program with offset and remaining time
  • Channel thumbnail generation
  • Program guide with time range queries (overview, content rating, Rotten Tomatoes score, artist/album info)

Content Discovery / Recommendation Engine

Discovery Modes

  • Similar To: Multi-factor similarity scoring against a seed title — weighted components: keyword overlap (0.30), embedding cosine similarity (0.25), genre overlap (0.20), cast overlap (0.10), year proximity (0.10), rating proximity (0.05); embedding weight redistributes proportionally when unavailable; returns top 10 most similar items
  • By Feel: Filters library by time commitment (quick/medium/long/epic with media-type-aware runtime thresholds) and mood (light & fun, intense, thought-provoking, heartwarming, dark & edgy) via keyword-to-mood cluster mapping; binary search narrowing when pool exceeds 10 candidates, splitting along highest-quality dimension (keyword cluster, genre, decade, content rating, vote average) each round
  • By Genre: Top 20 candidates in selected genre sorted by vote average

Engine Infrastructure

  • RecommendationEngine actor with session management, 10-minute session expiry cleanup
  • Binary search representative tracking: shownMediaIds Set ensures fresh titles every round
  • Database schema: keywords table, media_keywords junction table, embeddings table, metadata_version column, vote_average columns
  • TMDB keyword and vote average fetching integrated into library scanning with incremental metadata versioning
  • Protobuf schema: recommendation session, pick, and skip message types

Play History

  • Server-backed play history replacing device-local persistence
  • play_history table with per-client, per-file tracking across movies, shows/episodes, and music
  • Music history collapsed to one entry per artist+album via partial unique index (songs without album metadata create individual entries)
  • CRUD operations: add, get, delete, update offset
  • Periodic and final offset updates from client during playback
  • Media context IDs (movie/show/episode/artist/album/song) preserved per entry for library-link navigation
  • Channel-context playback writes history entries like library playback

File Browsing

  • Virtual path system mapping client paths to filesystem paths
  • Root listing with configured locations, custom display names, and custom SF Symbol icons
  • Recursive directory browsing within locations
  • Pagination support (offset/limit) for large directories and iCloud photo albums
  • BDMV directories presented as single playable items (not navigable as folders)
  • Library ID fields (movie_id, show_id, episode_id, album_id) populated on DirectoryEntry during browse responses for client-side library navigation
  • iCloud Photos browsing via __photos__ virtual path intercept
  • Supported file extensions:
    • Video: .mp4, .m4v, .mov, .avi, .mkv, .wmv, .flv, .webm, .mpeg, .mpg, .3gp, .ts, .mts, .m2ts
    • Audio: .mp3, .m4a, .aac, .flac, .wav, .aiff, .ogg, .wma, .opus, .alac
    • Image: .jpg, .jpeg, .png, .heic, .heif, .gif, .tiff, .tif, .webp, .bmp

Server Administration UI

Status Tab

  • Server running/stopped indicator
  • Service status rows for WSS, optional WS, HTTP Polling (with client count), and HLS listeners
  • Active listener ports
  • Active transcoding sessions (video, audio, BDMV, HLS) with live position/duration and encoder bitrate
  • Connected device list with device name, IP address, and connection time
  • Firewall self-diagnostic: detects when macOS Application Firewall silently blocks incoming connections after Xcode rebuild; runs 30 seconds after startup then hourly; alerts user once with fix instructions; auto-clears when resolved
  • Form/Section layout matching macOS System Settings appearance

Locations Tab

  • Add/remove media folders with security-scoped bookmarks
  • Custom display names per location (inline editing)
  • Custom SF Symbol icons per location (searchable picker with ~6,000 system symbols)
  • Alphabetical sorting by display name
  • Orphaned metadata cleanup for deleted locations

Library Tab

  • Trigger and monitor library scans with progress indicator
  • Library statistics: counts for movies, shows, episodes, artists, albums, songs
  • Manual database cleanup with confirmation
  • Library validation: test-transcode indexed video files with live pass/fail progress, persisted results to disk, failure list sheet, mutual exclusion with scan/cleanup operations; validates regular files via GStreamerTranscodingSession and BDMV discs via GStreamerBlurayTranscodingSession with PTS-span criteria (10s video + 10s audio)
  • Empty state instructions when no locations or media are configured

Channels Tab

  • Video, Music, and Photo channel editors with full filter configuration
  • Channel list management (create, edit, delete)
  • Manual schedule refresh

Providers Tab

  • TMDB and OMDB provider configuration with API key entry
  • Two-step type selection flow (Movie & TV Show vs. Music sections)
  • Provider status display
  • Quick link to provider websites
  • Lyrics provider configuration (LRCLib)
  • TMDB API key guidance with step-by-step instructions

Devices Tab

  • Known device list with name, identifier, and last connected time

Settings Tab

  • WSS port configuration with validation
  • Plain WS listener toggle and port
  • HTTP Polling port configuration with cross-port conflict detection
  • HLS service toggle and port configuration
  • Master password management

About Tab

  • App name, version, copyright, and support links (email + website)
  • Log submission: toggle file-based logging with 24-hour auto-disable, daily rolling log files, gzip compression, upload to cloud with reference ID, context sheet for name/email/issue description

Upgrade Tab

  • License status display
  • Purchase flow with Stripe checkout
  • Apple Sign In authentication

Licensing & Payments

  • Sign in with Apple OAuth
  • Server update notifications sent to clients after login

Server Log Gathering

  • File-based log sink (FileLogWriter) with daily rolling files, serial DispatchQueue, and 24-hour auto-disable toggle
  • All AppLogger output mirrored to file when logging is enabled
  • LogGatherer filters log files by timestamp; LogCompressor uses gzip with 20MB max file size validation
  • Upload via LogSubmissionAPIClient to Cloudflare Worker with metadata query parameters
  • 8-character alphanumeric reference ID returned to user with Copy button

Directory Exclusion

  • Exclude specific directories from library scanning while keeping them browsable
  • Security-scoped bookmarks for persistent exclusion access
  • Excluded directories skipped during scanning and cleanup