AGENTS.md 8.1 KB

GMPlayer Handoff Notes

Current Project State

GMPlayer is a native mobile app workspace for collecting internet video URLs and playing them directly. The project currently has:

  • iOS app in Swift + UIKit.
  • Android app in Kotlin + Jetpack Compose.
  • Shared requirements in docs/requirements.md.
  • Design/exported player button assets in design-assets/player-buttons.

The root directory is not currently a Git repository in this environment, so use file inspection rather than Git history for handoff context.

Product Flow

Current main flow:

  1. User enters an http or https video URL.
  2. URL must end with .m3u8 or .mp4.
  3. Valid URLs are added to a local in-memory history list, newest first, max 3 items.
  4. Tapping play/add opens a full-screen player view.

iOS Status

Main files:

  • ios/GMPlayer/PlayerViewController.swift

    • Main URL input and history screen.
    • Validates .m3u8 and .mp4.
    • Presents VideoPlayerViewController(url:).
  • ios/GMPlayer/VideoPlayerViewController.swift

    • Full-screen custom player based on AVPlayer and AVPlayerLayer.
    • Uses custom controls, not AVPlayerViewController.
    • Plays automatically on appear.
    • Supports close, play/pause/replay, seek backward/forward 15 seconds, progress display, and drag-to-seek.
    • Control overlay behavior:
    • Tap empty video area to show/hide controls.
    • When visible, controls auto-hide after 4 seconds without interaction.
    • Show/hide uses fade animation.
    • Playback buttons and progress dragging reset the auto-hide timer.
  • ios/GMPlayer/MobilePlaybackControlsView.swift

    • Center control group.
    • Supports side controls mode:
    • .skip15
    • .playlist
    • .hidden
  • ios/GMPlayer/PlayerControlsConfiguration.swift

    • Current side button mode is configured here.
  • ios/GMPlayer/MobileProgressBarInfoView.swift

    • Bottom title/time/progress area.
    • Height expected to be 106.
    • Progress bar supports horizontal scrubbing.
  • ios/GMPlayer/MobileMainControllerButton.swift

  • ios/GMPlayer/MobileSkipButton.swift

    • Custom button rendering using exported PNG resources.
    • Circular background uses UIVisualEffectView with .systemUltraThinMaterialDark.
    • No additional black overlay on iOS.

Temporary native system player testing was removed. There should be no SystemVideoPlayerViewController.swift.

iOS Assets

Player button assets live in:

  • ios/GMPlayer/Assets.xcassets/player_button_play.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_pause.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_replay.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_go_backwards_15.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_go_forward_15.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_skip_backward.imageset
  • ios/GMPlayer/Assets.xcassets/player_button_skip_forward.imageset

App icon assets are in:

  • ios/GMPlayer/Assets.xcassets/AppIcon.appiconset

iOS Build And Run

Known working simulator:

  • iPhone 17
  • iOS 26.5
  • UDID: 68D65FB5-95B9-4E38-8552-2A1934459005

Build:

xcodebuild -project ios/GMPlayer.xcodeproj -scheme GMPlayer -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.5' build

Install and launch:

open -a Simulator
xcrun simctl boot 68D65FB5-95B9-4E38-8552-2A1934459005
xcrun simctl install 68D65FB5-95B9-4E38-8552-2A1934459005 /Users/flyzto/Library/Developer/Xcode/DerivedData/GMPlayer-bikaarnrdbqjvfbzwmpbnythjtrj/Build/Products/Debug-iphonesimulator/GMPlayer.app
xcrun simctl launch 68D65FB5-95B9-4E38-8552-2A1934459005 com.gmplayer.app

Last verified iOS run:

  • Date: 2026-06-10
  • Build succeeded.
  • Installed and launched on iPhone 17 / iOS 26.5.

Known warning:

  • PlayerViewController.swift uses deprecated UIButton.contentEdgeInsets; currently harmless for this scaffold.

Android Status

