-
Couldn't load subscription status.
- Fork 304
Migrate MediaPlayer to ExoPlayer #5980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Migrate MediaPlayer to ExoPlayer #5980
Conversation
SDK Size Comparison 📏
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR migrates the audio playback implementation from Android's MediaPlayer to ExoPlayer to support a wider range of audio codecs, particularly addressing issues with playing voice recordings that have mime-type "audio/mp4;codecs=opus".
Key changes:
- Replaces MediaPlayer with ExoPlayer in the NativeMediaPlayerImpl wrapper
- Updates StreamMediaPlayer to StreamAudioPlayer throughout the codebase
- Deprecates legacy MediaPlayer error constants in favor of PlaybackException error codes
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| stream-chat-android-ui-common/src/main/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/AudioPlayerController.kt | Updates logger tag and reorders seekTo call after player setup |
| stream-chat-android-client/src/test/java/io/getstream/chat/android/client/audio/StreamMediaPlayerTest.kt | Renames StreamMediaPlayer to StreamAudioPlayer in tests |
| stream-chat-android-client/src/test/java/io/getstream/chat/android/client/audio/NativeMediaPlayerMock.kt | Updates error listener signature to match ExoPlayer's single errorCode parameter |
| stream-chat-android-client/src/main/java/io/getstream/chat/android/client/audio/StreamAudioPlayer.kt | Removes Android version checks and MediaPlayer-specific code |
| stream-chat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt | Complete reimplementation using ExoPlayer instead of MediaPlayer |
| stream-chat-android-client/src/main/java/io/getstream/chat/android/client/audio/AudioPlayer.kt | Updates parameter documentation from "hash" to "audioHash" |
| stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt | Updates audio player initialization to use ExoPlayer with proper audio attributes |
| stream-chat-android-client/src/test/java/io/getstream/chat/android/client/MockClientBuilder.kt | Updates mock to use StreamAudioPlayer type |
| stream-chat-android-client/build.gradle.kts | Adds ExoPlayer dependency |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
...hat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt
Outdated
Show resolved
Hide resolved
...hat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
...in/kotlin/io/getstream/chat/android/ui/common/feature/messages/list/AudioPlayerController.kt
Show resolved
Hide resolved
...hat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt
Show resolved
Hide resolved
...hat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt
Show resolved
Hide resolved
stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
...hat-android-client/src/main/java/io/getstream/chat/android/client/audio/NativeMediaPlayer.kt
Show resolved
Hide resolved
| } | ||
| val audioPlayer: AudioPlayer = StreamAudioPlayer( | ||
| mediaPlayer = NativeMediaPlayerImpl(appContext) { | ||
| ExoPlayer.Builder(appContext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit worried about the size bump of the SDK. Some companies pay attention to that.
Can we do it in a way to check if the dependency exists at runtime and decide whether to use ExoPlayer based on that?
I'm thinking, maybe we can add ExoPlayer as compileOnly instead of implementation and then check if the class exists like:
private boolean isExoPlayerAvailable() {
try {
Class.forName("androidx.media3.exoplayer.ExoPlayer");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and if it does not? Fallback to MediaPlayer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it adds unnecessary complexity to already complex chat. I think we need to live with the 1.9MBs.
@VelikovPetar why has offline increased for 2MB?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The offline module includes the client as a dependency, so its size has increased transitively.
The ui modules are not affected, because they already include the exoplayer dependency (for video playback).
Another (a bit more complex) solution would be to move the AudioPlayer up to the ui modules, where we already have the exoplayer library. Currently the ChatClient only accesses the AudioPlayer after a logout for cleanup, but with some effort we can ensure proper clean-up in the components where the AudioPlayer is used. The AudioPlayer API is already internal (with the exception of some now unused constants) so there won't be any breaking changes.
But such approach of course would introduce bigger complexity in the wiring of the player, because now can just access it as chatClient.audioPlayer, if we move it upwards, we would need to handle its instantiation better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct way to avoid the 2MB increase is I think to have the contract live in chat and default MediaPlayer implementation.
Then as a separate module include the ExoPlayer backed implementation of said contract. You can then supply an external StreamMediaPlayer implementation of whichever player you choose.
However this goes against our goal of reducing integration complexity and dependencies. I think including exo player is not an optional dependency when MediaPlayer is buggy. We've had several issues with this already. And in the end we are just going to tell people to include the dependency anyway and they will still suffer the 2MB size increase.
|




🎯 Goal
The current implementation of the
AudioPlayeris based onandroid.media.MediaPlayer. While this was working well in most cases, we had occurrences where a voice recoding could not be played (to be more specific:mime-type = "audio/mp4;codecs=opus"). By migrating to ExoPlayer we are able to play such files (+ potentially to support a wider range of codecs)🛠 Implementation details
exoplayerdependency tostream-chat-android-clientMediaPlayerwithExoPlayer(inside theNativeMediaPlayerImplwrapper)🎨 UI Changes
NA
🧪 Testing
Test ALL features related to voice recording: