All notable changes to this project will be documented in this file.
- Pre-rendering (First-Frame Decode Ahead of Display)
- Added
FastPixPreRenderManager(singleton viaFastPixPreRenderManager.shared, or instantiate directly) to decode and retain the first displayable frame of an upcoming playlist item on a shadowAVPlayer, so promoting that item to the visible player is flash-free instead of showing a black gap while the first frame decodes. - Pre-rendering is opt-in and OFF by default. Enable it with
isPreRenderEnabled = trueon the player; while it is false no shadow player is created and no decoder or GPU resources are used. - Introduced
setupPreRendering()to lazily create the manager and wire it toPreloadManagerfor the composition path. Safe to call repeatedly; a no-op unlessisPreRenderEnabledis set. - Introduced
preRender(playerItem:identifier:)to schedule pre-rendering for a single item (use theplaybackIdas the identifier so the SDK can retrieve it with the same key), andpreRender(items:)to schedule several at once. - Introduced
getPreRenderedItem(for:)for a non-consuming check that returns a fresh, ready-to-attachAVPlayerItemonly once the first frame has actually been decoded, andnilotherwise. - Introduced
consumePreRenderedItem(for:)to tear down the shadow pipeline, release the retained frame, and return a brand-newAVPlayerItem. Every vended item is freshly constructed from the source URL and is never bonded to the shadow player, so AVFoundation's single-owner rule cannot be violated. - Introduced
firstFramePixelBuffer(for:)to retrieve the retained first frame as aCVPixelBuffer, usable as a one-frame bridging poster on the visible layer to mask the real item's first decode. - Introduced
preRenderStatus(forId:)to query progress — available both on the manager and directly on the player — andcancel(for:)on the manager, mirrored bycancelPreRender(forId:)on the player, to abandon an in-flight or ready pre-render and release its resources. - Introduced
clearAll()onFastPixPreRenderManagerto release every entry at once — call it indeinitalongside the preload and precache cleanup. - Introduced
PreRenderStatuswith a decode-aware set of states thatPreloadStatuscannot express:idle— nothing scheduled for this idloading— shadow item created, asset still loadingbuffering— bytes warm and asset ready to play, first frame not yet decodedframeReady— first displayable frame decoded and retained; promotion is now instantfailed(Error?)andcancelled
- Introduced
FastPixPreRenderManagerDelegate, mirroringPreloadManagerDelegate, with the following callbacks:videoPreRenderDidStart(forId:)— fires when the shadow pipeline is created for a videovideoPreRenderDidBecomeReady(forId:)— fires when the first frame is decoded and retainedvideoPreRenderDidFail(forId:error:)— fires when pre-rendering fails, providing the error for logging or retry logicvideoPreRenderDidCancel(forId:)— fires when a pre-render is cancelled (e.g. viacancel(for:))
- Bounded concurrency:
maxConcurrentdefaults to1. First-frame decode is materially heavier than the byte warmingPreloadManagerperforms, and in practice only the immediate next item needs an instant picture. Requests beyond the cap are ignored rather than queued. - Composition with preloading: the SDK schedules a pre-render only for the immediate next playlist item, while
PreloadManagercontinues to warm bytes for the wider look-ahead window. On promotion the player prefers a pre-rendered item, falls back to a preloaded item (warm bytes), and finally loads fresh — so pre-rendering strictly adds to the existing preload behaviour and never replaces it. - DRM items degrade gracefully: FairPlay-protected items cannot have their first frame decoded without an attached content key, so they automatically fall back to preload-only. No error is raised and no delegate failure is reported.
- Resource lifecycle and release: all pre-render entries are released on memory-warning and on app background, and ready items are reset to non-ready, so a retained frame can never outlive the conditions that justified holding it. The shadow player is paused as soon as the frame is captured, freeing the decoder while only the single frame is retained.
- Pre-rendering is automatically re-evaluated on
next(),previous(),jumpTo(), andFastPixPlaylistStateChanged, and pre-renders for items that have scrolled past are cancelled to free memory. - Diagnostic
[PreRender]tracing is compiled out of release builds, so the feature is silent in production. - Fully compatible with token-protected streams, custom domains, playlist-based playback, preload/precache, and all existing SDK features.
- Added
- Code standardization updates applied across the SDK to align with best practices and strengthen overall stability.
- Updated iOS Data Core SDK.
All SDK-managed default service endpoints have been migrated from the .io domain to .com to align with the updated FastPix infrastructure. Existing integrations using SDK defaults will automatically start using the new hosts after upgrading.
- HLS playback host – default stream base changed from
https://stream.fastpix.iotohttps://stream.fastpix.comfor both on-demand and live streams, and for episode switching in the playlist flow. - DRM endpoints – Widevine license, FairPlay license, and FairPlay certificate URLs now resolve under
https://api.fastpix.com/v1/on-demand/drm/...(previouslyapi.fastpix.io). - Spritesheet / poster host –
spritesheet-srcdefault updated fromimages.fastpix.iotoimages.fastpix.com. Consumers that explicitly setspritesheet-srcare unaffected.
Note: Existing
.iodomains remain temporarily supported for backward compatibility but are planned for future deprecation. Migrating to.comendpoints is strongly recommended.
- Preload & Precache Support
- Added PreloadManager (singleton via PreloadManager.shared) to initialize AVPlayerItem instances for upcoming playlist items in the background using a shadow AVPlayer, warming AVFoundation's URL session cache before the user navigates to the next video.
- Added PrecacheManager (singleton via PrecacheManager.shared) to download and store HLS segments to disk, serving content from the local cache on subsequent playback requests for reduced startup latency.
- Introduced
preload(items:)to queue one or more (id: String, item: AVPlayerItem) pairs for background buffering. - Introduced
preloadStatus(forVideo:)to query the current preload state of a video — useful for filtering out items that are already loading, ready, or currently playing before queuing a new preload. - Introduced
consumePreloadedItem(for:)to detach a preloaded item from the shadow player before calling next(), allowing AVFoundation's URL session cache to be reused by the SDK when loading the same stream URL. - Introduced
clearAll()on PreloadManager to cancel all in-flight preload tasks and release buffered items — call this in deinit to prevent memory leaks. - Introduced
startPrecaching(url:)on PrecacheManager to begin downloading HLS segments for a given stream URL to disk. - Introduced
stopAllPrecaching()on PrecacheManager to cancel all active precache downloads — call this in deinit alongsideclearAll(). - DRM-protected items (drmToken is non-empty) are automatically excluded from precaching since their segments are encrypted and cannot be meaningfully cached. Preloading still applies to DRM items as AVFoundation handles license fetching separately.
- Introduced
PreloadManagerDelegatewith the following callbacks:videoPreloadDidStart(forId:)— fires when background buffering begins for a videovideoPreloadDidBecomeReady(forId:)— fires when the AVPlayerItem is buffered and ready for instant playbackvideoPreloadDidFail(forId:error:)— fires when preloading fails, providing the error for logging or retry logicvideoPreloadDidCancel(forId:)— fires when a preload task is cancelled (e.g., via clearAll())videoPreloadDidAutoAdvance(toId:)— fires when the SDK auto-advances to the next playlist item and consumes the preloaded buffer.
- Introduced `PrecacheManagerDelegate`` with the following callbacks:
videoCacheDidHit(url:)— fires when a segment request is served from the local disk cachevideoCacheDidMiss(url:)— fires when a segment is not cached and is being downloaded from the network
- Preloading and precaching are automatically re-triggered on next(), previous(), jumpTo(), and
FastPixPlaylistStateChangedto keep the preload window ahead of the current playlist position. - Fully compatible with token-protected streams, custom domains, playlist-based playback, and all existing SDK features.
- Adaptive Bitrate (ABR) & Resolution Switching
- Added support for Adaptive Bitrate Streaming (ABR) to automatically adjust video quality based on network conditions, ensuring smooth playback with reduced buffering.
- Enabled manual resolution switching, allowing users to select specific quality levels (e.g., 240p, 480p, 720p) during playback.
- Introduced
QualityLevelmodel with properties such as label, bitrate, resolution, and auto-mode indicator. - Added
setupQualityManager(delegate:)to initialize and manage quality-related operations. - Added
qualityDelegateto receive real-time updates for quality changes and availability. - Added
getResolutionLevels()to fetch all available quality levels dynamically from the stream. - Added
getCurrentResolutionLevel()to retrieve the currently active quality level. - Added
setResolutionLevel(_:)to allow manual switching between available quality levels. - Added
resetToAuto()to switch back to automatic ABR mode. - Implemented dynamic loading of quality levels after playback starts for accurate detection based on stream data.
- Introduced delegate callbacks:
onQualityLevelsUpdatedfor receiving available quality levelsonQualityLevelChangedfor tracking successful quality switchesonQualitySwitchingfor indicating switching stateonQualityLevelFailedfor handling errors during switching
- Designed to work effortlessly with custom player UI, enabling OTT-style quality selectors (Auto / Manual modes).
- Fully compatible with HLS streaming, buffering logic, and playlist-based playback.
- Fixed
- Fixed Swift Package Manager configuration.
- Updated
swift-tools-version. - Improved package compatibility with Xcode.
- Enhanced Spritesheet Support
- Added support for spritesheet-based timeline preview for private media.
- Enabled spritesheet preview for DRM-protected content (FairPlay).
- Improved thumbnail loading mechanism to work seamlessly with secured playback URLs.
- Ensured compatibility with token-based and signed URL playback flows.
- Optimized preview rendering performance for smoother scrubbing experience across all content types.
- Updated iOS Data Core SDK by updating the SDK’s default metrics collection domain to improve endpoint reliability and alignment with current infrastructure.
- Audio Track Switching
- Added
setPreferredAudioTrack(languageName:)to set a preferred audio language by display name (case-insensitive). - Preferred audio track is automatically applied on every playlist item change, not just the first video.
- SDK now resets the preferred track selection state on each player attach, ensuring consistent behavior across playlist transitions.
- Introduced
FastPixAudioTrackDelegatewith callbacks for track updates, track changes, switching state, and errors. - Added
getAudioTracks()to retrieve all available audio tracks for the current item. - Added
getCurrentAudioTrack()to retrieve the currently active audio track. - Added
setAudioTrack(trackId:)to switch audio tracks programmatically during playback. - Falls back to the manifest default track if the preferred language is not available in the stream.
- Added
- Subtitle Track Switching
- Added
setPreferredSubtitleTrack(languageName:)to set a preferred subtitle language by display name (case-insensitive). - Preferred subtitle track is automatically applied on every playlist item change.
- SDK resets subtitle parser and selection state on each player attach to prevent stale cues across playlist transitions.
- Introduced
FastPixSubtitleTrackDelegatewith callbacks for tracks loaded, track change, cue change, and errors. - Added
getSubtitleTracks()to retrieve all available subtitle tracks for the current item. - Added
getCurrentSubtitleTrack()to retrieve the currently active subtitle track, ornilif subtitles are off. - Added
setSubtitleTrack(trackId:)to switch subtitle tracks programmatically during playback. - Added
disableSubtitles()to turn off subtitles and stop the WebVTT parser. - Real-time subtitle cue delivery via
onSubtitleCueChange(information:)with text, timestamp, and language code. - Built-in WebVTT parser that fetches and parses subtitle segments from HLS manifest-resolved playlist URLs.
- Falls back to the manifest default track if the preferred language is not available in the stream.
- Added
- Network Handling
- Added real-time network monitoring (Wi-Fi, Cellular, Offline).
- Automatically pauses playback on network loss and resumes on reconnection (configurable).
- Exposed network state callbacks for custom UI and handling.
- Improved playback stability during buffering, stalls, and network switches.
- Skip Controls (Intro / Songs / Credits)
- Added support for Skip Intro, Skip Songs, and Skip Credits using time-based skip segments.
- Skip segments can be configured per asset or per FastPixPlaylistItem.
- SDK automatically validates and applies skip ranges during playback.
- Introduced SkipManager APIs to set, clear, and trigger skips.
- Skip button visibility is managed by the SDK based on playback time.
- Skip state resets automatically during playlist transitions.
- Fully compatible with custom UI implementations.
- Volume Control
- Added device-level volume support, reflecting system volume changes made via hardware buttons.
- Introduced on-screen volume control APIs for building custom sliders or gesture-based volume controls.
- Added mute / unmute functionality with proper state handling.
- Ensured volume slider UI and mute state remain synchronized with the player’s audio state
- Playback Loop
- Added Playback Loop support to automatically restart playback when the video reaches the end.
- Loop behavior works seamlessly across inline playback, fullscreen, and Picture-in-Picture (PiP) modes.
- Enabled simple configuration using
isLoopEnabled. - Playback loop is disabled by default to preserve standard playback behavior.
- Autoplay
- Added Autoplay support to automatically start playback once the media is ready.
- Enabled simple configuration using
isAutoPlayEnabled. - Autoplay behavior extends to playlist playback for automatic item transitions.
- Autoplay is disabled by default to maintain user-controlled playback.
- Playback Speed Control
- Added Playback Speed Control to dynamically adjust playback rate during runtime.
- Supports multiple playback rates including slow-motion and fast-forward options.
- Set a specific playback rate, Increment playback speed, Decrement playback speed, Retrieve the current playback rate.
- Playback speed changes apply instantly without interrupting playback or affecting buffering, video quality, or audio sync.
- Default playback speed is set to 1x (normal playback)
- Forward & Rewind Controls
- Added configurable seek increments via:
configureSeekButtons(enablePortrait:enableLandscape:forwardIncrement:backwardIncrement:) - Forward and rewind actions are fully synchronized with the player’s internal playback state and are automatically disabled during active seek bar scrubbing to prevent conflicting seeks.
- Improved user interaction handling — controls remain visible during forward/rewind interactions, and auto-hide logic pauses during seek actions and resumes safely afterward
- Added configurable seek increments via:
- Picture-in-Picture (PiP)
- Enable PiP with
enablePiP = true. - Check state via
isPiPAvailableandisPiPActive. - Toggle with
togglePiP()and observe viaFastPixPiPStateChangedNotification.
- Enable PiP with
- Full-Screen Mode
- Smooth inline ↔ full-screen transitions using
FastPixFullscreenManager. - Configure layout with
configureConstraints(normal:fullscreen:). - Observe state via
FastPixFullscreenStateChangedNotification.
- Smooth inline ↔ full-screen transitions using
- Spritesheet & Timeline Preview
- Show thumbnails on seek bar with
loadSpritesheet(url:previewEnable:config:). - Clear with
clearSpritesheet(). - Fall back to timestamp-only preview with
setFallbackMode(.timestamp).
- Show thumbnails on seek bar with
- FastPix iOS Player now supports fully customizable player controls.
- Integrate your own Play/Pause button while staying synced with the player’s internal playback state.
- Introduced support for a custom Seek Bar using FastPixSeekManager with real-time updates for: Current playback time, Total duration, Buffered time, Seek start/end events.
- Developers can now manage orientation handling manually, making it easier to build custom full-screen or embedded player UIs.
- Built-in seek navigation improvements (seekForward(), seekBackward(), seekToPercentage()) for enhanced control customization.
- Custom UI elements can now listen to playback and buffering updates using delegate callbacks to stay perfectly in sync with the player.
- FastPix iOS Player now supports playlist.
- Create and manage playlists with multiple
FastPixPlaylistItems. - Add playlist directly to the player using
addPlaylist()method. - Auto-play option (
isAutoPlayEnabled) to automatically continue playback with the next item. - Option to hide the SDK’s default controls (
hideDefaultControls) for building custom UI. - Playlist state notifications via
NotificationCenter(FastPixPlaylistStateChanged) for updating UI elements such as titles, buttons, or thumbnails. - Built-in navigation methods:
next(),previous(), andjumpTo(index:)for moving between items. - Navigation methods can also be connected to custom UI buttons (e.g., Next/Previous/Episode selectors)
- FastPix iOS Player now supports DRM via Apple FairPlay for content protection.
- Media Playback: Support for both live and on-demand streaming via
.m3u8playback. - Token-based Secure Playback: Enables playback with
playbackTokenfor secured streams. - Custom Domain Support: Allows streaming from custom domains with optional secure access.
- Audio Track Switching: Automatic detection and switching of multiple audio tracks in supported streams.
- Resolution Control:
- Support for minimum (e.g.,
.atLeast270p) and maximum (e.g.,.upTo1080p) resolution limits. - Fixed resolution option (e.g.,
.set480p). - Range-based resolution configuration.
- Support for minimum (e.g.,
- Rendition Order Customization: Added support for ascending or descending rendition selection.
- Swift Package Manager Support: SDK is installable via SPM using the repo URL.