feat: podcast improvements - #20
Open
RadNotRed wants to merge 8 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances the player stack to treat podcasts as a distinct media type, improving long-form playback ergonomics (seek controls/intervals), disabling crossfade behaviors that don’t fit podcasts, and persisting per-episode progress across sessions.
Changes:
- Added podcast media-type detection and propagation across
Track/GenericMediaItem/SongEntity, plus seek-interval normalization and tests. - Updated Android (Media3/ExoPlayer) and JVM (mpv) adapters to avoid crossfading podcasts and to apply podcast-specific audio handling (audio-session reporting / speech boost).
- Implemented podcast playback-position persistence and restore logic in both Android and JVM media handlers.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| media/media3/src/main/java/com/maxrave/media3/exoplayer/CrossfadeExoPlayerAdapter.kt | Reports active audio session changes and prevents crossfade/auto-meta behaviors for podcasts. |
| media/media-jvm/src/main/java/com/simpmusic/media_jvm/mpv/MpvPlayerAdapter.kt | Enables podcast-specific playback behavior (speech boost) and skips crossfade meta loading for podcasts. |
| media/media-jvm/src/main/java/com/simpmusic/media_jvm/mpv/MpvPlayer.kt | Adds a software gain “speech boost” factor into mpv volume application. |
| domain/src/commonTest/kotlin/com/maxrave/domain/extension/PodcastMediaTypeTest.kt | Adds unit coverage for podcast media-type propagation and seek-interval normalization. |
| domain/src/commonMain/kotlin/com/maxrave/domain/mediaservice/player/MediaPlayerListener.kt | Adds an audio-session callback hook for Android audio effects attachment timing. |
| domain/src/commonMain/kotlin/com/maxrave/domain/mediaservice/handler/MediaPlayerHandler.kt | Introduces SeekBy event and a PODCAST playlist type helper. |
| domain/src/commonMain/kotlin/com/maxrave/domain/manager/DataStoreManager.kt | Adds podcast seek interval settings and normalization utilities. |
| domain/src/commonMain/kotlin/com/maxrave/domain/extension/AllExt.kt | Adds isPodcast helpers and preserves podcast type during entity/item conversions. |
| data/src/jvmMain/kotlin/com/maxrave/data/mediaservice/JvmMediaPlayerHandlerImpl.kt | Implements podcast progress save/restore and adds support for SeekBy. |
| data/src/commonMain/kotlin/com/maxrave/data/dataStore/DataStoreManagerImpl.kt | Persists podcast seek interval preferences (forward/rewind). |
| data/src/androidMain/kotlin/com/maxrave/data/mediaservice/MediaServiceHandlerImpl.kt | Implements podcast progress save/restore, SeekBy, and audio-session-driven normalization behavior. |
| common/src/commonMain/kotlin/com/maxrave/common/Config.kt | Adds the PODCAST media type constant and a DataStore key prefix for episode progress. |
Suppressed comments (2)
data/src/androidMain/kotlin/com/maxrave/data/mediaservice/MediaServiceHandlerImpl.kt:2166
clearPodcastPositionwrites to DataStore viaputStringoncoroutineScope(often Main). BecauseputStringdoes not dispatch toDispatchers.IO, this can do disk-backed work on the main thread. Run this write onDispatchers.IO(orbackgroundScope) instead.
coroutineScope.launch {
dataStoreManager.putString("$PODCAST_PROGRESS_KEY_PREFIX${mediaItem.mediaId}", "0")
data/src/jvmMain/kotlin/com/maxrave/data/mediaservice/JvmMediaPlayerHandlerImpl.kt:2249
clearPodcastPositionperforms a DataStore write viaputStringoncoroutineScope. SinceputStringdoes not switch toDispatchers.IO, doing this on the handler scope can introduce avoidable blocking/latency. Run the write onDispatchers.IO(orbackgroundScope) instead.
coroutineScope.launch {
dataStoreManager.putString("$PODCAST_PROGRESS_KEY_PREFIX${mediaItem.mediaId}", "0")
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
RadNotRed
marked this pull request as ready for review
August 6, 2026 22:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I've improved the podcast player and it makes it easier to control for longer episodes. I use this for my daily and this was just one of the things I felt was missing since I'm a big podcast listener
Tested using android debug
Tested podcast playback, seeking, playback speed, episode progress, and switching between podcasts and music
Links to: maxrave-dev/SimpMusic#2303