0W-Tube ("Zero-Wait Tube") is a lightweight Android TV video search and playback client for RUTUBE, public VK Video, Dzen, OK, and public PeerTube content. It is designed for low-memory TV devices and projectors where the official applications are too heavy or slow.
The application uses a native Android interface, the system on-screen keyboard, direct network requests, and hardware-only video decoding. It supports phones as well as TVs, without a WebView or VK user account. On phones, audio-only playback can continue in a foreground service with a playback notification.
- Unified, concurrent search across RUTUBE, public VK Video, Dzen, OK, and PeerTube results.
- Local title-relevance ranking with known maximum quality as a tie-breaker.
- Maximum-quality badges are filled in on video cards without blocking the UI.
- Anonymous VK Video web session created automatically; no account or user token is required.
- Selectable quality filters: any quality, 720+, 1080+, 1440+, and 2160/4K.
- Search results and resolved qualities are cached in memory, so changing a quality filter does not repeat backend searches.
- Validation against the formats actually available for each video.
- Highest useful hardware-supported stream selected for playback, up to 3840×2160.
- HLS, DASH, and direct-stream playback through AndroidX Media3/ExoPlayer.
- Hardware-only video decoder selection to avoid expensive software decoding.
- TV remote navigation throughout search results and quality filters.
- Lightweight thumbnail grid with view recycling and a bounded in-memory image cache.
- Playback controls displayed over the video.
- Playback speed from 0.75× to 2× with unchanged pitch, and per-video hardware-accelerated mirroring.
- A movable playback overlay on touchscreens: drag it away from subtitles; it returns on release.
- Local watch history for up to 1000 videos, with thumbnails loaded as cards become visible.
- Traffic-saving quality selection and audio-only playback.
- Restoration of the last search, selected quality filter, open video, and playback position.
- Asynchronous GitHub Release update checks with SHA-256 verification and the Android system installer.
- Per-video local watch progress after the first minute, including subsequent rewinds back to the beginning.
- Fresh signed stream URLs resolved immediately before playback.
- Local crash diagnostics retained without an intrusive launch dialog.
0W-Tube was created for and tested on an XGIMI HORIZON Pro with:
- Android 11 / API 30;
- four ARM Cortex-A55 cores at up to 1.5 GHz;
- approximately 1.7 GB of usable RAM and a 192 MB application heap;
- 32-bit
armeabi-v7auserspace; - Mali-G52 graphics;
- a 1920×1080 Android UI surface and 3840×2160 projector output;
- hardware AVC/H.264, HEVC/H.265, VP8, VP9, AV1, and AAC decoders.
The minimum supported Android version is Android 6.0 (API 23). Other Android TV devices should work, but have not been tested.
- D-pad: move between the search field, quality filters, and video cards.
- Center/OK: select a filter, start a search, or open a video.
- System keyboard: enter the search query.
- Down: open history; hold Down while navigating the video grid. In history, hold Up to return, or press Up at its top edge.
On phones, swipe left across the grid to open history and right to return. The keyboard's search action submits the query.
- Center/OK: pause or resume playback.
- Left: seek backward 15 seconds.
- Right: seek forward 30 seconds.
- Hold Left/Right: move the seek bar; release to seek to the selected position.
- Up: show the playback controls.
- Down on Android TV: open history.
- Menu (≡), or hold Center/OK: open speed and mirroring settings.
- Back: close settings or return to the previous search/history screen.
The control overlay hides automatically during playback and shortly after pausing. Touch controls remain available on phones.
RUTUBE search uses its public video search endpoint. Playback options are resolved immediately before opening a video, and the HLS stream is selected from the returned balancer data.
VK Video search uses the same anonymous web API flow as the public vkvideo.ru search page. The application obtains a short-lived anonymous session and never asks for a VK account token. Public playback metadata is resolved separately for each selected video.
Dzen search uses its public JSON search API, with a server-rendered HTML fallback. The application keeps only anonymous session cookies, resolves fresh public stream metadata before playback, and uses the same quality filters as the other sources.
OK search reads the public anonymous video-search component. Playback follows the same public metadata flow as yt-dlp's Odnoklassniki extractor: inline player metadata first, then the metadata endpoint and mobile-page fallback. Native OK HLS, DASH, and direct streams are supported without an account; external providers are ignored unless the application already supports them.
PeerTube search uses the global Sepia Search index as a low-priority backend. Results are conservatively filtered for a complete film title and long-form duration, then verified against the originating PeerTube server before a card is shown. Playback prefers a reachable HLS master playlist; traffic-saving audio mode prefers an explicit audio-only file or HLS audio rendition and uses a low-resolution muxed stream only as a fallback.
Private, deleted, region-restricted, DRM-protected, age-gated, or account-only videos may not be available. These public web interfaces can change independently of the application and may require future compatibility updates.
0W-Tube stores only application state on the device:
- the last search query and selected filter;
- the last open video and position;
- per-video playback progress after one minute;
- up to 1000 history entries and saved progress/mirroring records;
- playback speed, traffic-saving preferences, and mirroring state;
- the most recent crash diagnostic.
No user account credentials or permanent VK access tokens are stored. Search and playback requests are sent directly from the device to the respective video services and their CDN hosts. Android cloud backup and device transfer are disabled for application data, including history and page URLs that may contain access keys. Thumbnails have a bounded RAM cache and are not cached on disk.
Signed APKs are published on the GitHub Releases page for every version tag. Each release also includes a SHA-256 checksum file.
To install a locally produced debug build instead, use:
app/build/outputs/apk/debug/app-debug.apk
Install it with ADB:
adb install -r app/build/outputs/apk/debug/app-debug.apkThe package ID remains ru.tubetv.app. Upgrades preserve settings and watch progress when signed with the same key. A locally signed debug build cannot replace a release-signed installation without uninstalling it first.
Requirements:
- JDK 17;
- Android SDK with API 36 installed;
- The included Gradle Wrapper downloads the pinned Gradle 9.5.0 distribution.
Build the debug APK:
./gradlew :app:assembleDebugRun the regression tests, Android lint, and both release builds:
./gradlew :app:testDebugUnitTest :app:lintRelease :codecprobe:lintRelease assembleRelease
python3 -m unittest research.test_peertube_search_prototypeThe current application version is defined in app/build.gradle.
Without release-key environment variables, release builds are unsigned. codecprobe is a separate diagnostic APK; it is not included in 0W-Tube. The check.yml workflow runs verification on main-branch pushes and pull requests.
After playback changes, also exercise these scenarios on a phone and an Android TV device: close the player while its stream is resolving; switch between foreground and background audio; return immediately after sending audio to the background; switch to another video; rewind a watched video below one minute and reopen it; hold/release the seek buttons; change mirroring and playback speed. Local JVM tests do not exercise a device's audio/video drivers.
Pushing a Git tag triggers .github/workflows/release.yml. The workflow verifies that the tag matches versionName, runs tests and Android lint, builds a minified unsigned APK, optimizes its ZIP compression, aligns it, and signs it once with the persistent release key. It verifies alignment and the signature before creating a GitHub Release. The R8 mapping is preserved as a separate workflow artifact for decoding crash reports.
The signing key and passwords are supplied through the RELEASE_KEYSTORE_BASE64, RELEASE_STORE_PASSWORD, RELEASE_KEY_ALIAS, and RELEASE_KEY_PASSWORD repository secrets. Never commit a release keystore or its passwords.
app/src/main/java/ru/tubetv/app/
MainActivity.java Search UI, filters, results, and state restoration
SearchClient.java RUTUBE search client
VkWebClient.java Anonymous VK Video search client
DzenClient.java Anonymous Dzen search client
OkClient.java Anonymous OK search and player metadata client
PeerTubeClient.java Federated PeerTube search, filtering, and stream inspection
VideoRanker.java Fast local title-relevance ranking
StreamResolver.java Fresh stream resolution for every supported backend
MediaCapabilities.java Cached dimensions, without temporary stream URLs
BoundedHttpReader.java Response size limits and cancellation checks
ParallelTasks.java Shared bounded quality-inspection pool
PlaybackEngineFactory.java Shared hardware-decoder and streaming configuration
ScopedCookies.java Request-scoped playback cookies
PlayerActivity.java Media3 player and TV remote controls
AudioPlaybackService.java Foreground audio playback on phones
WatchHistoryStore.java Bounded local history
WatchProgressStore.java Per-video local playback progress
ImageLoader.java Bounded thumbnail loader and memory cache
The research directory contains notes used to understand device capabilities and public playback formats. Downloaded APKs and decompiled source trees are intentionally excluded from Git.
- AndroidX Media3 for playback.
- yt-dlp as a reference for public video format behavior.
Copyright © 2026 Evgeny Stepanischev.
This project is licensed under the MIT License.