feature: Added MediaSegmentManager

This commit is contained in:
2026-04-23 19:59:12 +02:00
parent f0a4aadcf0
commit 59a471c535
5 changed files with 101 additions and 16 deletions

View File

@@ -2,12 +2,17 @@ package hu.bbara.purefin.core.model
import java.util.UUID
enum class SegmentType {
INTRO,
OUTRO,
MAIN_CONTENT,
PREVIEW,
RECAP;
enum class SegmentType(val value: Int) {
INTRO(0),
OUTRO(1),
MAIN_CONTENT(2),
PREVIEW(3),
RECAP(4);
companion object {
fun fromValue(value: Int): SegmentType? =
entries.firstOrNull { it.value == value }
}
}
data class MediaSegment(

View File

@@ -0,0 +1,69 @@
package hu.bbara.purefin.core.player.manager
import android.os.Looper
import android.util.Log
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.PlayerMessage
import hu.bbara.purefin.core.model.MediaSegment
import hu.bbara.purefin.core.model.SegmentType
import hu.bbara.purefin.core.player.model.SegmentStatus
@OptIn(UnstableApi::class)
class MediaSegmentManager(private val player: ExoPlayer) {
private var listener: MediaSegmentListener? = null
interface MediaSegmentListener {
fun onEvent(segmentType: SegmentType, status: SegmentStatus)
}
@Synchronized
fun registerListener(listener: MediaSegmentListener) {
this.listener?.let {
Log.w("PlayerMessageManager", "Listener was already register")
return
}
this.listener = listener
}
fun addMediaSegments(mediaSegments: List<MediaSegment>) {
val messageTarget = PlayerMessage.Target { messageType, payload ->
SegmentType.fromValue(messageType)?.let { segmentType ->
notifyListener(segmentType, payload as SegmentStatus)
}
}
mediaSegments.forEach { mediaSegment ->
installMediaSegment(messageTarget, mediaSegment)
}
}
private fun notifyListener(segmentType: SegmentType, status: SegmentStatus) {
if (listener == null) {
Log.w("PlayerMessageManager", "Listener was not register therefore it cannot notify")
}
listener?.onEvent(segmentType, status)
}
private fun installMediaSegment(messageTarget: PlayerMessage.Target, mediaSegment: MediaSegment) {
player.createMessage(messageTarget)
.setType(mediaSegment.type.value)
.setPosition(mediaSegment.startMs)
.setPayload(SegmentStatus.START)
.setLooper(Looper.getMainLooper())
.setDeleteAfterDelivery(false)
.send()
player.createMessage(messageTarget)
.setType(mediaSegment.type.value)
.setPayload(SegmentStatus.END)
.setPosition(mediaSegment.endMs)
.setLooper(Looper.getMainLooper())
.setDeleteAfterDelivery(false)
.send()
}
}

View File

@@ -7,8 +7,10 @@ import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.TrackSelectionOverride
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import dagger.hilt.android.scopes.ViewModelScoped
import hu.bbara.purefin.core.data.PlaybackReportContext
import hu.bbara.purefin.core.model.MediaSegment
import hu.bbara.purefin.core.player.model.MediaContext
import hu.bbara.purefin.core.player.model.MetadataState
import hu.bbara.purefin.core.player.model.PlaybackProgressSnapshot
@@ -51,6 +53,8 @@ class PlayerManager @Inject constructor(
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
private val mediaSegmentManager = MediaSegmentManager(player as ExoPlayer)
private var currentMediaContext: MediaContext? = null
private var pendingSeekPositionMs: Long? = null
@@ -84,10 +88,14 @@ class PlayerManager @Inject constructor(
}
}
override fun onEvents(player: Player, events: Player.Events) {
if (events.contains(Player.EVENT_MEDIA_ITEM_TRANSITION)) {
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
clearPendingSeek()
currentMediaContext?.let {
installMediaSegments(it.mediaSegments)
}
}
override fun onEvents(player: Player, events: Player.Events) {
updateFromPlayer(player)
if (events.contains(Player.EVENT_TRACKS_CHANGED)) {
scope.launch {
@@ -215,8 +223,10 @@ class PlayerManager @Inject constructor(
}
}
fun setPlaybackSpeed(speed: Float) {
player.setPlaybackSpeed(speed)
private fun installMediaSegments(mediaSegments: List<MediaSegment>) {
mediaSegmentManager.addMediaSegments(
mediaSegments = mediaSegments
)
}
fun retry() {

View File

@@ -0,0 +1,6 @@
package hu.bbara.purefin.core.player.model
enum class SegmentStatus {
START,
END
}

View File

@@ -272,11 +272,6 @@ class PlayerViewModel @Inject constructor(
playerManager.selectTrack(option)
}
fun setPlaybackSpeed(speed: Float) {
playerManager.setPlaybackSpeed(speed)
_uiState.update { it.copy(playbackSpeed = speed) }
}
fun retry() {
playerManager.retry()
}