Skip to content

feat(mobile-player): comprehensive mobile player interface overhaul & modular architecture - #610

Open
Himanth-reddy wants to merge 26 commits into
ProdigyV21:mainfrom
Himanth-reddy:feature/modular-player-architecture
Open

feat(mobile-player): comprehensive mobile player interface overhaul & modular architecture#610
Himanth-reddy wants to merge 26 commits into
ProdigyV21:mainfrom
Himanth-reddy:feature/modular-player-architecture

Conversation

@Himanth-reddy

@Himanth-reddy Himanth-reddy commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR delivers a comprehensive overhaul of the mobile video player interface, introducing modular architecture refactoring, refined multi-tap and swipe gesture engines, enhanced subtitle and audio drawers, dynamic edge-to-edge system bar integration, instantaneous orientation exit handling, and expanded aspect ratio controls.


What Has Been Done (Commit Breakdown)

1. Modular Player Architecture Refactor (32573186)

  • Before: The player was contained in a monolithic 6,000+ line screen where mobile touch logic, Android TV D-pad navigation, ExoPlayer engine specifics, and subtitle processing were tightly coupled.
  • After: Modularized into specialized subsystems:
    • player/mobile/: Dedicated mobile touch UI, design tokens (MobilePlayerTokens), bottom sheets, contextual prompts, and gesture surfaces.
    • player/tv/: Dedicated 10-foot Android TV D-pad interface.
    • player/engine/: Engine-agnostic abstraction layer (PlayerEngine, PlayerEngineModels, PlayerEngineFactory) supporting multiple playback backends.
    • player/subtitles/: Encapsulated subtitle and AI synchronization services.
    • player/common/: Shared playback gates and system bar effect coordinators.

2. PlayerEngine Wiring & Settings Persistence (b7c9b69b)

  • Before: Playback options (auto-skip intervals, audio normalization, delay offsets) were not unified and did not persist across sessions.
  • After: Wired PlayerEngine as the single coordinator for playback actions; persisted preferences in DataStore; implemented real-time intro/outro skip intervals, audio normalization via LoudnessEnhancer, and delay sync.

3. Multi-Tap Gestures Engine (d79e4d0d)

  • Before: Touch interaction was limited to single-tap toggles.
  • After: Implemented a comprehensive multi-tap gesture detection state machine:
    • Single tap: Toggle playback controls / dismiss open panels.
    • Double tap (Left / Right halves): Fast rewind / forward 10 seconds with animated ripple overlays.
    • Triple tap: Seamlessly cycle aspect ratio modes on the fly.

4. 2-Stage Drilldown Subtitle Picker & Language Standardization (6a1ef148, e140d6ac)

  • Before: Subtitles were shown in a flat, unorganized list with abbreviated ISO codes (e.g., eng, spa, por) and harsh bordered cards.
  • After: Redesigned subtitle sheet into a 2-stage drilldown:
    • Stage 1 (Language Groups): Standardized full language names (English, Spanish, etc.) with track count badges, active indicators, and quick Off toggle.
    • Stage 2 (Track Details): Granular track selection displaying metadata badges (Embedded, Provider, SDH, Forced).
    • Modern borderless card styling with soft focus highlights.

5. Monotonic Vertical Swipe Gestures (d8f9a912)

  • Before: Vertical volume and brightness gestures lacked an activation baseline, causing sign-reversal bugs (where an upward swipe could decrease volume on slight diagonals) and abrupt value jumps upon activation.
  • After: Implemented an activation baseline model (effectiveDeltaY = totalDeltaY - activationDeltaY). Swipes are strictly monotonic, continuous at activation (zero jump), and strict axis dominance filtering prevents accidental adjustments during horizontal seeking or diagonal swipes.

6. Edge-to-Edge System Bars & Dynamic Insetting (d8f9a912)

  • Before: System bars were static or did not synchronize with controls visibility, risking UI collisions or viewport resizing.
  • After: Transient system bars (BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) dynamically follow player controls visibility—revealing real status icons and navigation buttons when controls appear and hiding them cleanly when controls fade out. Interactive overlays combine live WindowInsets.systemBars and WindowInsets.displayCutout for safe clearance without video shifts.

7. Instantaneous & Smooth Exit Flow (d8f9a912)

  • Before: Orientation restoration was deferred until screen disposal, causing the previous screen to render in landscape and freeze for ~0.5s before rotating to portrait.
  • After: Remembers the exact device orientation from before entering playback and synchronously restores it the instant exit navigation is dispatched. Back navigation cleanly closes drawer panels and lock state first before exiting.

