Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various media fixes + reorganisation #407

Merged
merged 4 commits into from
Oct 4, 2023
Merged
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
66 changes: 66 additions & 0 deletions readium/adapters/exoplayer/audio/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2022 Readium Foundation. All rights reserved.
* Use of this source code is governed by the BSD-style license
* available in the top-level LICENSE file of the project.
*/

plugins {
id("com.android.library")
kotlin("android")
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
}

android {
resourcePrefix = "readium_"

compileSdk = 34

defaultConfig {
minSdk = 21
targetSdk = 34
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=org.readium.r2.shared.InternalReadiumApi"
)
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"))
}
}
buildFeatures {
viewBinding = true
}
namespace = "org.readium.adapter.exoplayer.audio"
}

kotlin {
explicitApi()
}

rootProject.ext["publish.artifactId"] = "readium-navigator-exoplayer-audio"
apply(from = "$rootDir/scripts/publish-module.gradle")

dependencies {
api(project(":readium:readium-shared"))
api(project(":readium:navigators:media:readium-navigator-media-audio"))

implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.timber)
implementation(libs.bundles.coroutines)
implementation(libs.kotlinx.serialization.json)

// Tests
testImplementation(libs.junit)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import androidx.media3.common.ForwardingPlayer
import androidx.media3.exoplayer.ExoPlaybackException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.navigator.media.audio.AudioNavigator
import org.readium.navigator.media.audio.AudioNavigatorFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import android.net.Uri
import androidx.media3.common.C.LENGTH_UNSET
Expand All @@ -21,13 +21,13 @@ import org.readium.r2.shared.util.resource.Resource
import org.readium.r2.shared.util.resource.buffered
import org.readium.r2.shared.util.toUrl

public sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException(
internal sealed class ExoPlayerDataSourceException(message: String, cause: Throwable?) : IOException(
message,
cause
) {
public class NotOpened(message: String) : ExoPlayerDataSourceException(message, null)
public class NotFound(message: String) : ExoPlayerDataSourceException(message, null)
public class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException(
class NotOpened(message: String) : ExoPlayerDataSourceException(message, null)
class NotFound(message: String) : ExoPlayerDataSourceException(message, null)
class ReadFailed(uri: Uri, offset: Int, readLength: Int, cause: Throwable) : ExoPlayerDataSourceException(
"Failed to read $readLength bytes of URI $uri at offset $offset.",
cause
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.r2.shared.ExperimentalReadiumApi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import android.app.Application
import androidx.media3.common.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import android.app.Application
import androidx.media3.datasource.DataSource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.r2.navigator.preferences.Configurable
import org.readium.r2.shared.ExperimentalReadiumApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.r2.navigator.extensions.format
import org.readium.r2.navigator.preferences.DoubleIncrement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import kotlinx.serialization.json.Json
import org.readium.r2.navigator.preferences.PreferencesSerializer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.r2.navigator.preferences.Configurable
import org.readium.r2.shared.ExperimentalReadiumApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import org.readium.r2.shared.ExperimentalReadiumApi

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* available in the top-level LICENSE file of the project.
*/

package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import kotlin.time.Duration
import kotlin.time.ExperimentalTime
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.readium.adapter.exoplayer
package org.readium.adapter.exoplayer.audio

import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
Expand Down
18 changes: 2 additions & 16 deletions readium/adapters/exoplayer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ plugins {
id("com.android.library")
kotlin("android")
kotlin("plugin.parcelize")
kotlin("plugin.serialization")
}

android {
Expand Down Expand Up @@ -38,29 +37,16 @@ android {
proguardFiles(getDefaultProguardFile("proguard-android.txt"))
}
}
buildFeatures {
viewBinding = true
}
namespace = "org.readium.adapter.exoplayer"
}

kotlin {
explicitApi()
}

rootProject.ext["publish.artifactId"] = "readium-navigator-exoplayer"
rootProject.ext["publish.artifactId"] = "readium-adapter-exoplayer"
apply(from = "$rootDir/scripts/publish-module.gradle")

dependencies {
api(project(":readium:readium-shared"))
api(project(":readium:navigators:media:readium-navigator-media-audio"))

implementation(libs.androidx.media3.common)
implementation(libs.androidx.media3.exoplayer)
implementation(libs.timber)
implementation(libs.bundles.coroutines)
implementation(libs.kotlinx.serialization.json)

// Tests
testImplementation(libs.junit)
api(project(":readium:adapters:exoplayer:readium-adapter-exoplayer-audio"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@ import android.media.AudioManager
import android.media.AudioTrack
import android.os.Build
import kotlin.coroutines.coroutineContext
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.readium.r2.navigator.preferences.Configurable
import org.readium.r2.shared.ExperimentalReadiumApi
import org.readium.r2.shared.extensions.tryOrNull
import org.readium.r2.shared.publication.Locator
import timber.log.Timber

/**
* Plays the content from a [TtsUtteranceIterator] with a [TtsEngine].
Expand Down Expand Up @@ -190,7 +197,6 @@ internal class TtsPlayer<S : TtsEngine.Settings, P : TtsEngine.Preferences<P>,
coroutineScope.launch {
// WORKAROUND to get the media buttons correctly working.
fakePlayingAudio()

playAsync()
}
}
Expand All @@ -205,29 +211,33 @@ internal class TtsPlayer<S : TtsEngine.Settings, P : TtsEngine.Preferences<P>,
val audioFormat =
AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(44100)
.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
.build()

val bufferSize = 8092

val audioTrack =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AudioTrack.Builder()
.setAudioAttributes(audioAttributes)
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(bufferSize)
.build()
tryOrNull {
AudioTrack.Builder()
.setAudioAttributes(audioAttributes)
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(bufferSize)
.build()
}
} else {
AudioTrack(
audioAttributes,
audioFormat,
bufferSize,
AudioTrack.MODE_STATIC,
AudioTrack.MODE_STREAM,
AudioManager.AUDIO_SESSION_ID_GENERATE
)
).takeIf { it.state == AudioTrack.STATE_INITIALIZED }
}
audioTrack.play()

audioTrack
?.play()
?: run { Timber.e("Couldn't fake playing audio.") }
}

private suspend fun playAsync() = mutex.withLock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.readium.navigator.media.tts.TtsEngine
import org.readium.r2.shared.ExperimentalReadiumApi
import org.readium.r2.shared.extensions.tryOrNull
import org.readium.r2.shared.util.Language

/*
Expand Down Expand Up @@ -57,7 +58,7 @@ public class AndroidTtsEngine private constructor(
val textToSpeech = initializeTextToSpeech(context)
?: return null

val voices = textToSpeech.voices
val voices = tryOrNull { textToSpeech.voices } // throws on Nexus 4
?.map { it.toTtsEngineVoice() }
?.toSet()
.orEmpty()
Expand Down
22 changes: 11 additions & 11 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ dependencyResolutionManagement {

rootProject.name = "Readium"

include(":readium:adapters:pdfium:pdfium-document")
project(":readium:adapters:pdfium:pdfium-document")
include(":readium:adapters:pdfium:document")
project(":readium:adapters:pdfium:document")
.name = "readium-adapter-pdfium-document"

include(":readium:adapters:pdfium:pdfium-navigator")
project(":readium:adapters:pdfium:pdfium-navigator")
include(":readium:adapters:pdfium:navigator")
project(":readium:adapters:pdfium:navigator")
.name = "readium-adapter-pdfium-navigator"

include(":readium:adapters:pspdfkit:pspdfkit-document")
project(":readium:adapters:pspdfkit:pspdfkit-document")
include(":readium:adapters:pspdfkit:document")
project(":readium:adapters:pspdfkit:document")
.name = "readium-adapter-pspdfkit-document"

include(":readium:adapters:pspdfkit:pspdfkit-navigator")
project(":readium:adapters:pspdfkit:pspdfkit-navigator")
include(":readium:adapters:pspdfkit:navigator")
project(":readium:adapters:pspdfkit:navigator")
.name = "readium-adapter-pspdfkit-navigator"

include(":readium:lcp")
Expand All @@ -84,9 +84,9 @@ include(":readium:navigator-media2")
project(":readium:navigator-media2")
.name = "readium-navigator-media2"

include(":readium:adapters:exoplayer")
project(":readium:adapters:exoplayer")
.name = "readium-adapter-exoplayer"
include(":readium:adapters:exoplayer:audio")
project(":readium:adapters:exoplayer:audio")
.name = "readium-adapter-exoplayer-audio"

include(":readium:opds")
project(":readium:opds")
Expand Down
2 changes: 1 addition & 1 deletion test-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ dependencies {
implementation(project(":readium:navigators:media:readium-navigator-media-audio"))
implementation(project(":readium:navigators:media:readium-navigator-media-tts"))
// Only required if you want to support audiobooks using ExoPlayer.
implementation(project(":readium:adapters:readium-adapter-exoplayer"))
implementation(project(":readium:adapters:exoplayer"))
implementation(project(":readium:readium-navigator-media2"))
implementation(project(":readium:readium-opds"))
implementation(project(":readium:readium-lcp"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import kotlin.time.DurationUnit
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.readium.adapter.exoplayer.ExoPlayerPreferences
import org.readium.adapter.exoplayer.ExoPlayerSettings
import org.readium.adapter.exoplayer.audio.ExoPlayerPreferences
import org.readium.adapter.exoplayer.audio.ExoPlayerSettings
import org.readium.navigator.media.common.MediaNavigator
import org.readium.navigator.media.common.TimeBasedMediaNavigator
import org.readium.r2.navigator.preferences.Configurable
Expand Down
Loading