Skip to content

Latest commit

ย 

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

VideoSkipper App Icon

๐ŸŽฌ VideoSkipper

Automatically skip unwanted Reels & Shorts using on-device OCR.

An Android automation app that detects user-defined keywords on short-form videos and automatically scrolls past matching content โ€” 100% on-device, no cloud, no data upload.

Android Kotlin Jetpack Compose Minimum SDK License

Features โ€ข How It Works โ€ข Architecture โ€ข Installation โ€ข Permissions โ€ข Limitations


๐ŸŽฅ Demo

VideoSkipper Demo

VideoSkipper automatically detects unwanted content and skips it.

โ–ถ๏ธ Watch the full demo on YouTube


๐Ÿ“ธ Screenshots

Screen recordings:

AppSetup.mp4
AppUsage.mp4

VideoSkipper running on top of short-form video applications.


๐Ÿ“ฑ What is VideoSkipper?

VideoSkipper automatically skips short-form video content when it detects user-defined keywords on the screen.

It currently works with:

  • Instagram Reels

VideoSkipper monitors the foreground screen, captures a screenshot when a genuine scroll occurs, extracts visible text using Google ML Kit's on-device OCR, and checks the detected text against the user's saved keywords. If a keyword matches, it automatically performs a swipe gesture to move to the next video โ€” all processed locally on the device.

flowchart TD
    A([User Scrolls]) --> B[AccessibilityService]
    B --> C[Detect Scroll Event]
    C --> D[Capture Screenshot]
    D --> E[Downscale Bitmap]
    E --> F[ML Kit OCR]
    F --> G[Extract Text]
    G --> H{Match Keyword?}
    H -- Yes --> I[Swipe to Next Video]
    H -- No --> J[Do Nothing]
Loading

โœจ Features

๐Ÿ” Real-Time Detection Detects text appearing on Reels and Shorts using on-device OCR.
๐Ÿค– Automatic Skipping Automatically performs a swipe when a configured keyword is detected.
๐Ÿ’ฌ Floating Bubble Add keywords and control detection without leaving the currently opened app.
๐Ÿ”‹ Battery Conscious Uses event-based detection, foreground-app gating, bitmap optimization and automatic safeguards.
๐Ÿ”’ Fully On-Device OCR processing happens locally โ€” screenshots are never uploaded to a server.
๐ŸŽ›๏ธ Independent Controls Text and image detection can be toggled independently.

๐Ÿ—๏ธ Architecture

VideoSkipper follows a Clean Architecture + MVVM approach with clear separation between presentation, domain logic, and data sources.

VideoSkipper
โ”‚
โ”œโ”€โ”€ presentation
โ”‚   โ”œโ”€โ”€ screens
โ”‚   โ”œโ”€โ”€ components
โ”‚   โ””โ”€โ”€ floating overlay UI
โ”‚
โ”œโ”€โ”€ viewmodel
โ”‚   โ”œโ”€โ”€ MonitoringViewModel
โ”‚   โ””โ”€โ”€ TextViewModel
โ”‚
โ”œโ”€โ”€ domain
โ”‚   โ””โ”€โ”€ repository
โ”‚       โ”œโ”€โ”€ KeywordRepository
โ”‚       โ”œโ”€โ”€ MonitoringRepository
โ”‚       โ”œโ”€โ”€ AutoScrollDetectionRepository
โ”‚       โ””โ”€โ”€ ScreenActionController
โ”‚
โ”œโ”€โ”€ data
โ”‚   โ””โ”€โ”€ repository
โ”‚       โ”œโ”€โ”€ Room-backed repositories
โ”‚       โ”œโ”€โ”€ DataStore-backed repositories
โ”‚       โ””โ”€โ”€ ML Kit-backed repositories
โ”‚
โ”œโ”€โ”€ service
โ”‚   โ”œโ”€โ”€ PizzaDetectorAccessibilityService
โ”‚   โ””โ”€โ”€ OverlayService
โ”‚
โ””โ”€โ”€ di
    โ”œโ”€โ”€ DatabaseModule
    โ””โ”€โ”€ RepositoryModule

Layer flow:

flowchart TD
    UI[Compose UI] --> VM[ViewModel / StateFlow]
    VM --> DOM[Domain Layer โ€” Repository Interfaces]
    DOM --> DATA[Data Layer โ€” Room / DataStore / ML Kit]
    DATA --> SVC[Android Services โ€” Accessibility / WindowManager]
Loading

๐Ÿ› ๏ธ Tech Stack

Category Technology
Language Kotlin
UI Jetpack Compose
Design Material 3
Architecture Clean Architecture + MVVM
Dependency Injection Hilt
Local Database Room
Preferences DataStore
Concurrency Kotlin Coroutines
Reactive State Kotlin Flow / StateFlow
OCR Google ML Kit Text Recognition
Screen Capture AccessibilityService takeScreenshot()
Automation AccessibilityService dispatchGesture()
Overlay WindowManager + ComposeView
Minimum Android Version Android 11 / API 30

โš™๏ธ How It Works

1 ยท Floating Overlay

OverlayService creates a draggable floating bubble using WindowManager. The overlay lets users add keywords, enable/disable detection, and control VideoSkipper without leaving Instagram, YouTube, or TikTok.

2 ยท Detecting Scroll Events

PizzaDetectorAccessibilityService listens for accessibility events generated by the watched application. Instead of reacting to every accessibility event, VideoSkipper focuses specifically on TYPE_VIEW_SCROLLED, which avoids unnecessary OCR triggered by:

  • Video progress updates
  • Caption animations
  • UI changes
  • Content refreshes