8. Aspect Ratio Modes & Startup Indicator Fix (1a42f84f)

  • Before: Limited aspect ratio options, and the indicator HUD erroneously flashed on screen every time the player initialized.
  • After: Added four standard aspect ratio modes: Auto (default), Fit to Screen, Stretch, and Crop. Fixed initial composition so the HUD indicator is suppressed on player startup and only appears on explicit user action.

@github-actions github-actions Bot added the area: android Changes to the Android app or Gradle build label Aug 26, 2026
@Himanth-reddy Himanth-reddy changed the title feat(player): modular player architecture, MX Player gestures, system bars sync, and aspect ratio modes feat(player): modular player architecture, swipe gestures, system bars sync, and aspect ratio modes Aug 26, 2026
@Himanth-reddy Himanth-reddy changed the title feat(player): modular player architecture, swipe gestures, system bars sync, and aspect ratio modes feat(mobile-player): comprehensive mobile player interface overhaul & modular architecture Aug 26, 2026
@Himanth-reddy
Himanth-reddy force-pushed the feature/modular-player-architecture branch 8 times, most recently from 1e62d54 to 764e7fc Compare August 28, 2026 09:42
@Himanth-reddy
Himanth-reddy force-pushed the feature/modular-player-architecture branch from 764e7fc to 4c25e06 Compare September 3, 2026 04:44
@ProdigyV21

Copy link
Copy Markdown
Owner

@Himanth-reddy Update is planned tomorrow evening. Will it be done by then?

@Himanth-reddy

Copy link
Copy Markdown
Collaborator Author

No 🥲

@Himanth-reddy
Himanth-reddy force-pushed the feature/modular-player-architecture branch 2 times, most recently from a1f2dc2 to 7ce3af0 Compare September 4, 2026 14:33
- Extract dedicated Mobile UI into player/mobile/ with touch controls, bottom sheets, and contextual prompt cards
- Extract dedicated Android TV UI into player/tv/ with D-pad navigation, 10-foot chrome, and TV overlays
- Introduce multi-engine playback abstraction layer in player/engine/ with PlayerEngine, PlayerEngineModels, and PlayerEngineFactory (ExoPlayer / MPV / VLC)
- Encapsulate AI & Subtitle translation/synchronization services into player/subtitles/
- Move shared playback gatekeeper logic into player/common/
- Clean up PlayerScreen into a lean root coordinator
… mobile player

- Single tap: show/hide playback controls
- Double tap (left/right): seek backward/forward 10s with visual indicator overlay
- Double tap (center): toggle play/pause
- Triple tap: cycle aspect ratio (Fit / Fill / Zoom)
- Revert debug applicationIdSuffix change in build.gradle.kts
- Wire PlayerEngine as the core controller in PlayerScreen for play/pause, seek, speed, and track actions
- Persist and load auto_skip_intro, auto_skip_outro, audio_delay_ms, audio_normalization, and subtitle preferences in DataStore
- Add real-time auto-skip interval enforcement for intro/outro
- Connect audioDelayMs to subtitle sync processor and audioNormalization to LoudnessEnhancer
- Stage 1: clean list of language groups with track count badges, active indicators, and Off toggle
- Stage 2: detailed subtitle tracks for chosen language with Embedded, Provider, SDH, and Forced badges
- Full back-navigation and gesture support
…ction UI

- Normalize all language codes to full names with Java Locale fallback across Mobile & TV
- Reposition track count number to the right, adjacent to the chevron arrow without background badge
- Remove hard borders from selected cards, using smooth borderless highlight background
…e gestures on error, and retain active stream
…bile touch scrubbing

- Add quantizeSeekPreviewPositionWithHysteresis with ±2.5s deadzone to eliminate thumb jitter boundary flipping
- Gate preview extractions with isSeekPreviewSupported to avoid infinite loading spinners on HLS/DASH/IPTV/live streams
- Eliminate stale frame retention by matching frames to active buckets and using clean loading placeholders
- Upgrade seekbar touch input to awaitEachGesture with continuous tracking and zero-delay touch down
- Remove progress indicator dot from SeekPreviewPlaceholder for a clean dark preview bubble
- Add 160ms settle debounce for mobile dragging and fit seek preview dimensions for PixelCopy surface captures
- Add unit tests for preview position hysteresis and boundary transitions
- Integrate 16 official Hugeicons SVG vector drawables (Stroke-Rounded for controls, Solid-Rounded for Play/Pause)
- Update MobilePlayerControls with Hugeicons for top bar, transport controls, bottom bar, next episode, and utility chips
- Update ArvioMobilePlayer gesture overlays (double-tap 10s seek, lock screen unlock)
…s-player

