Summary
Airo TV currently supports M3U playlist import and .m3u8 stream playback, but Xtream Codes and Stalker Portal are not wired through the main IPTV runtime end to end.
Observed on July 23, 2026 while reviewing the current source-loading path:
feature_iptv runtime channel loading still uses the legacy single-playlist M3UParserService path.
- Xtream and Stalker source models, storage, credential handling, settings UI, and adapters exist, but the saved sources are not consumed by the main channel-loading/playback flow.
.m3u8 is supported as a stream URL for playback, but a raw HLS manifest URL is not yet a distinct first-class import source type.
Problem
Users can configure M3U, Xtream Codes, and Stalker Portal source types in source-management settings, but only the M3U runtime path is fully active. This creates a product mismatch between what the UI suggests and what the live IPTV flow actually supports.
User / actor
Airo TV bring-your-own-content users who want to connect provider details using:
- M3U / M3U8 playlist URLs
- Xtream Codes server URL + username/password
- Stalker Portal URL + MAC address
Expected outcome
Airo TV should either:
- fully support these source types end to end in browse, playback, refresh, EPG, and VOD flows where applicable, or
- explicitly limit the UI to the source types that are actually shipped.
This ticket assumes the preferred direction is full end-to-end support for Xtream and Stalker, while keeping existing M3U support intact.
Current-state evidence
- Active IPTV runtime centers on
packages/feature_iptv/lib/application/providers/iptv_providers.dart and still loads channels through the M3U path.
- Content-source models are defined in
packages/platform_playlist/lib/src/content_source.dart.
- Xtream adapter exists in
packages/platform_playlist/lib/src/xtream/xtream_content_source.dart.
- Stalker adapter exists in
packages/platform_playlist/lib/src/stalker/stalker_content_source.dart.
- Source persistence exists in
packages/feature_iptv/lib/application/providers/content_source_management_providers.dart and packages/feature_iptv/lib/application/content_source_store.dart.
- TV settings source-management UI exists in
app/lib/features/settings/presentation/tv/tv_source_management_section.dart.
- Stalker adapter notes that no UI consumes it yet.
Scope
In scope
- Define the canonical runtime contract for selecting and loading the active content source.
- Wire saved Xtream Codes sources into channel loading, refresh, and playback.
- Wire saved Stalker Portal sources into channel loading, refresh, and playback.
- Decide whether raw
.m3u8 URLs remain playback-only or become a supported import path distinct from M3U channel-list import.
- Make capability handling explicit:
- M3U: live channels, optional EPG from external XMLTV
- Xtream: live channels, EPG, VOD where supported
- Stalker: live channels, EPG if implemented for current source path
- Align source-management UI copy with actual shipped behavior.
- Add deterministic tests for source loading, refresh, and failure states.
Out of scope
- New provider types beyond existing
M3U, Xtream, Stalker, and already-present Jellyfin code.
- Broad redesign of the IPTV information architecture unrelated to source loading.
- Unbounded portal compatibility work for every provider quirk.
Impacted modules
packages/feature_iptv
packages/platform_playlist
packages/platform_playlist_import
packages/platform_epg
packages/platform_player
app/lib/features/settings
Constraints
- Preserve existing M3U behavior and cached import flow.
- Keep credentials secret-handled through
ContentSourceCredentialStore.
- Respect the repo’s off-main-isolate policy for large playlist/EPG parsing.
- Avoid provider-specific hacks leaking into shared models.
- Support focused local validation before any remote CI.
Cross-agent contract
- Primary owner: Media Intelligence Architect
- Required reviewers: Platform Architect, Chief QA Officer
- Additional reviewers if UI copy/behavior changes materially: Flutter Architect, Product Manager
Contract boundaries
platform_playlist owns provider protocol adapters and source capability mapping.
feature_iptv owns user-facing source selection, browse integration, refresh behavior, and failure UX.
platform_player continues to own playback URL handling only; it should not gain provider-specific business logic.
platform_epg owns guide contracts and provider-backed EPG integration points.
Critical Agent Gate
Problem: Airo TV exposes multiple source types in settings, but the main runtime is still effectively M3U-only.
User / actor: BYOC Airo TV user connecting provider data.
Framework or application layer: Mixed (platform_playlist + feature_iptv + settings UI).
Owning agent: Media Intelligence Architect.
Reviewing agents: Platform Architect, Chief QA Officer; Flutter Architect and Product Manager if UX changes.
Impacted modules/files: packages/feature_iptv, packages/platform_playlist, packages/platform_playlist_import, packages/platform_epg, packages/platform_player, app/lib/features/settings.
Base branch/worktree: Confirmed from latest origin/main or explicitly named base: no. Implementation must sync from latest origin/main before coding.
Open questions:
- Should raw
.m3u8 URLs become a supported import type or remain playback-only?
- Should Stalker
create_link resolution happen lazily at play time instead of eagerly during channel load?
- What is the minimum shippable Xtream/Stalker capability set for v1: live only, live+EPG, or live+EPG+VOD?
Decision: Ready for contract refinement, blocked for implementation until the runtime contract and active-source model are finalized.
Deterministic use cases
- User adds an M3U playlist URL, opens browse, sees imported channels, refreshes successfully, and plays a channel.
- User adds an Xtream Codes source, authenticates successfully, opens browse, sees live categories/channels, and plays a stream.
- User adds a Stalker Portal source, handshakes successfully, opens browse, resolves a playable link, and plays a stream.
- User switches between multiple configured source types and the active source changes predictably without stale channels leaking from the previous source.
- User enters invalid Xtream credentials and sees a clear, non-destructive error state with no credential leakage.
- User enters an invalid or expired Stalker source and sees a recoverable error state.
- User refreshes an Xtream or Stalker source and favorites/history mapping remains stable where IDs can be mapped.
- User with M3U plus external XMLTV still gets the current guide behavior without regression.
- If a source type advertises VOD capability, VOD surfaces only when the runtime path actually supports it.
Automation flows
- Source add flow automation:
- Add M3U source
- Add Xtream source with mocked successful auth
- Add Stalker source with mocked successful handshake
- Assert source list persistence and correct capability badges
- Runtime source selection automation:
- Select active source
- Load browse screen
- Assert channel list originates from the selected source only
- Failure-path automation:
- Xtream auth failure
- Stalker handshake failure
- Stalker link-resolution failure
- Source refresh timeout
- Regression automation:
- Existing M3U import progress flow remains intact
- Existing
.m3u8 playback path remains intact
- EPG path for M3U+XMLTV is unchanged
Acceptance criteria
- A saved Xtream source can be selected and used to load live channels in the main IPTV runtime.
- A saved Stalker source can be selected and used to load live channels in the main IPTV runtime.
- Source selection is explicit and test-covered; channel data does not silently fall back to unrelated M3U state when a different source is active.
- Refresh behavior works per source type and reports provider-specific failures clearly.
- Credentials remain redacted in logs/state and are stored only in the secure credential store where applicable.
- Existing M3U playlist import and playback behavior do not regress.
- The settings/source-management UI text matches the shipped capabilities.
- Deterministic tests cover happy path and failure path for each supported source type.
Validation plan
- Focused unit tests for Xtream and Stalker adapters and active-source routing.
- Provider tests for runtime source selection and refresh behavior.
- Widget/integration coverage for source-management and browse flows.
git diff --check, formatter, analyzer, and narrow test runs only for touched modules before any push.
Security / privacy
- Xtream credentials must remain in secure storage only.
- Stalker session tokens must remain in-memory only.
- Playback and diagnostics must not expose raw credential-bearing URLs.
- Provider errors must be safe to surface without leaking secrets.
Performance notes
- Do not resolve expensive provider operations on the UI isolate.
- Revisit eager Stalker
create_link resolution; lazy resolution at play time is likely the safer scale boundary.
- Preserve caching characteristics for M3U imports.
Rollback plan
- If provider routing causes regressions, keep M3U runtime as the fallback shipped path and hide unsupported source types from the UI until end-to-end support is stable.
Related roadmap context
- Root issue to clarify and complete multi-source BYOC ingestion behavior for Airo TV.
- Parent roadmap links: none attached yet; add when a roadmap owner maps this to the current TV release line.
Summary
Airo TV currently supports M3U playlist import and
.m3u8stream playback, but Xtream Codes and Stalker Portal are not wired through the main IPTV runtime end to end.Observed on July 23, 2026 while reviewing the current source-loading path:
feature_iptvruntime channel loading still uses the legacy single-playlistM3UParserServicepath..m3u8is supported as a stream URL for playback, but a raw HLS manifest URL is not yet a distinct first-class import source type.Problem
Users can configure
M3U,Xtream Codes, andStalker Portalsource types in source-management settings, but only the M3U runtime path is fully active. This creates a product mismatch between what the UI suggests and what the live IPTV flow actually supports.User / actor
Airo TV bring-your-own-content users who want to connect provider details using:
Expected outcome
Airo TV should either:
This ticket assumes the preferred direction is full end-to-end support for Xtream and Stalker, while keeping existing M3U support intact.
Current-state evidence
packages/feature_iptv/lib/application/providers/iptv_providers.dartand still loads channels through the M3U path.packages/platform_playlist/lib/src/content_source.dart.packages/platform_playlist/lib/src/xtream/xtream_content_source.dart.packages/platform_playlist/lib/src/stalker/stalker_content_source.dart.packages/feature_iptv/lib/application/providers/content_source_management_providers.dartandpackages/feature_iptv/lib/application/content_source_store.dart.app/lib/features/settings/presentation/tv/tv_source_management_section.dart.Scope
In scope
.m3u8URLs remain playback-only or become a supported import path distinct from M3U channel-list import.Out of scope
M3U,Xtream,Stalker, and already-presentJellyfincode.Impacted modules
packages/feature_iptvpackages/platform_playlistpackages/platform_playlist_importpackages/platform_epgpackages/platform_playerapp/lib/features/settingsConstraints
ContentSourceCredentialStore.Cross-agent contract
Contract boundaries
platform_playlistowns provider protocol adapters and source capability mapping.feature_iptvowns user-facing source selection, browse integration, refresh behavior, and failure UX.platform_playercontinues to own playback URL handling only; it should not gain provider-specific business logic.platform_epgowns guide contracts and provider-backed EPG integration points.Critical Agent Gate
Problem: Airo TV exposes multiple source types in settings, but the main runtime is still effectively M3U-only.
User / actor: BYOC Airo TV user connecting provider data.
Framework or application layer: Mixed (
platform_playlist+feature_iptv+ settings UI).Owning agent: Media Intelligence Architect.
Reviewing agents: Platform Architect, Chief QA Officer; Flutter Architect and Product Manager if UX changes.
Impacted modules/files:
packages/feature_iptv,packages/platform_playlist,packages/platform_playlist_import,packages/platform_epg,packages/platform_player,app/lib/features/settings.Base branch/worktree: Confirmed from latest
origin/mainor explicitly named base: no. Implementation must sync from latestorigin/mainbefore coding.Open questions:
.m3u8URLs become a supported import type or remain playback-only?create_linkresolution happen lazily at play time instead of eagerly during channel load?Decision: Ready for contract refinement, blocked for implementation until the runtime contract and active-source model are finalized.
Deterministic use cases
Automation flows
.m3u8playback path remains intactAcceptance criteria
Validation plan
git diff --check, formatter, analyzer, and narrow test runs only for touched modules before any push.Security / privacy
Performance notes
create_linkresolution; lazy resolution at play time is likely the safer scale boundary.Rollback plan
Related roadmap context