mirror of
https://github.com/bbara04/Purefin.git
synced 2026-07-24 03:36:51 +00:00
feature: Added MediaSegmentManager
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package hu.bbara.purefin.core.player.model
|
||||
|
||||
enum class SegmentStatus {
|
||||
START,
|
||||
END
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user