Audio Mark is an Opinionated Android application that lets you instantly find the audiobook location corresponding to selected EPUB text.
It works with SQLite databases generated using: AudioMarkGenerator
Tested With Storyteller EPUBs
Audio Mark is currently developed using templates primarily against EPUB3 files with SMIL media overlays generated using the Storyteller application from GitLab.
If you are generating your EPUB + audio alignment using Storyteller, Audio Mark should work as expected.
Other EPUB3 + SMIL workflows may work, but Storyteller-generated EPUBs are the reference implementation used during development.
This repository contains only the Android viewer app.
Before using Audio Mark, you must:
- Use AudioMarkGenerator to generate a
.dbfile from your EPUB (with SMIL media overlays). - Import that
.dbfile into the Android app.
Audio Mark does not process EPUB files directly.
Select text inside any app (e.g., an ebook reader), tap Audio Mark, and the app will return:
- 📖 Chapter title (from EPUB TOC)
- 🎧 Audiobook file name
- ⏱ Timestamp (HH:MM:SS)
All matching locations are shown.
- Exact substring search (no fuzzy matching)
- Displays real chapter titles (not numeric indices)
- Card-based, mobile-optimized results layout
- Supports multiple books at once
- Long-press to delete imported books
- Works fully offline
- No tracking, no telemetry
-
Generate a book database using AudioMarkGenerator.
-
Transfer the
.dbfile to your Android device. -
Open Audio Mark.
-
Tap Import Book DB.
-
Select the generated
.dbfile. -
In your ebook reader:
- Select at least 10 words
- Choose Audio Mark
-
Pick the book to search.
-
Instantly see matching audiobook locations.
Download the latest Android APK from the Releases page: https://github.com/ujwalnk/AudioMark/releases
- Android device
- EPUB3 with SMIL media overlays (Can be generated using storyteller)
- Generated SQLite database (
.db) (generated using AudioMarkGenerator)
- Flutter (Material 3 UI)
- Kotlin
MainActivityforandroid.intent.action.PROCESS_TEXT - SQLite via
sqflite - Local file storage (per-book database)
-
Searches use exact substring matching:
SELECT chapter_title, audio_file, timestamp FROM paragraphs WHERE text LIKE '%<selected_text>%'
-
No text normalization.
-
No ranking.
-
All matches are shown.
Each book uses one SQLite file containing:
CREATE TABLE metadata (
id INTEGER PRIMARY KEY,
title TEXT,
author TEXT
);CREATE TABLE paragraphs (
id INTEGER PRIMARY KEY,
chapter_title TEXT NOT NULL,
audio_file TEXT NOT NULL,
timestamp TEXT NOT NULL,
text TEXT NOT NULL
);An index on text supports search queries.
- Flutter 3.3+
- Dart 3.3+
- Android SDK
From project root:
flutter pub get
flutter runTo build a release APK:
flutter build apk --releaseAPK output:
build/app/outputs/flutter-apk/
The app registers for:
android.intent.action.PROCESS_TEXT
When text is selected in another app:
- The selected text is forwarded via MethodChannel to Flutter.
- Minimum requirement: 10 words.
- User selects which imported book to search.
- Results are displayed as scrollable cards.
- Strict requirement: SMIL-based EPUBs only.
- No fuzzy search.
- No normalization.
- No server dependency.
- Optimized for self-hosted audiobook libraries.
- ✅ Android
- iOS can be built manually by interested developers (not officially supported yet)
You are free to use, modify, and distribute this software under the GNUGPLv3 license.