3 ยท Screenshot Capture

When a genuine scroll is detected, the accessibility service captures the screen via takeScreenshot(). The bitmap is downscaled before OCR processing to reduce memory usage and CPU consumption.

4 ยท On-Device OCR

The processed bitmap is passed to ML Kit Text Recognition โ€” no cloud OCR service required.

flowchart LR
    A[Screenshot] --> B[Bitmap Processing] --> C[ML Kit] --> D[Recognized Text]
Loading

5 ยท Keyword Matching

The recognized text is compared against the user's active keyword list, stored locally.

flowchart LR
    A[Detected Text] --> B[Active Keywords] --> C[String Matching] --> D{Keyword Found?}
Loading

6 ยท Automatic Swipe

On a match, the service calls dispatchGesture() to perform a synthetic swipe past the current video.

flowchart LR
    A[Keyword Found] --> B["dispatchGesture()"] --> C[Swipe Up] --> D[Next Reel / Short]
Loading

๐Ÿ”‹ Performance & Battery Engineering

Performance was a major part of the implementation.

Event precision โ€” The initial implementation relied on TYPE_WINDOW_CONTENT_CHANGED, which fired excessively as content changed. It was replaced with TYPE_VIEW_SCROLLED, drastically cutting unnecessary screenshot/OCR cycles.

Foreground-app gating โ€” OCR only runs when a supported app is actually in the foreground.

flowchart TD
    A[Instagram / YouTube / TikTok] --> B{App in Foreground?}
    B -- Yes --> C[Run OCR]
    B -- No --> D[Do Nothing]
Loading

Bitmap optimization โ€” Screenshots are downscaled before processing.

flowchart LR
    A[1080px Screenshot] --> B[Bitmap Downscale] --> C[720px Processing Image] --> D[ML Kit OCR]
Loading

Mutex protection โ€” Detection cycles are protected by a Mutex, preventing overlapping screenshot/OCR operations when scroll events fire rapidly.

Automatic safety stop โ€” A 6-hour automatic stop safeguard prevents an unattended accessibility session from continuously draining battery.


๐Ÿ› Notable Bug Fix

During development, the accessibility service appeared as Connected / Enabled in Android system settings, but received zero accessibility events.

Inspecting the runtime AccessibilityServiceInfo revealed:

eventTypes = 0
typeAllMask = -1

The service configuration was never actually applied โ€” the root cause was a one-character typo in the manifest metadata key.

Metadata Key
โŒ Incorrect android:name="android.accessibility.service"
โœ… Correct android:name="android.accessibilityservice"

Android silently ignored the incorrect key, breaking the entire event-processing pipeline.


๐Ÿš€ Getting Started

Requirements

  • Android Studio
  • Kotlin
  • Android SDK
  • A physical Android device (required โ€” the app depends on Accessibility APIs and takeScreenshot(), which don't behave reliably on emulators)
  • Android 11 / API 30 or higher

๐Ÿ“ฆ Installation

# 1. Clone the repository
git clone https://github.com/mohitdamke/VideoSkipper.git

# 2. Open the project in Android Studio
# 3. Let Gradle sync and build
# 4. Run on a physical Android 11+ device

๐Ÿ” Required Permissions

VideoSkipper needs special Android permissions to interact with other apps.

Permission Path Why
Display over other apps Settings โ†’ Apps โ†’ Special app access โ†’ Display over other apps โ†’ VideoSkipper โ†’ Allow Powers the floating overlay bubble
Accessibility Service Settings โ†’ Accessibility โ†’ Installed / Downloaded apps โ†’ VideoSkipper โ†’ Enable Detects scrolls, captures screenshots, and performs swipes
Restricted settings (Android 13+, sideloaded installs) App Info โ†’ โ‹ฎ โ†’ Allow Restricted Settings Required before Accessibility can be enabled on sideloaded builds

โš ๏ธ Limitations

  • Requires Android 11 / API 30+
  • OCR accuracy depends on text visibility, size, contrast, and styling
  • Highly stylized or animated text may not be detected
  • Current keyword matching is substring-based
  • Accessibility-based automation apps may face Google Play policy restrictions
  • Image detection UI exists, but the full image-detection pipeline isn't implemented yet
  • Continuous screen analysis can still consume battery despite optimization

๐Ÿ”’ Privacy

VideoSkipper is built around on-device processing. The OCR pipeline never uploads screenshots to a remote server, and captured screen content is not intentionally persisted to disk as part of the detection pipeline.

โš ๏ธ Accessibility services have powerful capabilities on Android. Only enable VideoSkipper if you understand and trust the permissions being granted.


๐Ÿ“‚ Project Highlights

Android Fundamentals

  • Jetpack Compose
  • Material 3
  • WindowManager overlays

Architecture

  • Clean Architecture
  • MVVM
  • Hilt Dependency Injection

Systems & Performance

  • Accessibility Services
  • takeScreenshot() / dispatchGesture()
  • ML Kit OCR
  • Bitmap optimization
  • Concurrency control (Coroutines, Flow, Mutex)
  • Battery-conscious background processing

๐Ÿ“„ License

This project currently does not specify a license. If you plan to open-source the repository, consider adding MIT or Apache-2.0.


๐Ÿ‘จโ€๐Ÿ’ป Author

Mohit Damke Android Developer


Made with โค๏ธ using Kotlin & Android

๐ŸŽฌ VideoSkipper โ€” Scroll less. See what you want.

About

Automatically skip unwanted Reels & Shorts using on-device OCR.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages