# ExoMedia: a Media3 wrapper that trades control for setup, on a release that is twenty months old

> ExoMedia is an Android audio and video playback library that puts a higher level abstraction over the platform's own media stack, with a view you drop into a layout and a prepared callback that starts playback, and the readme is honest that it abstracts some of the underlying customisability rather than all of it. Two facts decide whether you should still be reaching for it: the library now builds on the rebranded platform media library, and its newest release is from December 2024.

**brianwernick/ExoMedia** — An Android ExoPlayer wrapper to simplify Audio and Video implementations

- Repository: https://github.com/brianwernick/ExoMedia
- Stars: 2,170 · Forks: 378
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-09-30 · Updated: 2026-09-30 · Language: en
- Canonical page: https://hysenlabs.com/projects/brianwernick-exomedia

## The trade in one paragraph, and the word some

The readme contains a section comparing this library to the platform's own player, and it is the most useful paragraph in the repository because it states the trade instead of hiding it. The platform player is described as advanced and highly customizable, with the cost being a more complex setup and configuration process, and the readme is fair about both sides: that customisability is great when it is needed and daunting when you just want to play a file. This library is then positioned as a higher level abstraction that takes some of that customisability and turns it into simple functions and callbacks, keeping the required configuration to a minimum. Read the word some carefully, because it is the entire limitation. This is not a superset and it is not a facade over the full surface; it is a smaller surface that has made choices for you, and every choice is a door you may later need open. So the decision is not which library is better but whether your requirements fit inside the smaller one, and that is a question about your application rather than about the libraries. The stated focus is quick setup and the common audio and video playback needs, with extensibility offered for more custom cases, which is a reasonable two-tier promise. What the readme does not do is show the second tier, which is the subject of the next sections.

## Three classes called VideoView, and a dependency that changed its name

The attribution section is where the dependency story is, and it contains a change that matters more than the list around it. The library is built on Kotlin, on the AndroidX media library, on ConstraintLayout, on the AndroidX app compatibility library and on the Material Design icons, and all five are under the same permissive licence. The AndroidX media library is the point. The readme's own text calls the underlying component ExoPlayer, and the repository's topics are still tagged with ExoPlayer, but the attribution links the AndroidX media library and its release notes rather than the older standalone project. The media player from the AndroidX team was renamed and moved into the support libraries, and this wrapper now sits on the renamed version while keeping the old name in its prose and its tags. That is not a criticism so much as a warning: if you are reading a blog post or a stack overflow answer about this library, the advice may predate the move. The second thing in this section is the class name, and the readme includes a comment about it in the sample code because it is a genuine trap. The view this library provides is called VideoView. Android has a VideoView. The media library has its own player view. So a project that has any of the others on its classpath has three types with that name or a near name, and the sample's own advice is to make sure you import the right one, offered as a bare comment with no explanation of what the wrong import would do. The XML sample reinforces the point: the layout file spells out the fully qualified class name, which is what you have to do precisely because the short name is ambiguous.

## The quick start, and the four things it leaves out

The sample is short enough to read in a minute, and the shape is the whole API. A view goes in the layout file like any other Android view, with its fully qualified class name. In the activity or fragment you find it by its identifier, cast it, attach a prepared listener, and hand it a media item built from a parsed URI. Then the prepared callback starts playback. That is four steps and one callback, and it is genuinely less than configuring a player by hand, which is the claim the readme makes. Four things are missing, and their absence is informative. There is no error listener, so a failed load is silent, and for a view whose whole job is to show something that is a real omission rather than a simplification. There is no lifecycle handling: nothing pauses the playback when the activity stops and nothing releases the player, and a video view holds a codec and a surface, so the usual Android advice is to release it in the stopping callback. There is no state restoration, so a rotation interrupts what the user was watching. And there is no separate prepare step, because attaching the media item appears to start the load, which means the prepared callback is the only hook you get before playback. None of these are necessarily missing from the library, and the readme is a summary rather than a reference. The point for an evaluator is that the readme promises extensibility for custom cases and then demonstrates only the simple case, so the documentation you will need for anything beyond playback-and-start is the library's own reference and the platform documentation underneath it.

## Maven Central, a placeholder version, and a group id from another namespace

