Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ internal class ExoPlayerPlaybackEngineLooperTest {
InstrumentationRegistry.getInstrumentation().targetContext,
mock(),
true,
false,
MutableSharedFlow(),
BufferConfiguration(),
AssetTimeoutConfig(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class PlaybackEngineModuleRoot(
context: Context,
connectivityManager: ConnectivityManager,
useLibflacAudioRenderer: Boolean,
useTopPlaybackInfo: Boolean,
events: MutableSharedFlow<Event>,
bufferConfiguration: BufferConfiguration,
assetTimeoutConfig: AssetTimeoutConfig,
Expand Down Expand Up @@ -61,6 +62,7 @@ class PlaybackEngineModuleRoot(
cacheProvider,
configuration,
useLibflacAudioRenderer,
useTopPlaybackInfo,
appSpecificCacheDir,
streamingApi,
okHttpClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface ExoPlayerPlaybackEngineComponent {
@BindsInstance cacheProvider: CacheProvider,
@BindsInstance configuration: Configuration,
@BindsInstance @Named("useLibflacAudioRenderer") useLibflacAudioRenderer: Boolean,
@BindsInstance @Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
@BindsInstance appSpecificCacheDir: File,
@BindsInstance streamingApi: StreamingApi,
@BindsInstance @Local okHttpClient: OkHttpClient,
Expand Down
2 changes: 2 additions & 0 deletions player/src/main/kotlin/com/tidal/sdk/player/Player.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Player(
credentialsProvider: CredentialsProvider,
eventSender: EventSender,
useLibflacAudioRenderer: Boolean = true,
useTopPlaybackInfo: Boolean = false,
userClientIdSupplier: (() -> Int)? = null,
bufferConfiguration: BufferConfiguration = BufferConfiguration(),
assetTimeoutConfig: AssetTimeoutConfig = AssetTimeoutConfig(),
Expand All @@ -67,6 +68,7 @@ class Player(
credentialsProvider,
eventSender,
useLibflacAudioRenderer,
useTopPlaybackInfo,
userClientIdSupplier,
version,
bufferConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ internal object PlaybackEngineModule {
context: Context,
connectivityManager: ConnectivityManager,
@Named("useLibflacAudioRenderer") useLibflacAudioRenderer: Boolean,
@Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
events: MutableSharedFlow<Event>,
bufferConfiguration: BufferConfiguration,
assetTimeoutConfig: AssetTimeoutConfig,
Expand All @@ -66,6 +67,7 @@ internal object PlaybackEngineModule {
context,
connectivityManager,
useLibflacAudioRenderer,
useTopPlaybackInfo,
events,
bufferConfiguration,
assetTimeoutConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ internal interface PlayerComponent {
@BindsInstance credentialsProvider: CredentialsProvider,
@BindsInstance eventSender: EventSender,
@BindsInstance @Named("useLibflacAudioRenderer") useLibflacAudioRenderer: Boolean,
@BindsInstance @Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
@BindsInstance userClientIdSupplier: (() -> Int)?,
@BindsInstance version: String,
@BindsInstance bufferConfiguration: BufferConfiguration,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.tidal.sdk.player.di

import com.google.gson.Gson
import com.tidal.sdk.auth.CredentialsProvider
import com.tidal.sdk.player.common.model.ApiError
import com.tidal.sdk.player.offlineplay.OfflinePlayProvider
import com.tidal.sdk.player.streamingapi.StreamingApiModuleRoot
import com.tidal.sdk.player.streamingapi.StreamingApiTimeoutConfig
import dagger.Module
import dagger.Provides
import dagger.Reusable
import javax.inject.Named
import javax.inject.Singleton
import okhttp3.OkHttpClient

Expand All @@ -24,13 +26,17 @@ internal object StreamingApiModule {
gson: Gson,
apiErrorFactory: ApiError.Factory,
offlinePlayProvider: OfflinePlayProvider?,
credentialsProvider: CredentialsProvider,
@Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
) =
StreamingApiModuleRoot(
okHttpClient,
streamingApiTimeoutConfig,
gson,
apiErrorFactory,
offlinePlayProvider?.offlinePlaybackInfoProvider,
credentialsProvider,
useTopPlaybackInfo,
)
.streamingApi
}
7 changes: 5 additions & 2 deletions player/streaming-api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
plugins {
alias(libs.plugins.tidal.kotlin.jvm)
alias(libs.plugins.tidal.android.library)
alias(libs.plugins.google.devtools.ksp)
}

android { namespace = "com.tidal.sdk.player.streamingapi" }

dependencies {
ksp(libs.dagger.compiler)

compileOnly(libs.androidx.annotations)
implementation(libs.androidx.annotations)

implementation(libs.dagger)
implementation(libs.gson)
Expand All @@ -15,6 +17,7 @@ dependencies {
implementation(libs.retrofit.converter.gson)
api(libs.retrofit)
implementation(project(":player:common"))
implementation(project(":tidalapi"))

testImplementation(libs.kotlin.reflect)
testImplementation(libs.kotlinxCoroutinesCore)
Expand Down
7 changes: 7 additions & 0 deletions player/streaming-api/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tidal.sdk.player.streamingapi">

<uses-permission android:name="android.permission.INTERNET" />

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.tidal.sdk.player.streamingapi.playbackinfo.repository.PlaybackInfoRep
internal class StreamingApiDefault(
private val playbackInfoRepository: PlaybackInfoRepository,
private val drmLicenseRepository: DrmLicenseRepository,
private val useTopPlaybackInfo: Boolean,
) : StreamingApi {

override suspend fun getTrackPlaybackInfo(
Expand All @@ -27,14 +28,25 @@ internal class StreamingApiDefault(
streamingSessionId: String,
playlistUuid: String?,
) =
playbackInfoRepository.getTrackPlaybackInfo(
trackId,
audioQuality,
playbackMode,
immersiveAudio,
streamingSessionId,
playlistUuid,
)
if (useTopPlaybackInfo) {
playbackInfoRepository.getTrackPlaybackInfoTop(
trackId,
audioQuality,
playbackMode,
immersiveAudio,
streamingSessionId,
playlistUuid,
)
} else {
playbackInfoRepository.getTrackPlaybackInfo(
trackId,
audioQuality,
playbackMode,
immersiveAudio,
streamingSessionId,
playlistUuid,
)
}

override suspend fun getVideoPlaybackInfo(
videoId: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tidal.sdk.player.streamingapi

import com.google.gson.Gson
import com.tidal.sdk.auth.CredentialsProvider
import com.tidal.sdk.player.common.model.ApiError
import com.tidal.sdk.player.streamingapi.di.DaggerStreamingApiComponent
import com.tidal.sdk.player.streamingapi.playbackinfo.offline.OfflinePlaybackInfoProvider
Expand All @@ -12,6 +13,8 @@ class StreamingApiModuleRoot(
gson: Gson,
apiErrorFactory: ApiError.Factory,
offlinePlaybackInfoProvider: OfflinePlaybackInfoProvider?,
credentialsProvider: CredentialsProvider,
useTopPlaybackInfo: Boolean,
) {

val streamingApi =
Expand All @@ -22,6 +25,8 @@ class StreamingApiModuleRoot(
gson,
apiErrorFactory,
offlinePlaybackInfoProvider,
credentialsProvider,
useTopPlaybackInfo,
)
.streamingApi
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.tidal.sdk.player.streamingapi.playbackinfo.mapper.ApiErrorMapper
import com.tidal.sdk.player.streamingapi.playbackinfo.offline.OfflinePlaybackInfoProvider
import com.tidal.sdk.player.streamingapi.playbackinfo.repository.PlaybackInfoRepository
import com.tidal.sdk.player.streamingapi.playbackinfo.repository.PlaybackInfoRepositoryDefault
import com.tidal.sdk.tidalapi.generated.apis.TrackManifests
import dagger.Lazy
import dagger.Module
import dagger.Provides
Expand All @@ -18,12 +19,14 @@ internal object PlaybackInfoModule {
fun providePlaybackInfoRepository(
offlinePlaybackInfoProvider: OfflinePlaybackInfoProvider?,
playbackInfoService: PlaybackInfoService,
trackManifests: TrackManifests,
apiErrorMapperLazy: Lazy<ApiErrorMapper>,
): PlaybackInfoRepository {
return PlaybackInfoRepositoryDefault(
offlinePlaybackInfoProvider,
playbackInfoService,
apiErrorMapperLazy,
trackManifests,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.tidal.sdk.player.streamingapi.di

import com.google.gson.Gson
import com.tidal.sdk.auth.CredentialsProvider
import com.tidal.sdk.player.common.model.ApiError
import com.tidal.sdk.player.streamingapi.StreamingApi
import com.tidal.sdk.player.streamingapi.StreamingApiTimeoutConfig
import com.tidal.sdk.player.streamingapi.playbackinfo.offline.OfflinePlaybackInfoProvider
import dagger.BindsInstance
import dagger.Component
import javax.inject.Named
import javax.inject.Qualifier
import javax.inject.Singleton
import okhttp3.OkHttpClient
Expand Down Expand Up @@ -34,6 +36,8 @@ interface StreamingApiComponent {
@BindsInstance gson: Gson,
@BindsInstance apiErrorFactory: ApiError.Factory,
@BindsInstance offlinePlaybackInfoProvider: OfflinePlaybackInfoProvider?,
@BindsInstance credentialsProvider: CredentialsProvider,
@BindsInstance @Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
): StreamingApiComponent
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.tidal.sdk.player.streamingapi.di

import com.google.gson.Gson
import com.tidal.sdk.auth.CredentialsProvider
import com.tidal.sdk.player.common.model.ApiError
import com.tidal.sdk.player.streamingapi.StreamingApi
import com.tidal.sdk.player.streamingapi.StreamingApiDefault
import com.tidal.sdk.player.streamingapi.drm.repository.DrmLicenseRepository
import com.tidal.sdk.player.streamingapi.playbackinfo.mapper.ApiErrorMapper
import com.tidal.sdk.player.streamingapi.playbackinfo.model.ManifestMimeType
import com.tidal.sdk.player.streamingapi.playbackinfo.repository.PlaybackInfoRepository
import com.tidal.sdk.tidalapi.generated.TidalApiClient
import com.tidal.sdk.tidalapi.generated.apis.TrackManifests
import dagger.Module
import dagger.Provides
import dagger.Reusable
import javax.inject.Named
import retrofit2.Converter
import retrofit2.converter.gson.GsonConverterFactory

Expand Down Expand Up @@ -40,10 +44,22 @@ internal object StreamingApiModule {
@Reusable
fun provideApiErrorMapper(apiErrorFactory: ApiError.Factory) = ApiErrorMapper(apiErrorFactory)

@Provides
@Reusable
fun provideTidalApiClient(credentialsProvider: CredentialsProvider): TidalApiClient =
TidalApiClient(credentialsProvider)

@Provides
@Reusable
fun provideTrackManifests(tidalApiClient: TidalApiClient): TrackManifests =
tidalApiClient.createTrackManifests()

@Provides
@Reusable
fun streamingApiDefault(
playbackInfoRepository: PlaybackInfoRepository,
drmLicenseRepository: DrmLicenseRepository,
): StreamingApi = StreamingApiDefault(playbackInfoRepository, drmLicenseRepository)
@Named("useTopPlaybackInfo") useTopPlaybackInfo: Boolean,
): StreamingApi =
StreamingApiDefault(playbackInfoRepository, drmLicenseRepository, useTopPlaybackInfo)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ internal interface PlaybackInfoRepository {
playlistUuid: String?,
): PlaybackInfo

/**
* Returns a [PlaybackInfo] which we can use for playback of a track from Top.
*
* @param[trackId] The requested track id as [String].
* @param[audioQuality] The requested audio quality as [AudioQuality].
* @param[playbackMode] The requested playback mode as [PlaybackMode].
* @param[immersiveAudio] The requested option to include immersive audio or not.
* @param[streamingSessionId] The streaming session uuid as [String], created by the client, for
* this streaming session.
* @param[playlistUuid] The playlistUuid this play originates from as [String]. May be null.
*/
suspend fun getTrackPlaybackInfoTop(
trackId: String,
audioQuality: AudioQuality,
playbackMode: PlaybackMode,
immersiveAudio: Boolean,
streamingSessionId: String,
playlistUuid: String?,
): PlaybackInfo

/**
* Returns a [PlaybackInfo] which we can use for playback of a video.
*
Expand Down
Loading
Loading