Skip to content

feat(siri): play channels, movies and series by voice with Siri and Shortcuts - #352

Open
bilipp wants to merge 1 commit into
mainfrom
feature/add-siri-support-to-lume
Open

bilipp wants to merge 1 commit into
mainfrom
feature/add-siri-support-to-lume

Conversation

@bilipp

@bilipp bilipp commented Oct 31, 2026

Copy link
Copy Markdown
Owner

Summary

Lume Pro users can start playback by voice and from Shortcuts: "Play in Lume", "Start in Lume", "Play in Lume" (next unwatched episode, resuming if started) and "Continue watching in Lume". Titles are matched by name against the active profile's unlocked playlists, with favorites/recents ranked first, then the active playlist, then exact names; Siri asks only on a tie. An unknown, restricted or Pro-locked title gets a spoken "not found" without opening the app.

Implementation

New Lume/Services/Intents/ holds the channel/movie/series AppEntitys and their queries (fresh background context on the catalog container, fetchLimit, ranking in memory, prefix-stripped display titles), the four intents, LumeShortcuts (phrases in the new AppShortcuts.xcstrings) and an in-memory pending slot (IntentRouter). perform() resolves through WidgetLinkResolver, queues the request, then foregrounds the app; SiriIntentDrain in MainTabView plays it once the launch gate, profile picker and PIN pad are clear, re-checking against the now-active profile. If a player is already open, the stream is swapped in place (PlayerSwapRequests + PlayerSwapRequestHost, built on PlayerMediaSwapper; macOS via MacPlayerWindowRouter.pendingMedia); Multi-View and the tvOS quick-switch close first. The cold-launch auto-sync waits while a Siri-started stream plays (SiriLaunchSyncDeferral). Settings on iOS gets a Pro-only Siri section (SiriTipView + ShortcutsLink). ContentRestriction.fromCatalog is extracted and now also used by WidgetSnapshotExporter.

Decisions

  • Intents in v1: Play Channel, Play Movie, Play Series, Resume Watching; names only, no channel numbers
  • All platforms (iOS, iPadOS, macOS, tvOS, visionOS); tvOS voice is best-effort
  • Ranking: favorites/recents → active playlist → exact name; disambiguation only on ties
  • Already playing: swap the stream in place
  • Siri is Pro-only (PremiumFeature.siri): a free user gets the app plus the .siri paywall (it waits for an open player to close); the request replays only if they upgrade and is dropped on dismiss. Pro-locked playlists are never searched
  • Child profile: silent "not found"; Siri never switches profiles or bypasses a PIN
  • Launch gate: the request waits and is re-checked for the now-active profile
  • Movies/series resume if started; no match answers "not found" without opening the app
  • Extras: defer cold-launch auto-sync during a Siri-started stream, strip provider prefixes from spoken titles, iOS Settings Siri tip
  • OS 18–25 shows Siri's "Continue in Lume?" confirmation (requestToContinueInForeground); 26+ continues directly
  • Out of scope: Spotlight (feat: Spotlight indexing of catalog content #128), headless media controls, alternative spoken app names, casting from Siri
  • Implementation choices: Play Series uses SeriesEpisodeProgress.nextEpisode and falls back to opening the series page; ProfileManager is registered via AppDependencyManager; the PIN pad counts as a blocking sheet in ScreenOccupancy; "Continue watching" while a player is open keeps the current player
  • Deferred: native review of the ar, ja, ko and zh-Hans phrases and strings

Testing

  • Acceptance criteria met — end-to-end Siri/Shortcuts runs still need a team-signed build or a device: on the simulator linkd rejects the ad-hoc-signed app ("Unable to get teamId … requiresValidBundle"), so shortcuts fail with "Couldn't find AppShortcutsProvider" and the Siri tip row stays blank
  • Builds clean (iOS 26.5 sim, macOS, tvOS 27.0 sim)
  • Tests pass — all Siri-related suites (iPhone 17 Pro, iOS 26.5; no 26.4 runtime installed). Full-suite failures are pre-existing on main: MediaServerLocalizationTests, SportsHubStringsTests, SportsResolveCacheTests; TextEmbedderTests needs simulator language assets
  • SwiftLint clean
  • Tests added — IntentCatalogResolverTests, IntentEntityTests, PlayerSwapRequestsTests, ResumeSnapshotCheckTests, SiriLaunchSyncDeferralTests, SiriLocalizationTests, SiriSwapDecisionTests; extended ContentRestrictionTests, DeepLinkTests, WidgetSnapshotTests
  • UI verified on simulator — Settings Siri section and the four App Shortcuts in the Shortcuts app; running them is blocked as above

Platforms

  • iOS / iPadOS — iPadOS not built locally (no iPad sim; generic build fails to link the arm64-only LumeEngine FFmpeg)
  • tvOS
  • macOS
  • visionOS — fails to build on main too (PremiumManager.purchase, AirPlayRouteButton, GlassEffectCompat); nothing from this branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant