Home Creators Posts Import Register Favorites Logout

Videos

Content

Vexxx TV — Features

A native Android TV client for Vexxx (Stash fork), built with Jetpack Compose for TV and ExoPlayer/Media3.

Setup & Onboarding

Dedicated setup screen shown on first launch and after disconnect.

Server URL and optional API key fields with appropriate keyboard types.

API key field is password-masked.

Tab-order focus: URL → API Key → Connect, navigable via remote.

Auto-focuses the URL field on screen entry.

Validates connection before navigating away; shows error if unreachable.

“Change Server” and “Disconnect” actions available from Settings at any time.

Navigation Shell

Persistent side-drawer (TvNavDrawer) wrapping Home, Browse, Search, and Settings — always accessible while outside the player.

Top-level destinations: Home, Browse (by content type), Search, Settings.

Jetpack Navigation handles the full back-stack including the player.

Home Screen

Hero Banner

Full-screen cross-fading background pulled from the focused scene’s screenshot.

Debounced 300 ms so rapid D-pad scrolling through cards doesn’t trigger unnecessary image loads.

Metadata panel (bottom-left): title, studio, performers, tags, release date, duration, resolution, star rating, and a direct Play button.

Blurred in SFW mode.

Carousels

Each scene carousel has a View All card at the end that navigates to the Browse screen.

Scroll position is saved and restored when returning from a detail screen.

Server library statistics footer (scene count, duration, etc.).

Browse Screen

Content Types

Tabs: Scenes · Performers · Studios · Galleries · Images · Groups · Tags

Grid & Pagination

Adaptive grid sized to card dimensions (e.g. 320 dp wide for scenes).

40 items per page with a pagination bar (Previous / Next, page X of Y).

Item count and current range displayed above the grid (1–40 of 412).

Search

Inline search field toggled via a button in the toolbar.

400 ms debounce so network requests are batched.

Per-tab query is preserved when switching between content types.

Active query displayed as a pill on the search button; click to clear.

Filters

Filter panel accessible via a Filters button (visible on tabs that support filtering).

Active filter count shown on the button badge.

Filter options are loaded lazily the first time the panel is opened.

Alpha-Jump

On the Scenes tab, pressing a letter key on a physical keyboard scrolls the grid to the first scene whose title begins with that letter.

A transient letter indicator confirms the jump and auto-dismisses after 800 ms.

Search

Universal search bar across scenes, performers, studios, tags, and groups simultaneously.

Requires at least 2 characters before querying the server.

Results displayed as horizontal carousels grouped by type.

Each section header shows the number of results returned vs. total matches (5 of 128).

Loading spinner shown inline in the search bar header.

Auto-focuses the text field on screen entry so typing can begin immediately.

“No results” and error states with descriptive messages.

Video Player

Playback Engine

ExoPlayer (Media3) with a pure-Compose ContentFrame surface — no AndroidView/PlayerView interop.

HLS streaming over the Vexxx server’s native stream endpoint.

OkHttpClient shared with Apollo GraphQL for connection pooling and API key authentication on every HLS request (playlist, key files, media segments).

MediaSession wired up so Bluetooth remotes, earphone buttons, and the Google TV system UI can control playback.

Track Selection & Codec

Prefers H.264 and caps video at 1080p to avoid software-decoding 4K on lower-end hardware.

Hardware tunneling enabled on real devices for efficient display pipeline use; disabled on emulators (Goldfish/Ranchu).

Audio offload enabled on capable hardware to reduce CPU load during long sessions.

Extension renderer mode ON (platform codecs first, software extensions as fallback).

Decoder fallback so ExoPlayer retries with another codec on init failure instead of crashing.

Seeking

TS timestamp search window widened ×3 for more accurate HLS seeks.

Constant bitrate seeking enabled so seeks start immediately without waiting for keyframe detection.

Resume & Progress

Resume position saved to the server every 10 seconds during playback.

Position restored on next open (converted between clip-relative and absolute file offsets for segment support).

“Resume at X:XX” indicator on the scene detail play button; a dialog lets the user choose Resume or Play from Start.

Play count recorded after 10 consecutive seconds of active playback.

Segment / Virtual Scene Support

Scenes with start_point and end_point fields are played as a clipped sub-region of the underlying file.

Resume positions and marker timestamps are stored/displayed as absolute file seconds, not clip-relative, keeping sync with the web app.

Chapters / Markers

Chapter tick marks drawn on the progress bar at each marker’s position.

Active chapter is tracked in real time (polling every 500 ms) and highlighted.

Chapter sidebar slides in from the right edge:

Shows all chapters with a 16:9 thumbnail, title, and timestamp.

Active chapter is visually highlighted.

Auto-scrolls to the active chapter as playback progresses.

D-pad focus is automatically placed on the active (or first) chapter when the sidebar opens.

Clicking a chapter seek bar chip on the scene detail screen deep-links directly into the player at that timestamp.

Controls Overlay

Fade-in/fade-out controls bar at the bottom of the screen.

Seek bar with live position and duration timestamps.

Buttons: Bookmarks (chapters toggle, only visible when the scene has markers), Seek Back 10 s, Play/Pause, Seek Forward 30 s.

Auto-hides after 5 seconds of playback with no interaction (pinned while the chapter sidebar is open).

D-pad focus moves automatically to the Play/Pause button when controls appear.

Scene title displayed above the seek bar while controls are visible.

Playback Queue & Auto-Advance

PlaybackQueue supports sequential scene playback (e.g. from a playlist).

Navigates to the next scene automatically when the current one ends.

Triggers a Google TV Watch Next row sync (via ChannelSyncWorker) on scene completion.

Lifecycle

