Skip to content

Commit

Permalink
Convenient corebusiness player (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
StaehliJ authored Sep 14, 2023
1 parent d4ae92f commit 93655ad
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
package ch.srgssr.pillarbox.core.business

import android.content.Context
import androidx.media3.common.TrackSelectionParameters
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter
import ch.srgssr.pillarbox.core.business.akamai.AkamaiTokenDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultMediaCompositionDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector.getVector
import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.SeekIncrement
import ch.srgssr.pillarbox.player.extension.setPreferredAudioRoleFlagsToAccessibilityManagerSettings
import ch.srgssr.pillarbox.player.extension.setSeekIncrements
import ch.srgssr.pillarbox.player.source.PillarboxMediaSourceFactory
import ch.srgssr.pillarbox.player.tracker.MediaItemTrackerProvider
import kotlin.time.Duration.Companion.seconds

/**
* DefaultPillarbox convenient class to create [PillarboxPlayer] that suit SRG needs.
*/
object DefaultPillarbox {
private val defaultSeekIncrement = SeekIncrement(backward = 10.seconds, forward = 30.seconds)

/**
* Invoke create an instance of [PillarboxPlayer]
*
* @param context The context.
* @param seekIncrement The seek increment.
* @param mediaItemTrackerRepository The provider of MediaItemTracker.
* @param trackerProvider The [TrackerDataProvider] to customize tracker data.
* @return [PillarboxPlayer] suited for SRG.
*/
operator fun invoke(
context: Context,
seekIncrement: SeekIncrement = defaultSeekIncrement,
mediaItemTrackerRepository: MediaItemTrackerProvider = DefaultMediaItemTrackerRepository(),
trackerProvider: TrackerDataProvider? = null
): PillarboxPlayer {
return PillarboxPlayer(
Builder(context, seekIncrement, trackerProvider),
mediaItemTrackerProvider = mediaItemTrackerRepository
)
}

/**
* Builder convenient class to create a [ExoPlayer.Builder] that suit SRG needs.
*/
object Builder {
/**
* Invoke
*
* @param context The context.
* @param seekIncrement The seek increment.
* @param trackerProvider The [TrackerDataProvider] to customize tracker data.
* @return [ExoPlayer.Builder] suited for SRG.
*/
operator fun invoke(
context: Context,
seekIncrement: SeekIncrement = defaultSeekIncrement,
trackerProvider: TrackerDataProvider? = null
): ExoPlayer.Builder {
return ExoPlayer.Builder(context)
.setUsePlatformDiagnostics(false)
.setSeekIncrements(seekIncrement)
.setRenderersFactory(
DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF)
.setEnableDecoderFallback(true)
)
.setBandwidthMeter(DefaultBandwidthMeter.getSingletonInstance(context))
.setLoadControl(DefaultLoadControl())
.setMediaSourceFactory(
PillarboxMediaSourceFactory(
mediaItemSource = MediaCompositionMediaItemSource(
DefaultMediaCompositionDataSource(vector = context.getVector()),
trackerProvider
),
defaultMediaSourceFactory = DefaultMediaSourceFactory(AkamaiTokenDataSource.Factory())
)
)
.setTrackSelector(
DefaultTrackSelector(
context,
TrackSelectionParameters.Builder(context)
.setPreferredAudioRoleFlagsToAccessibilityManagerSettings(context)
.build()
)
)
.setDeviceVolumeControlEnabled(true) // allow player to control device volume
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
package ch.srgssr.pillarbox.core.business

import android.net.Uri
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata

/**
* Create [MediaItem] for Pillarbox from a urn.
*/
object MediaItemUrn {
/**
* Invoke
*
* @param urn The media urn to play.
* @param title The optional title to display..
* @param subtitle The optional subtitle to display.
* @param artworkUri The artworkUri image uri.
* @return MediaItem.
*/
operator fun invoke(urn: String, title: String? = null, subtitle: String? = null, artworkUri: Uri? = null): MediaItem {
return MediaItem.Builder()
.setMediaId(urn)
.setMediaMetadata(
MediaMetadata.Builder()
.setTitle(title)
.setSubtitle(subtitle)
.setArtworkUri(artworkUri)
.build()
)
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
package ch.srgssr.pillarbox.demo.di

import android.content.Context
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import ch.srgssr.pillarbox.core.business.DefaultPillarbox
import ch.srgssr.pillarbox.core.business.MediaCompositionMediaItemSource
import ch.srgssr.pillarbox.core.business.akamai.AkamaiTokenDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.DefaultMediaCompositionDataSource
import ch.srgssr.pillarbox.core.business.integrationlayer.service.Vector.getVector
import ch.srgssr.pillarbox.core.business.tracker.DefaultMediaItemTrackerRepository
import ch.srgssr.pillarbox.demo.data.MixedMediaItemSource
import ch.srgssr.pillarbox.player.PillarboxPlayer
import ch.srgssr.pillarbox.player.SeekIncrement
import kotlin.time.Duration.Companion.seconds
import ch.srgssr.pillarbox.player.source.PillarboxMediaSourceFactory

/**
* Dependencies to make custom Dependency Injection
Expand All @@ -34,16 +35,13 @@ object PlayerModule {
* Provide default player that allow to play urls and urns content from the SRG
*/
fun provideDefaultPlayer(context: Context): PillarboxPlayer {
val seekIncrement = SeekIncrement(backward = 10.seconds, forward = 30.seconds)
return PillarboxPlayer(
context = context,
mediaItemSource = provideMixedItemSource(context),
/**
* Optional, only needed if you plan to play akamai token protected content
*/
dataSourceFactory = AkamaiTokenDataSource.Factory(),
mediaItemTrackerProvider = DefaultMediaItemTrackerRepository(),
seekIncrement = seekIncrement
val builder = DefaultPillarbox.Builder(context)
builder.setMediaSourceFactory(
PillarboxMediaSourceFactory(
mediaItemSource = provideMixedItemSource(context),
defaultMediaSourceFactory = DefaultMediaSourceFactory(AkamaiTokenDataSource.Factory())
)
)
return PillarboxPlayer(builder, DefaultMediaItemTrackerRepository())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter
import androidx.media3.exoplayer.util.EventLogger
import ch.srgssr.pillarbox.player.data.MediaItemSource
import ch.srgssr.pillarbox.player.extension.setPreferredAudioRoleFlagsToAccessibilityManagerSettings
import ch.srgssr.pillarbox.player.extension.setSeekIncrements
import ch.srgssr.pillarbox.player.source.PillarboxMediaSourceFactory
import ch.srgssr.pillarbox.player.tracker.CurrentMediaItemTracker
import ch.srgssr.pillarbox.player.tracker.MediaItemTrackerProvider
Expand All @@ -38,7 +39,7 @@ import ch.srgssr.pillarbox.player.tracker.MediaItemTrackerRepository
*/
class PillarboxPlayer internal constructor(
private val exoPlayer: ExoPlayer,
mediaItemTrackerProvider: MediaItemTrackerProvider? = null
mediaItemTrackerProvider: MediaItemTrackerProvider?
) :
ExoPlayer by exoPlayer {
private val itemTracker: CurrentMediaItemTracker?
Expand All @@ -61,6 +62,11 @@ class PillarboxPlayer internal constructor(
}
}

constructor(builder: ExoPlayer.Builder, mediaItemTrackerProvider: MediaItemTrackerProvider? = null) : this(
exoPlayer = builder.build(),
mediaItemTrackerProvider = mediaItemTrackerProvider
)

constructor(
context: Context,
mediaItemSource: MediaItemSource,
Expand All @@ -71,8 +77,7 @@ class PillarboxPlayer internal constructor(
) : this(
ExoPlayer.Builder(context)
.setUsePlatformDiagnostics(false)
.setSeekBackIncrementMs(seekIncrement.backward.inWholeMilliseconds)
.setSeekForwardIncrementMs(seekIncrement.forward.inWholeMilliseconds)
.setSeekIncrements(seekIncrement)
.setRenderersFactory(
DefaultRenderersFactory(context)
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023. SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
package ch.srgssr.pillarbox.player.extension

import androidx.media3.exoplayer.ExoPlayer
import ch.srgssr.pillarbox.player.SeekIncrement

/**
* Set seek increments
*
* @param seekIncrement The seek increments to set.
* @return this
*/
fun ExoPlayer.Builder.setSeekIncrements(seekIncrement: SeekIncrement): ExoPlayer.Builder {
setSeekForwardIncrementMs(seekIncrement.forward.inWholeMilliseconds)
setSeekBackIncrementMs(seekIncrement.backward.inWholeMilliseconds)
return this
}

0 comments on commit 93655ad

Please sign in to comment.