Overview
ThePlayer model manages the complete video playback experience. It tracks playback progress, handles stream loading, manages subtitles, implements binge watching features, collects analytics, and syncs watching state to the library. This is the most complex model in Stremio Core.
Structure
Fields
Currently selected stream and related metadata
Video file parameters (hash, size, filename) for subtitle matching
Meta item being played
Available subtitles from all addons
Next video to play (for binge watching)
Streams loaded for the next video
Recommended stream for next video (matches current source)
Converted stream with playback URLs
Series information (season, episode) for current video
Library item being updated during playback
Current playback state stored in streams bucket
Skip intro/outro timing information
Bitfield tracking watched episodes
Context for analytics events
Timestamp when player started loading
Last time library item was synced (rate-limited to every 90 seconds)
Whether video has started playing
Whether playback has ended
Current pause state
Seek events for skip gaps analysis
Skip gaps request and response for intro/outro detection
Whether to collect seek history (default: false)
Selected
The stream being played
Original request used to load this stream
Request to fetch the meta item
Path to subtitle resource
VideoParams
- OpenSubtitles hash matching
- Better subtitle synchronization
- Skip gaps detection
AnalyticsContext
Update Implementation
ImplementsUpdateWithCtx<E> for playback management:
Supported Messages
Action::Load::Player
Action::Load::Player
Loads a stream for playback:
- Converts stream to playable URLs
- Loads meta item
- Loads subtitles
- Determines next video for binge watching
- Updates library item with current state
- Dismisses notifications
- Initializes analytics context
src/models/player.rs:139Action::Unload
Action::Unload
Stops playback and cleans up:
- Emits
Event::PlayerStoppedif not ended - Saves final library item state
- Submits seek history
- Clears all player state
src/models/player.rs:305Action::Player::VideoParamsChanged
Action::Player::VideoParamsChanged
Updates video parameters (hash, size, filename):
- Reloads subtitles with new params
- Triggers skip gaps detection
src/models/player.rs:371Action::Player::StreamStateChanged
Action::Player::StreamStateChanged
Notifies that stream playback state changed:
- Forwards to
Internal::StreamStateChanged - Updates streams bucket
src/models/player.rs:394Action::Player::Seek
Action::Player::Seek
User manually seeks to a position:
- Updates library item time_offset and duration
- Collects seek log if enabled
- Sends Trakt events (paused/playing)
- Rate-limited library sync (every 90s)
src/models/player.rs:408Action::Player::TimeChanged
Action::Player::TimeChanged
Playback position changed (periodic updates):
- Updates time_offset and time_watched
- Checks if video should be marked as watched (watched threshold)
- Marks videos in watched bitfield
- Handles temp/removed flags
- Rate-limited library sync
src/models/player.rs:475Action::Player::PausedChanged
Action::Player::PausedChanged
Playback paused or resumed:
- First unpause emits
Event::PlayerPlaying - Subsequent changes emit Trakt events
- Syncs library item
src/models/player.rs:560Action::Player::NextVideo
Action::Player::NextVideo
User requests to play next video:
- Submits seek history with outro time
- Updates library item time_offset to 0 or 1
- Emits
Event::PlayerNextVideo
src/models/player.rs:596Action::Player::Ended
Action::Player::Ended
Playback ended:
- Sets ended flag
- Emits
Event::PlayerEnded
src/models/player.rs:637Action::Player::MarkVideoAsWatched
Action::Player::MarkVideoAsWatched
Manually mark video as watched/unwatched during playbackSource:
src/models/player.rs:646Action::Player::MarkSeasonAsWatched
Action::Player::MarkSeasonAsWatched
Manually mark entire season as watched/unwatched during playbackSource:
src/models/player.rs:658Internal::LibraryChanged
Internal::LibraryChanged
External library change:
- Reloads library item
- Updates watched bitfield
src/models/player.rs:689Internal::StreamsChanged
Internal::StreamsChanged
Streams bucket changed:
- Updates stream_state
src/models/player.rs:710Internal::ResourceRequestResult
Internal::ResourceRequestResult
Processes resource responses:
- Meta item loading
- Subtitle loading
- Next video streams loading
- Updates library item, watched state, skip gaps
src/models/player.rs:713Internal::SkipGapsResult
Internal::SkipGapsResult
Processes skip gaps response:
- Updates intro/outro timing information
src/models/player.rs:836Watched Threshold
A video is automatically marked as watched when:WATCHED_THRESHOLD_COEF is typically 0.7 (70%).
Source: src/models/player.rs:522
Credits Threshold
When switching videos, if the current position exceeds the credits threshold:src/models/player.rs:888
Library Sync Rate Limiting
Library updates are rate-limited usingPUSH_TO_LIBRARY_EVERY (90 seconds):
src/models/player.rs:872
Binge Watching
The player automatically determines the next video:
Source:
src/models/player.rs:939
Intro/Outro Skip
Intro/outro detection uses skip gaps API:- Requires
video_params(hash, size, filename) - Requires
series_info(must be a series) - Sends request to skip gaps service
- Receives intro/outro timestamps
- Updates
intro_outrofield
src/models/player.rs:1219 (in truncated portion)
Seek Logs
Whencollect_seek_logs is enabled:
- Records all seek operations before
PLAYER_IGNORE_SEEK_AFTERtime - Only for series content
- Submitted to API on unload or next video
- Used for improving intro/outro detection
src/models/player.rs:424
Events
The player emits:Event::PlayerPlaying { load_time, context }- Playback startedEvent::PlayerStopped { context }- Playback stopped without endingEvent::PlayerEnded { context, is_binge_enabled, is_playing_next_video }- Playback endedEvent::PlayerNextVideo { context, is_binge_enabled, is_playing_next_video }- Next video requestedEvent::TraktPlaying { context }- For Trakt scrobblingEvent::TraktPaused { context }- For Trakt scrobbling
Usage Example
Performance Considerations
The player automatically handles:
- Library state persistence
- Progress tracking
- Watched status updates
- Binge watching recommendations
- Analytics event emission
See Also
- Stream - Stream structure
- LibraryItem - Library item updates
- MetaDetails - Content details before playback
- Subtitles - Subtitle structure
