ShowShark Client Features
ShowShark Client is a SwiftUI multiplatform app for iOS, iPadOS, macOS, tvOS, visionOS, and watchOS that connects to a ShowShark Server to browse, stream, and play media.
Platform Support
- iOS (iPhone): Full-featured with swipe gestures, pull-to-refresh, long-press menus, Picture-in-Picture, background audio, and lock screen controls
- iPadOS: Sidebar navigation with server list and media browser split view
- macOS: Native window with sidebar navigation, keyboard shortcuts, media key support, window frame persistence, and single-instance behavior
- tvOS: Focus-based interface with Siri Remote support, card-style layouts, dedicated server management view, top shelf images, and platform-appropriate app icons
- visionOS (Apple Vision Pro): Shares iPad navigation layout with native visionOS appearance (no custom backgrounds)
- watchOS (Apple Watch): Companion app with HLS video/audio playback, server list with Bonjour discovery, media browsing, channel and history sections, Digital Crown volume control, and buffering countdown UI
Server Connection
Discovery & Setup
- Automatic server discovery via Bonjour/mDNS on the local network
- Discovered servers show server name, preferred address (IPv4 listed first), and additional address count (e.g., "192.168.1.100 (+1 more)")
- Address picker when adding a discovered server with multiple IPv4/IPv6 addresses
- IPv6 link-local address support
- Add, edit, and delete saved servers with persistent storage
- Server form: display name, hostname/IP, port (default 18080), password with reveal/hide toggle
- iOS: swipe-to-delete and swipe-to-edit on saved servers
- macOS: swipe delete, context menu for edit/delete
- tvOS: card-based server management view with inline edit/delete buttons and Getting Started help section
- Hostname display sanitization: hides port suffix and IPv6 zone identifiers in the server list
Connection Lifecycle
- Secure WebSocket over TLS connections
- Password-based authentication with device name and persistent device identifier
- Auto-reconnect with incremental backoff (increases by 1 second per attempt, capping at 5 seconds)
- Fast-fail on initial connection when host is unreachable (5-second timeout)
- WebSocket liveness detection: periodic pings with adaptive timeouts detect server crashes and network drops within ~10-12 seconds on LAN, instead of hanging indefinitely
- Graceful server shutdown detection: server sends close notifications so clients are informed immediately rather than timing out
- Connection states: disconnected, connecting, connected, waiting, failed, cancelled, reconnecting
- Visual connection status indicator: colored dot (gray/green/red) or spinner for in-progress states
- Connection failure alert with actionable error messages
- Authentication failure alert
- Media browser stays visible during reconnection if user was previously authenticated
- Requests automatically wait up to 15 seconds for authentication during reconnection (prevents errors on foreground resume)
- Server update notification after login (dismissible, with "Ignore" option to suppress per-version)
Media Browsing
Directory Browser
- Grid-based media browser with dynamic column calculation (responsive to window/screen size)
- Three sections: Channels (subdivided by video/audio/photo), Library (directories and files), History
- Section headers from server-provided directory entries
- Live directory filter: when browsing inside folders, a search icon toggles an inline filter bar for real-time case-insensitive matching against file and folder names
- Pagination with infinite scroll for large directories and iCloud photo albums (100 items per page)
- Auto-refresh every 5 minutes while visible
- Pull-to-refresh on iOS
- Cmd+R keyboard shortcut and toolbar button for manual refresh on macOS/iPadOS
- Breadcrumb navigation (iOS/visionOS) with clickable path segments and home button
- Empty state screens with helpful instructions when no servers or content are available
Grid Items
- Folder entries: gradient background with SF Symbol icon (custom per-location), 16:9 aspect ratio
- File entries: thumbnail image, 16:9 aspect ratio
- Display name resolution: metadata title > display name > raw filename
- Custom location icons sent from server (SF Symbols)
Media Detail View
- File information: name, path, size, duration, media type
- Video track details: resolution, codec, bitrate, frame rate
- Audio track details: codec, channels (Mono/Stereo/5.1/7.1), bitrate, language
- Subtitle track details: language, format
- tvOS: list-based layout with large thumbnail
- Other platforms: scrollable layout with 600px max thumbnail
Video Playback
Player Controls
- Automatic video codec negotiation: detects H.265 (HEVC) hardware decode support at startup and falls back to H.264 when needed
- Intelligent output resolution: defaults to the best resolution your device supports (e.g., 4K on Apple TV 4K, 1080p on Apple TV HD), with a manual 720p/1080p/4K override available
- Source video info displayed as "Input" row in resolution section (codec and resolution)
- Audio track and subtitle track selection before playback
- Play button in toolbar (iOS/macOS) or tvOS top button bar; when a resume position exists, shows a dialog with "Play from beginning" and "Resume from X:XX" options
- Seek bar / scrubber with time display (not on tvOS)
- Auto-hiding controls with timer-based visibility
- In-app volume slider (0-100%) that adjusts player volume without changing system volume, persisted across restarts (excluded on tvOS where the hardware remote controls volume)
Adaptive Bitrate Streaming
- Fully automatic bitrate adjustment -- no manual bitrate or quality controls needed
- The client continuously reports playback health to the server, which adjusts encoding quality in real time
- Starts conservatively and ramps up quickly on fast connections, reaching up to 10 Mbps within about 48 seconds
- Automatically reduces quality to prevent buffering on slower or congested networks
- Resolution-aware bitrate ceilings prevent wasting bandwidth (e.g., a 720p stream won't encode at 4K bitrates)
Resume & Position Tracking
- Auto-save playback position every 10 seconds
- Restarts from the beginning if saved position is within the last 60 seconds of duration
- Play history resume restores the full album or collection context, so playback continues through remaining tracks (not just the single song)
Chapter Navigation
- Chapter list display with expandable chapter picker
- Previous/next chapter buttons with 3-second threshold for previous chapter behavior
- Current chapter indicator
- Starting chapter selection before playback
Subtitle Settings
- User-adjustable subtitle timing delay from -3 to +3 seconds via subtitle settings sheet
- Subtitle font size selection (small, medium, large)
- Subtitle button inline with transport controls (visible during both single video and channel playback)
- tvOS: focus-aware subtitle button with grouped form styling
Playback Contexts
- Single video: standard file playback with File Details button in toolbar (iOS/macOS) or tvOS top button bar
- Channel video: channel program playback with schedule display and auto-advance to next program
Video Rendering
- Hardware-accelerated H.264 and H.265 (HEVC) decoding
- Last frame stays visible during pause and seek (no blank screen flash)
- Display persists through Picture-in-Picture transitions
End-of-Stream Handling
- Single video: dismisses the player
- Channel playback: auto-advances to next scheduled program
- Demo limit detection with user-facing message
Library Navigation from Playback
- "Go to Library" button appears during playback when the media has an associated library entry (movie, show, or album)
- Navigates directly to the movie, show, or album detail view
Platform-Specific Video Behavior
- macOS: Screen sleep prevention, window chrome hidden during playback, click-to-show controls
- tvOS: Inline icon-only button bar at top of pre-playback content for Play, Thumbnails, Library, and File Details; focus-based transport controls; Siri Remote play/pause and directional commands; focus/scroll position preserved on back-navigation
- iOS: Status bar hidden during playback, navigation bar back button hidden during playback
- iOS/macOS: Space bar keyboard shortcut for play/pause
Audio Playback
- Album art display loaded from server
- Repeat modes: Off, All (loop collection), One (loop current track)
- Shuffle: randomized playback order within collection
- Collection-based playback: albums, artists, and folders treated as collections with automatic track advancement
- Track navigation: previous/next track with shuffle awareness
- Scrubber / seek bar with elapsed and remaining time
- In-app volume slider (same as video, persisted)
- Space bar play/pause on macOS/iOS
- macOS: screen sleep prevention during audio playback
- macOS: card-based layout matching iOS design (rounded rect backgrounds, no list dividers)
- tvOS: three-zone layout (shuffle left, transport center, repeat right) with default focus on play/pause
- iOS/macOS: centered playback controls
- Per-buffer peak detection with transparent attenuation to prevent clipping distortion on loud passages
Lyrics
- On-demand synced lyrics during audio playback
- Lyrics persist across track changes: auto-fetches lyrics for the new song without dismissing the view
- Content-switch pattern: lyrics replace album art view with compact transport controls bar
- Song title and artist displayed in lyrics view navigation bar
- Time-synced line highlighting with auto-scroll following the current playback position
- tvOS: each lyric line is individually focusable via the Siri Remote for manual scrolling; manual navigation pauses auto-scroll for 5 seconds before resuming
- iOS/macOS: manual scrolling pauses auto-scroll for 5 seconds before resuming
- Back action hierarchy: dismisses lyrics first, then dismisses playback view (per-platform: custom toolbar back button on iOS/visionOS, onExitCommand on tvOS, Escape key on macOS)
- Plain text lyrics fallback when synced lyrics unavailable
- Source attribution (e.g., "LRCLib")
- In-memory lyrics cache by file path
Now Playing & Media Controls
- Lock screen and Control Center display during music and video playback: title, artist, album, artwork, duration, elapsed time, playback rate
- Lock screen scrubber for both audio and video
- Remote command handling: play, pause, toggle play/pause, next track, previous track (collections), skip forward, skip backward (single file)
- Album artwork displayed on lock screen
- Audio-only session mode for music (optimized for background playback), video mode for video content
- Available on iOS, macOS, and tvOS
- macOS media key support: hardware play/pause key controls ShowShark even when not frontmost
Background Audio (iOS)
- Audio continues playing when the app is backgrounded or the screen is locked
- Server connection stays alive during background audio playback
- Auto-reconnect handles recovery if the connection is interrupted
Picture-in-Picture (iOS)
- Automatic PiP activation when app is backgrounded during video or channel playback
- Play/pause and skip controls in the PiP window
- Seamless UI restoration when returning from PiP to the full app
- Display shared between inline player and PiP (no reload)
Channels
Channel Types
- Video channels: virtual TV with scheduled programming
- Music channels: continuous music with album art and track info
- Photo channels: synchronized full-screen photo slideshows
Channel Listing
- Grid display with live thumbnails and channel names
- Separate sections: Video Channels, Audio Channels, Photo Channels
- Channel thumbnail caching with 5-minute expiration
- Channels sorted alphabetically
Video Channel Playback
- Wraps the standard video player in a channel context
- Auto-advances to next program on stream completion
- Channel schedule display within the player
- Year appended to titles from metadata
Music Channel Playback
- Album art display with progress tracking
- "Up Next" program list showing upcoming schedule
- Auto-advance on playback completion
- Now Playing integration
Photo Channel Playback
- Full-screen slideshow with automatic advancement
- Photo metadata overlay: date taken and reverse-geocoded GPS location
- Tap to toggle controls visibility (chrome hidden by default)
- Screen sleep prevention on all platforms
- tvOS: truly full-screen with hidden navigation bar and edge-to-edge display
TV Guide (Channel Guide)
- 24-hour programming grid with horizontal scrolling
- Current time indicator (red line)
- Video channels only (music and photo channels excluded from guide)
- Program tiles with width proportional to duration
- Thumbnail backgrounds with dark gradient overlay for text readability
- Color-coded borders: blue for now-playing video, purple for music, gray for past/future
- Platform-specific time slot widths (tvOS: 800px, others: 500px)
Program Detail
- Thumbnail, title, channel name, time range, duration, media type
- Video programs: content rating badge, Rotten Tomatoes score, synopsis/overview
- Music programs: artist name, album title
- "Open Player" button for currently playing programs
- tvOS: pushed onto navigation stack instead of presented as sheet, with focus management
Library Search
Search
- Search bar with cancellation of previous in-flight searches
- Search fields: title, overview, genre, actor, year (all enabled by default)
- Result categories: movies, shows, genres, actors, artists, albums, songs, photo albums
- "Music Albums" section name (distinguished from Photo Albums)
- Library stats overview above search: aggregate counts for movies, shows, episodes, artists, albums, songs
- Empty state shows browsable genre sections (Movie Genres, TV Show Genres, Music Genres) as tappable capsule pills, plus recent search history (capped at 10, deduplicated, most-recent-first, with Clear button)
Movie Detail
- Poster/backdrop image
- Title, year, MPAA rating badge, Rotten Tomatoes score
- Overview/synopsis
- Tappable genre pills (navigate to genre browse)
- Cast member cards with profile photos and character names (tappable, navigate to actor filmography)
- "Open Player" button
Show Detail
- Poster/backdrop image
- Title, TV content rating badge, overview
- Tappable genre pills
- Cast member cards with photos (tappable)
- Season selector for quick navigation between seasons
- Season/episode listing grouped by season, episodes tappable to episode detail
Episode Detail
- Title, season/episode label (S01E01 format), duration, overview
- "Open Player" button
- tvOS: auto-focus on play button
Genre Browse
- Genre-scoped browsing by media type: Movies, TV Shows, or Music
- Movies and Shows sections with 16:9 thumbnail grid cards
- Music genre browsing with Artists, Albums, and Songs sections
- Tappable entries navigate to movie, show, album, or artist detail
Actor Browse
- Actor profile photo header (loaded via server)
- Filmography: Movies and Shows sections
- Tappable entries navigate to movie or show detail
Album Detail
- Album art thumbnail
- Title, artist name, year, song count
- "Play All" button
- Track listing grouped by disc number (multi-disc support)
- Individual track tapping starts collection playback from that track
Artist Detail
- Artist name, album count, total track count
- "Play All" button (plays the artist's complete discography)
- Discography section: albums with year and track count, tappable to album detail
Content Discovery
Discovery Modes
- Similar To: Search for a seed title in your library, then view the top 10 most similar items ranked by keyword overlap, genre overlap, cast overlap, year proximity, and rating proximity
- By Feel: Filter your library by time commitment (quick / medium / long / epic) and mood (light & fun, intense, thought-provoking, heartwarming, dark & edgy); when more than 10 candidates match, a side-by-side comparison flow narrows the results down
- By Genre: Browse top 20 titles in a selected genre sorted by rating
Discovery UI
- Wizard flow: media type selection, discovery mode, mode-specific sub-flow, comparison rounds (if applicable), final candidates
- Side-by-side candidate cards with thumbnail, title, year, genre chips, overview snippet, and progress indicator
- Scrollable results with navigation to movie/show detail
- "Find Similar" entry point on movie and show detail views
- "Discover" button in media browser toolbar
- Available on all platforms (iOS, iPad, macOS, tvOS, watchOS)
Photo Viewing
- Full-screen photo display with left/right navigation
- Full-size photo loading at screen resolution
- Adjacent photo prefetching (distant photos released from memory)
- Photo metadata: EXIF date taken and GPS coordinates
- Reverse geocoding of GPS coordinates to "City, State, Country" with caching
- Platform input: macOS arrow keys, tvOS directional commands, iOS/visionOS swipe gestures
- Info bar: filename, position counter (e.g., "3 of 15"), metadata line (date and location)
- iCloud Photo Library support
Thumbnails & Caching
Thumbnail Cache
- Two-tier cache: in-memory (100MB limit) + on-disk (500MB limit)
- 5-minute cache freshness check for channel thumbnails
- Automatic eviction when disk cache exceeds size limit
Thumbnail Loading
- Request batching and deduplication
- Thumbnail sizes: grid (300x200), detail (800x600), person photo (200x300), full photo (screen resolution)
- Default thumbnail offset: 300 seconds into the video
Batch Thumbnails (Scrub Grid)
- Per-minute thumbnail offsets computed from video duration
- Cached thumbnails populate immediately; uncached offsets requested from server in a single batch
- Progressive loading: images appear as each server response arrives
- Tap any thumbnail to view full-resolution or jump to playback at that offset
Playback History
Position Tracking
- Server-backed playback position persistence via periodic and final offset updates
- Positions saved during playback without causing unnecessary UI refreshes
Play History
- Server-backed play history: movies, shows/episodes, and music tracked across all your devices
- Dynamic 16:9 thumbnail grid layout matching Channels and Library sections
- Music history collapsed to one entry per album (displays album title with latest song as subtitle)
- Resuming from play history restores the full album collection, so auto-advance continues through remaining tracks and playback resumes from the saved position
- Channel-watched videos saved to history with playback position
- Play offset shown below title
- Library-link navigation from history items to the corresponding movie, show, or album detail
- Delete individual items: macOS context menu, iOS long-press, tvOS confirmation dialog
First Launch & Onboarding
- Tutorial on first launch (skipped on tvOS)
- Shown only once
- macOS: "Open in Browser" button opens tutorial in Safari
- iOS: "Open in Browser" opens in system browser
- "Done" button to dismiss
About
- App name, version, copyright, and support links (email + website URL)
- Privacy policy and terms of service links
- Open-source license attribution (GStreamer LGPL, SQLite public domain)
- iOS/iPad/Mac: question mark toolbar button on server list opens About sheet
- tvOS: "About ShowShark" button on server management screen
App Updates & Cross-Promotion
- Automatic update detection notifies you when a new version is available
- Deprecated version warnings
- "Other Apps" cross-promotion section in server list sidebar (hidden on tvOS)
Theming & Visual Design
Standard Background
- Dark mode: black base with dark red/orange accent gradient
- Light mode: light neutral with warm accent
- tvOS: slightly brighter for TV viewing distance
- visionOS: no custom background (native appearance)
Platform Styles
- Platform-specific typography (tvOS uses significantly larger sizes for 10-foot viewing)
- Platform-specific spacing for grid layout
Playback View Modifiers
- Status bar hidden during active playback (iOS/visionOS)
- Navigation bar and toolbar hidden during active playback
- Conditional application based on modal vs. navigation presentation
Accessibility
accessibilityLabelon history rows: "Recently played: {title}"- Platform-specific accessibility hints on history items
- Decorative elements (chevrons, icons) hidden from screen readers
- Combined accessibility labels on cast cards: "{name} as {character}"
- Descriptive labels on person photos: "Photo of {name}"
Networking
- Secure WebSocket over TLS with low-latency optimizations for streaming
- HTTP polling transport for watchOS (where direct WebSocket is unavailable)
- Self-signed certificate support for local networks
- Protobuf message serialization
- Rate-limited connection attempts (2-second minimum interval) to avoid overwhelming the server
- Configurable port (default 18080, range 1024-65535)