Installation is one dependency. The build file needs the central repository declared, and the dependencies block adds the library, with the version left as a placeholder and a comment telling you where to find the real one. Two details in that block are worth more attention than they look. The first is the coordinate. The group is the original author's namespace rather than the person who maintains the repository now, and the package is published under it, so if you are searching for this library you need the old name and not the current repository owner. That is normal for a project that changed hands, and it will bite anyone who assumes the coordinates follow the repository. The second is the placeholder. The version in the sample is not a version, it is a shape, and the comment points at Maven Central or at a tag at the beginning of the readme for the current number. The badge at the top does show the published version, so the instruction works if you read it as a pointer to the badge, but the readme as published here does not contain a version tag anywhere, and there is no changelog file at the top of the repository either. So version discovery is the badge or the package index, and neither is in a file you would diff. The build layout is worth a sentence too, because it is modern and deliberate. The build is written in the Kotlin DSL with a dedicated build logic module holding the shared configuration, there are two modules, the library and a demo application, and the demo carries its own properties file, which is the usual way to pin the SDK levels a sample compiles against so it keeps building after the library moves on.

```gradle
repositories {
  mavenCentral()
}

dependencies {
  // See MavenCentral or the tag at the beginning of the Readme for the latest version
  implementation 'com.devbrackets.android:exomedia:x.x.x'
}
```

## A view in a layout, then four lines of Kotlin

The layout sample is a plain container with the view filling it, and the only unusual thing is the class name, which has to be written in full. That is worth pausing on, because it is the moment a reader discovers this is a third-party view with a colliding name rather than the platform one, and the fully qualified name in the XML is what makes the difference permanent for anyone reading the file later.

```xml
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

    <com.devbrackets.android.exomedia.ui.widget.VideoView
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>
```

The activity sample is the second half of the tutorial and it is where the ambiguity lands. The field is declared as the library's own type, found by identifier and cast, and the cast is the line that fails at compile time rather than at runtime if the import is wrong, which is the good failure mode. The listener is attached, the media item is set from a parsed URI, and the prepared callback starts playback. The comment above the media call says the item was picked arbitrarily, which is a hint that this is a smoke test rather than a pattern to copy: the URI points at a sample file on the original author's own domain, so a project that ships that line is shipping a dependency on somebody else's web server. Substitute your own resource or URL before this reaches a repository. The listener shape is the part worth internalising as a design idea rather than as an API detail. Attaching the item starts the load, the load finishes, and only then does playback begin, so the user never sees a black rectangle while bytes arrive, and the callback is where any transition belongs.

```kotlin
private lateinit var videoView: VideoView

private fun setupVideoView() {
  // Make sure to use the correct VideoView import
  videoView = findViewById(R.id.video_view) as VideoView
  videoView.setOnPreparedListener(this)

  // For now we just picked an arbitrary item to play
  videoView.setMedia(Uri.parse("https://www.devbrackets.com/media/samples/video/big_buck_bunny.mp4"))
}
```

## A release from December 2024 on top of a dependency that versions on its own

Here is the fact that should govern the decision. The release record shows 5.0.0 in July 2023, 5.1.0 in December 2023 and 5.2.0 in December 2024, and the last push to the repository was on 2026-05-25, with the copyright line running to 2026. So the repository is not abandoned and the licence file is being maintained, but the newest artefact anyone can install is about twenty months old while the source has moved since. For an ordinary library that gap would be unremarkable. For a wrapper it is the whole risk, because the thing being wrapped versions on somebody else's schedule. The AndroidX media library ships its own releases, its own migration notes and its own breaking changes, and a wrapper that has not cut a release in twenty months may not compile against the newest one, may compile and behave differently, or may have been updated on the main branch without a version bump. The readme does not address any of this. There is no compatibility table, no statement of which version of the underlying media library each release targets, and no changelog in the repository, so the only way to find out is to build it. That is a five minute experiment and it should be the first thing you do: add the release to a project, resolve the media library version your application already uses, and compile. If it builds and the sample plays, the wrapper is fine for you. If it does not, the fallback is not a bug report, because the project is not promising a cadence, it is using the platform's own player, and the platform documentation is complete. The honest summary is that this is a small, well-scoped convenience wrapper with a clear licence and an idle release line, and the convenience is real enough that it is worth ten minutes to check.