Pauses automatically when the Activity goes to background (ON_STOP).

Player and MediaSession are fully released onCleared to prevent decoder/surface crashes.

Low-RAM Adaptation

Detects ActivityManager.isLowRamDevice() at runtime.

Low-RAM devices: min 10 s / max 20 s buffer, 12 MB byte cap.

Capable hardware: min 15 s / max 50 s buffer, auto byte limit.

Scene Detail

Full-screen blurred screenshot as background.

Metadata: title, studio chip (navigable), release date, director, rating, file info (resolution × height, duration, fps).

Description (up to 6 lines, ellipsised).

Play button — shows a Resume/Start-Over dialog if a save position exists.

More options dialog: O-counter (increment / decrement / reset), star rating (1–10), scene code, stream picker (multiple quality labels and MIME types).

Resume time indicator below the play button.

Tags — horizontal scrollable chips, each navigates to that Tag’s detail screen.

Chapters — horizontal scrollable chips showing timestamp + title; clicking one launches the player at that chapter.

Cast panel (right column): performer chips with thumbnail and name, each navigates to the Performer detail screen.

Related scenes from the same studio (horizontal carousel at the bottom).

Gallery Viewer

Full-screen image display with animated cross-fade between images.

Slideshow / Auto-Play — advances every 4 seconds, loops back to the first image at the end.

Auto-play toggle button in the top HUD; pauses on any manual navigation.

Image counter showing current position and total (e.g. 7 / 42).

Gallery title in the header.

Directional arrow hints shown at left/right edges when not at the boundary.

Chapter panel for galleries with defined sections:

Down arrow / Enter opens the panel; Up arrow closes it or moves to the previous chapter.

Up/Down navigate between chapters; Enter jumps to the selected chapter’s first image.

Back closes the panel before exiting the screen.

SFW blur applied to all images.

Performer Detail

Details Tab

Full-screen performer photo background (semi-transparent).

Name, disambiguation note, scene count badge, gender, rating, country.

Favourite toggle (heart button).

Portrait image (140 × 200 dp, rounded) — SFW-blurred.

Physical details: height, weight, measurements, eye colour, hair colour, ethnicity, country, birthdate, career length, tattoos, piercings.

Aliases horizontal row.

Tags horizontal row.

Biography text.

Scenes Tab

Paginated grid of all scenes featuring this performer.

Each scene card navigates to the Scene detail screen.

Studio Detail

Full-screen studio logo background.

Header: logo thumbnail, studio name, parent studio (if any), scene count, performer count, rating.

Description (single line, ellipsised).

Paginated scene grid with page range indicator.

Group Detail

Full-screen backdrop image (SFW-blurred).

Header: front-cover thumbnail (SFW-blurred), name, scene count, total duration, rating, director, studio, release date.

Synopsis (2 lines, ellipsised).

Tags row — each tag navigates to Tag detail.

Sub-groups horizontal carousel — each card shows the sub-group cover (SFW-blurred) and navigates to its own Group detail screen.

Paginated scene grid.

Tag Detail

Full-screen tag image background.

Header: tag icon, name, scene/performer/gallery counts.

Description.

Parent tags breadcrumb strip.

Child tags horizontal row — each navigates to that tag’s detail screen, showing its scene count.

Paginated scene grid.

Playlists

Smart Playlists (Home Screen)

Predefined curated playlists available as cards in a dedicated Home carousel.

Each entry navigates to the Playlist detail screen.

Playlist Detail

Left panel: cover image, title, description, scene count, total duration.

Play All — loads the playlist into the PlaybackQueue and navigates to the player at the selected index.

Shuffle — randomises the queue then starts playback.

Right panel: scrollable item list with track number, 16:9 thumbnail, title, duration, and a resume progress bar for scenes with a saved position.

Clicking an item navigates to that scene’s detail screen; “play from here” starts the queue from that position.

Safe-for-Work (SFW) Mode

A privacy toggle that blurs all media artwork app-wide, suitable for use in shared or public spaces.

Toggled in Settings; state persisted across sessions.

Provided via LocalSfwMode CompositionLocal at the navgraph root — no prop drilling required.

When enabled, a Modifier.blur(20 dp) (10 dp for performer portraits) is applied to every AsyncImage that displays media content.

A centred eye-slash SfwOverlayIcon is overlaid on every blurred surface to make the SFW state visually explicit.

D-Pad & Remote Navigation

Global

All interactive elements (cards, buttons, tabs) are Compose focus-traversal compatible.

Back button pops the nav back-stack; intercepted contextually (e.g. closes a panel before exiting a screen).

Player

Any key while controls are hidden: reveals controls; Left/Right also seeks ±10/30 s simultaneously.

While controls are visible: Compose focus handles Left/Right/Up/Down naturally between buttons (Bookmarks ← Seek Back ← Play/Pause → Seek Forward).

Chapters sidebar:

Bookmarks button opens the sidebar; D-pad focus automatically moves to the active (or first) chapter after 150 ms.

Left or Back closes the sidebar.

Up/Down traverse the chapter list via LazyColumn’s built-in scrolling.

Right is consumed (nothing to navigate beyond the right edge).

Back from the outer player while sidebar is open closes the sidebar rather than popping the back-stack.

Gallery Viewer

Left/Right: previous/next image.

Down: opens chapter panel (if chapters exist).

Up: closes chapter panel or moves to the previous chapter entry.

Enter / D-pad Centre: confirms chapter selection or opens the panel.

Back: closes chapter panel first, then exits the viewer.

Browse

Letter keys (A–Z) on a physical keyboard scroll the Scenes grid to the first matching title.

Files

Vexxx-TV

Comments

No comments found for this post.