LosslessCut (MP4) is a high-performance, open-source Android application for instant, lossless media trimming and merging. By manipulating compatible codecs (H.264, H.265, AAC) directly, it preserves original quality and processes files at lightning speed, remuxing them into standard .mp4 and .m4a containers without re-encoding.
- π Zero Quality Loss: Trims and merges video (
.mp4) and audio (.m4a) using nativeMediaExtractorandMediaMuxerβno transcoding involved. - ποΈ Pro Timeline: Desktop-class NLE timeline supporting multi-segment editing (Split, Discard, and Drag).
- π Precision Seeking: Zoom up to 20x for frame-accurate edits.
- π§² Keyframe Snapping: Mandatory, strict keyframe snapping in lossless mode ensures frame-perfect cuts. Features haptic feedback and visual snapping.
- π± Adaptive UI: Ergonomic landscape sidebars and a unified floating player overlay for maximum screen real estate.
- β Smart Playlist: Inline "Add Media" shortcut and intelligent duplicate detection on import.
- π΅ Audio-Only Mode: Intelligent UI adaptation for audio files with waveform visualization.
- π¦ Batch Export & Merge: Export multiple "KEEP" regions as individual clips or merge them into a single seamless file in one pass.
- πΌ Smart Audio Extraction: Automatically saves audio-only exports (when video is unchecked) as lossless
.m4afiles in theMusicfolder. - βΏ Accessibility First: Comprehensive screen reader support via virtual view hierarchies (
ExploreByTouchHelper). - π Non-Destructive Workflow: Full Undo/Redo stack for all segment operations.
- π€ Smart Cut (v2.0): Unified, tabbed interface combining Silence Cut and Visual Detection.
- Silence: Automated, parameterized removal of quiet sections with interactive "Ghost State" visualizations and live savings previews.
- Visual: Algorithm-driven segment detection for Scene Changes, Black Frames, Freeze Frames, and Blur Quality.
- βΈοΈ Intelligent Focus: Auto-pause playback when opening settings, export options, or silence detection to prevent missing content.
- β¨ Contextual UX: Seamless, auto-dismissing timeline hints and haptic feedback for a clean, professional interface.
- πΎ Project Persistence: Seamless session restorationβresume your edits exactly where you left off.
- π Custom Output Path: Flexible export folder selection via Storage Access Framework (SAF).
- π Remux & Convert: Change container formats (e.g., MKV to MP4) instantly without re-encoding.
- π·οΈ Quick Metadata Fix: Correct video orientation and rotation flags in seconds.
- ποΈ Clean Architecture: Context-free ViewModels and a centralized Repository pattern for maximum maintainability.
- π§ Format Compatibility: Optimized for modern codecs and containers (MP4, AAC). See Technical Reference for details.
Unlike traditional video editors that decode and re-encode every frame, LosslessCut operates at the container level:
- Probe: Scans the file structure to identify stream metadata and track availability.
- Visualize: Renders a zoomable timeline where keyframes are marked as snapping points.
- Mux: During export, the app extracts the original encoded samples between cut points and remuxes them into a new container. If the video track is excluded, it smartly routes to an audio-only
.m4acontainer to preserve original quality.
- Android Studio Koala+
- Android SDK 36 (Target) / 26 (Min)
# Clone the repo
git clone https://github.com/tazztone/lossless-video-cut.git
# Generate icons (Consolidated tool)
java dev-scripts/asset-generate-icons.java
# Build debug APK using Gradle Kotlin DSL
./gradlew assembleDebugWe follow MVVM + Clean Architecture with a strict separation between UI, Domain, and Data layers.
- Multi-Module: Core logic belongs in
:core:domain,:core:data, or:engine. - Use Cases: All business logic MUST reside in Use Cases within the
:core:domainmodule. - Workflow: Create a feature branch for every change and ensure CI passes before opening a PR.
- Code Style: Follow standard Kotlin conventions and avoid "God Classes".
If you discover a security vulnerability within LosslessCut, please do not open a public issue. Instead, report it privately to the maintainers. We aim to respond to all reports within 48 hours and provide a fix or mitigation plan as soon as possible.
- Privacy-First Model: Removed all unnecessary runtime permissions (Notifications, Media Access). The app relies on the Storage Access Framework (SAF) for user-initiated file selection.
- Scoped Storage: Uses
MediaStoreto save results toMovies/LosslessCut(video) orMusic/LosslessCut(audio extraction). - Privacy: 100% offline. No analytics, no tracking, no data collection.
- Smart Cut (v2.0): Integrated advanced algorithm-driven visual detection (Scene, Black, Freeze, Blur) and unified it with Silence Cut.
-
Task Orchestration(Shelved: Background orchestration not required for near-instant exports) - Advanced Tags: Title, artist, and creation date editing.
- Architectural Enforcement: Implement Konsist testing to safeguard module boundaries in the CI pipeline.
- Domain Purification: Extracted standard JVM domain module for maximum portability and testability.
- Metadata Tuning: Quick rotation and orientation flag fixes.
- Remux Utility: Instant container switching.
- Activity Decomposition: Refactored major UI logic into specialized delegates.
- Modern Build: Full migration to Gradle Kotlin DSL and AGP 9.0.
LosslessCut follows MVVM architecture with a focus on reactive UI and native media processing.
- Languages: Kotlin 1.9+, Gradle Kotlin DSL (
.gradle.kts) - Media Engine:
MediaExtractor,MediaMuxer(Processing), Media3 (Playback UI in:app) - Dependency Inversion: Clean boundaries via
:core:domaininterfaces (JSR-330) - Dependency Injection: Hilt (in Android modules)
- Minimum SDK: 26 (Android 8.0)
- Target SDK: 36 (Android 15)
- Tooling: AGP 9.0 (Built-in Kotlin Support), JVM 17 Toolchain
The project is organized into a modular feature/layer-based structure:
:app: Main Android application module.ui: Fragments (EditorFragment,RemuxFragment,MetadataFragment) and Navigation.VideoEditingActivityis now a thin host.viewmodel: Jetpack ViewModels.VideoEditingViewModeldelegates complex logic to Use Cases.:core:domain: Pure Kotlin/JVM library. Contains Use Cases and domain interfaces. Zero Android/Hilt dependencies.
:engine: Core media processing library. Decoupled from storage and Media3 via domain interfaces.:core:data: Shared data module containing models (MediaClip,TrimSegment), persistence (AppPreferences), and implementations of domain interfaces (IMediaFinalizer).
- Jetpack Navigation: Orchestrates transitions between editing modes.
- Fragments:
EditorFragment: Full NLE editor.RemuxFragment: Simplified remux-only mode.MetadataFragment: Metadata editing and rotation override.
- CustomVideoSeeker: A high-performance custom
Viewfor the NLE timeline.- Logic: Handles multi-touch (zoom), drag gestures for playhead and segments, and edge-auto-panning.
- Accessibility: Implements
ExploreByTouchHelperto expose virtual nodes for playhead and segment handles. Supports standard accessibility actions. - UX Polish: Implements auto-dismissing hint animations (e.g., "pinch to zoom") that disappear upon the first interaction.
- Visuals: Draws segment colors, keyframe ticks, and zoom levels directly on the canvas for performance.
- Waveform Caching: Uses
LruCacheto store pre-rendered 2048px bitmap tiles, replacing per-frame draw lines to dramatically improve scrubbing performance.
- Layout System: Uses orientation-specific layouts (
layoutvslayout-land) to maintain ergonomics.- Playlist Sidebar: Synced with ExoPlayer via robust Clip ID-based targeting. Blue border follows the Clip UUID, making it position-invariant.
- Overlays: Semi-transparent overlays for player controls ensure unified UX across both orientations. Auto-pauses playback whenever a dialog or overlay (Settings, Silence Cut, Export) is opened.
- Smart Cut Tabbed Overlay: Unified controller (
SmartCutOverlayController) managing:SilenceDetectionOverlayController: audio-based detection.VisualDetectionOverlayController: New video-based detection engine in:engine.
- Keyboard Shortcuts: Managed by
ShortcutHandler.SPACE: Play/Pause.I/O: Set In/Out markers.S: Split segment at current playhead position.LEFT/RIGHT: Seek to previous/next keyframe.ALT + LEFT/RIGHT: Nudge playhead viaPlayerManager.performNudge.
- Share Intent Flow:
MainActivityfilters forACTION_SEND/ACTION_VIEW. URIs are passed toVideoEditingActivityfor probing. - Playback Speed: Range:
0.25x, 0.5x, 1.0x, 1.5x, 2.0x, 4.0x.
LosslessEngine: Core muxing orchestration.executeLosslessCut: Trims a single file. Bypasses video-specific orientation hints if no video track is present.executeLosslessMerge: Concatenates multipleMediaClipobjects or segments. Handles PTS shifting.
VideoEditingViewModel: State machine for the editor. Context-Free.- Architecture: No dependency on
android.content.Context. All context-dependent operations (I/O) are delegated to the Repository. - Events: Uses a
VideoEditingEventsealed class viaChannelfor reliable one-time UI actions (e.g.,ShowToast,ExportComplete). - Undo/Redo Stack: In-memory history of
List<MediaClip>snapshots with synchronizedcanRedoflow logic. - Detection Engine:
- Silence: Orchestrates
DetectionUtils.findSilenceusing absoluterawAmplitudesfrom extractedwaveformDatato prevent false amplification of quiet clips. - Visual: Leverages
VisualSegmentDetectorImplin:enginefor high-performance frame analysis using pure Kotlin algorithms (pHash, SAD, Laplacian variance) without native external libraries. Optimized with sequential frame processing viaMediaExtractor.advance()rather than seek-based sampling, and features realtime progress callbacks.
- Silence: Orchestrates
- Architecture: No dependency on
- StorageUtils: Handles Scoped Storage. Centralizes URI creation, dynamically selecting
Movies/LosslessCutorMusic/LosslessCutbased on media type. - TimeUtils: Formatting and precision conversion between MS and microseconds.
- Permission Management: Relies primarily on the Storage Access Framework (SAF). Broad runtime permissions are avoided for enhanced privacy and UX.
MediaExtractorseeks to the nearest keyframe before the requestedstartMs.- Encoded samples are read and passed to
MediaMuxer. - Samples before
startMsare discarded by the muxer logic based on timestamp. - Samples are written until
endMs.
- Validates track compatibility (codecs must match for lossless concatenation).
- Shifts sample PTS values by the cumulative duration of previous segments to ensure continuity.
- Testing:
- JVM:
./gradlew test(Robolectric). - Android:
./gradlew connectedAndroidTest(Espresso).
- JVM:
- Scripts:
dev-scripts/containsIconGenerator.javaand maintenance scripts likeproject-clean.sh. - CI/CD: GitHub Actions (
release.yml) builds and signs production APKs on tag push. Includes a Lint gate and static analysis with Detekt.
Use these IDs for documentation queries:
/androidx/media(Media3/ExoPlayer)/kotlin/kotlinx.coroutines(Concurrency)/androidx/datastore(Preferences)/material-components/material-components-android(UI)
LosslessCut is designed for maximum speed and compatibility by leveraging Android's native MediaMuxer for MP4/MPEG-4 output.
| Category | Primary Support (Optimized) | Legacy/Technical Support |
|---|---|---|
| Output Container | .mp4, .m4a |
β |
| Video Codecs | H.264 (AVC), H.265 (HEVC) | H.263, MPEG-4 Visual (ES) |
| Audio Codecs | AAC (LC, HE) | AMR-NB, AMR-WB |
| Input Container | .mp4, .m4a, .mov, .mkv* |
.3gp, .webm* |
* MKV/WebM inputs can be remuxed to MP4 ONLY if the internal codecs match the supported list above.
Important
Why are these the only supported formats?
Standard Android APIs (MediaMuxer) enforce strict compliance for the MP4 container. Codecs like MP3, FLAC, VP9, or Vorbis require transcoding (re-encoding) to fit into an MP4 file, which would defeat the "lossless" purpose of this app.
Tip
Pro Tip: If your file is a .mov or .mkv with H.264/AAC, LosslessCut will handle it perfectly by remuxing the streams into a new .mp4 file.
Licensed under the MIT License. See LICENSE for details.