## Apache-2.0 throughout, a missing changelog, and the alternative the readme describes

The licensing picture is as clean as this kind of project gets, and it is worth one paragraph rather than a section. The library is under the Apache licence at version 2.0, the copyright runs from 2015 to 2026, and all five attributed dependencies are under the same licence, so there is no interaction to reason about and no attribution obligation that will surprise you. The attribution list is also the dependency list, which means you know what you are shipping from the readme alone, and that is more than many wrappers bother to do. Two small gaps in the same file. There is a link definition for the Android compatibility test suite at the bottom of the readme that nothing in the visible text refers to, which suggests a sentence was removed at some point, and there is no security policy or changelog in the repository, so a security report has no stated destination and a version history has to be reconstructed from the releases. Both are minor, and both are the kind of thing that tells you how much attention the documentation gets. The alternative is the one the readme itself describes, and taking its argument seriously is the right way to decide. The platform media library ships a player and a player view that do everything this wrapper does, they are documented by the platform team, they are updated on the platform's schedule, and the cost is the configuration this library hides. Choose the wrapper when the setup is the thing annoying you and the feature set is enough. Choose the platform directly when you need the parts the wrapper hides, when you want the documentation and the release notes that ship with the dependency, or when the wrapper's idle release line makes you nervous about the next platform release. Both answers are legitimate; the readme's own framing is the honest version of the comparison, and it does not pretend the wrapper is a strict improvement.

## Conclusion

ExoMedia is worth using for an application whose playback needs are ordinary, because the view-plus-callback shape is genuinely less code than configuring a player directly, and the readme's own comparison is an honest description of what you get. Do not use it for anything where you need the media stack's full surface, since the library's stated purpose is to hide part of that configuration and there is no documented path back to it. The deciding question is version compatibility, and the readme does not answer it. The newest release is 5.2.0 from 2024-12-22, the source was last pushed on 2026-05-25, and the library depends on a platform component that versions independently of it, so check that the release you take builds and runs against the media library version your application already uses before you commit. Two smaller things to verify while you are there. Which of the three classes called VideoView you are importing, since the readme's own comment warns about it, and what your activity does when it stops, because the quick start does not show a release or a pause and the readme does not document one.

## FAQ

### What is the difference between ExoMedia and the platform's own player?

The readme describes the platform player as advanced and highly customizable at the cost of a more complex setup, and this library as a higher level abstraction that turns some of that customisability into simple functions and callbacks with minimal configuration. It abstracts part of the surface rather than all of it, so the trade is setup simplicity against control.

### How do I install it?

Add the central Maven repository and one dependency, whose version is left as a placeholder in the readme with a comment pointing at the package index or a tag for the current number. The group in the coordinate is the original author's namespace rather than the current repository owner, so search by that name.

### Why does the sample warn about the VideoView import?

Because the library's view is called VideoView, and the platform and the media library have types with the same or a similar name, so a project with either on its classpath has an ambiguous name. The layout file spells out the fully qualified class name for the same reason, and the cast in the sample fails at compile time if the wrong type is imported.

### Does the quick start handle pausing and releasing the player?

The sample shows finding the view, attaching a prepared listener, setting a media item from a URI and starting playback when it is ready, with no error listener and no lifecycle handling. The readme does not document pausing or releasing, so the platform guidance for a view that holds a codec applies, and the library's own reference is where to look.

### Is ExoMedia still being released?

The repository is not archived and was last pushed on 2026-05-25, but the newest published release is 5.2.0 from 2024-12-22, and the readme has no compatibility table naming which version of the underlying media library each release targets. Building it against the media library version your application uses is the check worth doing first.

## Sources

- [brianwernick/ExoMedia on GitHub](https://github.com/brianwernick/ExoMedia)
- [Issues](https://github.com/brianwernick/ExoMedia/issues)
- [License: Apache-2.0](https://github.com/brianwernick/ExoMedia/blob/master/LICENSE)
- [README](https://github.com/brianwernick/ExoMedia/blob/master/README.md)
- [Releases](https://github.com/brianwernick/ExoMedia/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/brianwernick-exomedia