Main files:

  • android/app/src/main/java/com/gmplayer/app/MainActivity.kt

    • Main URL input and history screen.
    • Opens AndroidPlayerScreen after a valid URL is added.
    • AndroidPlayerScreen uses Android VideoView with Compose overlays.
    • Control overlay behavior is synchronized with iOS intent:
    • Tap video area to show/hide controls.
    • Auto-hide after 4 seconds when visible.
    • Fade in/out animation is 220ms.
    • Button interactions reset the timer.
    • Android back exits the player screen.
  • android/app/src/main/java/com/gmplayer/app/MobilePlaybackControls.kt

    • Center control group.
    • Supports side controls mode:
    • Skip15
    • Playlist
    • Hidden
    • Android button backgrounds include a 25% black circular layer so transparent exported icons remain visible.
  • android/app/src/main/java/com/gmplayer/app/MobileMainControllerButton.kt

  • android/app/src/main/java/com/gmplayer/app/MobileProgressBarInfo.kt

  • android/app/src/main/java/com/gmplayer/app/PlayerControlsConfiguration.kt

Android Assets

Button resources were copied from design-assets/player-buttons into Android resource folders. Current button names include:

  • player_button_play
  • player_button_pause
  • player_button_replay
  • player_button_go_backwards_15
  • player_button_go_forward_15
  • player_button_skip_backward
  • player_button_skip_forward

Android Build Notes

This environment currently does not have:

  • android/gradlew
  • global gradle

So Android has not been compiled locally after the latest player overlay changes. Open android/ in Android Studio or add/sync a Gradle wrapper before verifying:

cd android
./gradlew :app:assembleDebug

Player UX Details

iOS currently has the most complete custom player implementation:

  • Custom full-screen player.
  • Center play/pause/replay and side controls.
  • Bottom progress info area.
  • Drag-to-seek.
  • Auto-hide controls.
  • Fade transitions.

Android has the matching overlay behavior at the Compose level, but playback is currently implemented with VideoView. If parity matters for HLS behavior and richer controls, consider moving Android playback to Media3 ExoPlayer.

Design/Figma Context

The player UI was based on the Figma file:

  • Video Player For Web Mobile Community
  • File key: ApvSwPRpW7jYhJ0xUohpT4

Relevant Figma nodes previously inspected/used:

  • Mobile Player node: 21:4432
  • Play button states: 40:99

The user exported button PNGs at @1x, @2x, and @3x. Figma default @1x export has no suffix; these were mapped into iOS imagesets and Android drawable resources.

Important Decisions Already Made

  • The app should use native projects for iOS and Android.
  • React component generation is not needed.
  • iOS should use the custom player, not AVPlayerViewController, for the product direction.
  • Main page should not embed a player placeholder.
  • Clicking play/add should open a full-screen player.
  • Player should not show subtitle.
  • iOS control button blur uses .systemUltraThinMaterialDark.
  • Android uses a 25% black circular background behind transparent button icons for now.
  • Side controls should show only one set:
    • 15-second seek controls, or
    • previous/next controls, or
    • no side controls.

Known Gaps / Next Steps

  • Android build needs Gradle wrapper or Android Studio sync.
  • Android playback should likely be upgraded from VideoView to Media3 ExoPlayer for robust .m3u8 and .mp4 parity.
  • Android progress info is currently static in the overlay and should be wired to playback position/duration.
  • Android drag-to-seek is not yet implemented.
  • iOS AirPlay, playback speed, mute, and full-screen controls were discussed earlier, but the current restored custom player only has the implemented subset described above.
  • History is in-memory only on both platforms; persistence has not been added.
  • No automated tests are currently present.

Suggested Next Implementation Order

  1. Verify Android project in Android Studio or add gradlew.
  2. Replace Android VideoView with Media3 ExoPlayer.
  3. Wire Android progress, duration, and drag-to-seek.
  4. Add persistent history storage on both platforms.
  5. Add player speed, mute, full-screen/orientation behavior, and AirPlay where required.
  6. Add focused unit/UI tests for URL validation and player state transitions.