- Move all player drawables to dedicated resource directory app/src/main/res-player/drawable/
- Switch Episodes icon to Hugeicons ListVideo
- Update More Settings icon with larger 3.6dp dots for enhanced legibility
- Switch Sound/Audio chip icon from headphones to speaker (VolumeHigh)
- Switch movie Sources icon from generic layers to 35mm film cell
- Ensure Cast button is always visible on mobile player top bar
… and frosted HUDs

- Redesign seekbar thumb to Style A: 14dp/18dp stroke-rounded ring with 2dp white stroke, dark core, and inner optical pip
- Add animated seekbar track expansion (3.5dp resting -> 5.5dp while scrubbing) with rounded pill ends
- Redesign MobileEdgeIndicator to modern frosted glass capsule HUD (36x156dp, 18dp radius)
- Integrate Hugeicons Sun (Sun03/SunDim) and Volume (VolumeHigh/VolumeMute) for edge swipe HUDs
- Remove legacy Material icons for volume and brightness
…and gracefully hide UI on slide

- Integrate Hugeicons CaptionsIcon and CaptionsOffIcon based on subtitle active state
- Remove frosted glass containers from Volume & Brightness HUDs, making them floating edge indicators
- Gracefully hide player controls when sliding volume or brightness
- Add Hugeicons ArrowLeft, ChevronLeft, and CancelCircle drawables
… and unified persistent buffering spinner with pause support
…ss review findings

- Overhaul mobile player audio and subtitle sheets:
  - Add unified DelayAdjusterContent for exact audio & subtitle delay adjustment
  - Implement two-phase volume boost gesture with consuming amber fill indicator
  - Add interactive on-screen subtitle repositioning overlay with live cue detection
  - Support linear subtitle text size scaling, font family picker, and persistence
  - Refine mobile sheet menus with direct list rows and settings shortcuts
- Fix audio delay mechanism:
  - Add VideoOffsetRenderer to AiSubtitleRenderersFactory adjusting video presentation timestamps
  - Wire PlayerScreen audio delay adjustments to dynamic renderer delay
- Address 22 code review findings across player, details, and translation services:
  - Track episode stream identity for autoplay in Details
  - Debounce remote seeking keys and unify player exit callbacks to onExitPlayer
  - Connect subtitle sizing and vertical positioning to PlayerViewModel
  - Synchronize settings keys for subtitle preloading and language filtering
  - Preserve playback position on retry and fix ExoPlayer track selection indices
  - Add auto-advance one-shot latch to mobile player
  - Optimize audio capture buffers (ShortBuffer bulk read, loop-based FloatBuffer)
  - Thread-safe Gemini live translation segmentation and audio queue draining
  - Resilient subtitle batch translation error handling with atomic pending counter
  - Pass Gemini API key in x-goog-api-key header
  - TV player scrubbing base position initialization and interaction timer reset
  - TV subtitle menu selection matching and localized string resources
…ookahead, and gesture lifecycle

- Align subtitle sizing clamp range to 50-250 across stepper, overlay, VM, and engine styling
- Delegate formatLanguageDisplayName to getFullLanguageName to eliminate duplicate language mapping
- Decouple volume button observer in ArvioMobilePlayer from volumeBoostDb key using rememberUpdatedState
- Allow unhandled TV keys in subtitle settings and track menu to pass through instead of consuming
- Use shared applySubtitleAppearance on PlayerEngineSurface with PiP scaling support
- Generate character-bigram tokens for text without spaces in SubtitleSyncMatcher for CJK subtitles
- Cache reflection fields and bound cue extraction in AiSubtitleRenderersFactory
@Himanth-reddy
Himanth-reddy force-pushed the feature/modular-player-architecture branch from 7ce3af0 to a9812c1 Compare September 4, 2026 15:02
Arvin added 2 commits September 5, 2026 13:54
Retain current TV seeking/native previews and Details quality selection. Use the shared end-of-episode gate, cancel interrupted scrubs, keep gesture callbacks current, release the engine wrapper, preserve episode identities, and wire subtitle controls. Add mobile interaction and real-engine device tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: android Changes to the Android app or Gradle build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants