DEV Community

Cover image for Building Nexo Player: An Offline-First Android Media App with PDF-to-Audiobook Support
Chandrakanta Behera
Chandrakanta Behera

Posted on

Building Nexo Player: An Offline-First Android Media App with PDF-to-Audiobook Support

Most Android media apps solve only one part of the problem.

A video player plays videos. A music player handles songs. A PDF reader displays documents. A text-to-speech app reads text. A vault hides private files.

But real media libraries are not separated that neatly.

My phone may contain downloaded movies, music, lecture notes, ebooks, PDFs, recordings, subtitles, and files I do not want exposed in the normal gallery. Constantly moving between different apps creates friction and breaks playback or reading continuity.

That is why I built Nexo Player: an offline-first Android media app that brings local playback, document reading, audiobook generation, text-to-speech, and private storage into one experience.

What Nexo Player does

Nexo Player currently supports:

  • Local video and audio playback
  • PDF and EPUB reading
  • PDF, EPUB, and text narration
  • Background audiobook generation
  • MP3, M4B, and ZIP export
  • Multiple narrator voices
  • Resume playback and reading progress
  • Equalizer, sleep timer, subtitles, and playback-speed controls
  • Picture-in-Picture
  • Secure Vault protected with PIN or biometrics

The app is built natively for Android using Kotlin, Jetpack Compose, and Android Media3.

The main product idea: local-first media

The core rule behind the app is simple:

A local file should remain local unless the user explicitly chooses otherwise.

This rule influenced the entire product.

Opening a downloaded video should not require an account. Reading a PDF should not require uploading it to a server. Listening to a generated audiobook should remain possible without a permanent internet connection. Private files should not leak into normal galleries, thumbnails, or recent-history screens.

Offline-first is not only about caching data. It means the main workflow must remain useful, understandable, and recoverable without depending on the network.

Building the playback layer

For video and audio playback, I used Android Media3 as the foundation.

The visible player looks simple, but a reliable media experience has to handle much more than pressing play:

  • Audio focus changes
  • App backgrounding and foregrounding
  • Device rotation
  • Playback restoration
  • Subtitle loading and styling
  • Picture-in-Picture
  • Gesture-based brightness and volume controls
  • Different local file permissions
  • Interrupted playback

The challenge was keeping the playback state consistent across all of these situations.

A user should be able to leave the app, return later, and continue from the correct position without thinking about lifecycle events or storage APIs.

Turning documents into playable media

The most important feature in Nexo Player is document narration.

Instead of treating a PDF or EPUB as only something to read, the app can also turn it into a listening experience.

The user flow is intentionally simple:

  1. Open a PDF, EPUB, or pasted text.
  2. Select a narrator voice.
  3. Start listening or generate a complete audiobook.
  4. Continue using the app while generation runs.
  5. Export the result as MP3, M4B, or ZIP.

The difficult work happens behind that interface.

Documents are designed for pages, not speech. Extracted text can contain repeated headers, page numbers, broken spacing, footnotes, symbols, or incorrect reading order. Large documents also cannot be processed as one giant block.

The narration pipeline therefore needs to:

  • Extract readable text
  • Preserve chapter boundaries where possible
  • Clean page-oriented formatting
  • Split long content into manageable segments
  • Process segments in the correct order
  • Track progress
  • Recover from interruptions
  • Join the generated audio correctly
  • Save the result for later playback

One major UX lesson was clear: document processing must never block document opening.

The reader should appear immediately. Expensive work should happen only when needed and should run in the background with visible progress.

Background work is also a UX problem

Moving a task away from the main thread is not enough.

For a long audiobook generation job, users also need to know:

  • What is currently happening
  • How much work is complete
  • Whether they can leave the screen
  • Whether the task will continue
  • What happens if Android stops the process
  • Whether they can retry or cancel

A technically correct background task can still feel broken when the interface gives no confidence.

For Nexo Player, progress, recovery, and clear status messages are treated as part of the feature rather than as optional UI polish.

Designing the narrator experience

Nexo Player includes narrator voices across multiple languages and styles.

The voice-selection screen needs to help users answer three questions quickly:

  • Does this voice support my language?
  • Does it sound appropriate for this content?
  • Is it available for offline use?

That is why voice previews, filters, language labels, and download state are important parts of the audiobook workflow.

The goal is not only to provide text-to-speech. The goal is to make long-form listening feel intentional and comfortable.

Adding a secure vault

A local media app also needs to consider files that should not appear in the public library.

Nexo Player includes a private vault protected by PIN or biometric authentication. Supported files can be viewed or played inside the vault without exposing them through the normal media browser.

A secure vault is more than a hidden folder.

It must also handle:

  • Authentication state
  • App backgrounding
  • Session timeouts
  • Thumbnail privacy
  • Temporary files
  • Recent-history leakage
  • Screen restoration

A small lifecycle mistake can reveal a screen after the user returns to the app. Because of that, privacy has to be treated as an architectural requirement rather than a visual feature.

Keeping one app from feeling like five apps

Combining video, music, documents, narration, exports, and private storage can easily create a confusing interface.

I found it more useful to organize the product around user intent:

  • Play something
  • Read or listen to something
  • Create a narrated version
  • Protect something

This is easier to understand than exposing codecs, parsers, TTS engines, storage APIs, and export formats directly.

Advanced controls are shown only when they are relevant. A user can play a video without configuring the equalizer, read a PDF without starting narration, and generate an audiobook without seeing every internal processing detail.

The larger the feature set becomes, the smaller and clearer the mental model must be.

Lessons from building Nexo Player

1. Offline-first is more than local storage

The product must remain useful when the network disappears, not merely retain previously loaded data.

2. Background processing needs visible progress

Users trust long-running work when the app explains what is happening and recovers correctly.

3. Privacy affects every layer

Storage, previews, logs, temporary files, navigation, and lifecycle handling all become part of the security model.

4. Documents can be treated as media

Once reading position, narration, chapters, and playback are connected, the boundary between a reader and a media player becomes less useful.

5. More features require more restraint

A broad product needs consistent terminology, progressive disclosure, and simple navigation.

What comes next

The next phase is focused on strengthening the core experience:

  • Faster PDF and EPUB opening
  • Smarter background processing
  • Better narration quality and language support
  • More reliable chapter detection and exports
  • Improved large-library performance
  • Better continuity between reading and listening
  • Chromecast support

I would rather clearly label upcoming work than present an unfinished feature as already available.

Try Nexo Player

Website: https://nexoplayer.chandrakantabehera.dev/

Google Play: https://play.google.com/store/apps/details?id=dev.chandrakantabehera.nexoplayer

I would love feedback from developers working with Android Media3, Jetpack Compose, document processing, offline-first applications, or on-device narration.

Which part should I cover next: the Media3 playback architecture, the PDF-to-audiobook pipeline, or the secure vault design?

Top comments (0)