Skip to content

Commit

Permalink
Merge pull request #1 from DevinDuricka/media3-update
Browse files Browse the repository at this point in the history
Media3 (and other dependencies) update
  • Loading branch information
DevinDuricka authored Feb 7, 2023
2 parents 44406ad + 17e8c5d commit 23ac327
Show file tree
Hide file tree
Showing 28 changed files with 946 additions and 1,384 deletions.
34 changes: 17 additions & 17 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {

Expand All @@ -13,20 +13,17 @@ android {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}

compileSdkVersion 29
buildToolsVersion "29.0.3"
compileSdkVersion 33

defaultConfig {
applicationId "one.fable.fable"
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 33
versionCode 6
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

apply plugin: 'kotlin-kapt'


buildTypes {
release {
Expand All @@ -35,6 +32,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

dataBinding {
enabled = true
}
Expand All @@ -45,12 +43,12 @@ dependencies {
//Default Dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.core:core-ktx:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
Expand All @@ -63,18 +61,20 @@ dependencies {
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0-beta01'

//RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha03'
implementation 'androidx.recyclerview:recyclerview:1.3.0-rc01'

//ExoPlayer
implementation 'com.google.android.exoplayer:exoplayer:2.11.4'
implementation 'com.google.android.exoplayer:extension-mediasession:2.10.0'
implementation "androidx.media3:media3-exoplayer:1.0.0-beta02"
implementation "androidx.media3:media3-ui:1.0.0-beta02"
implementation "androidx.media3:media3-exoplayer-dash:1.0.0-beta02"
implementation 'androidx.media3:media3-session:1.0.0-beta02'

//Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1"

//Material Design
implementation 'com.google.android.material:material:1.1.0'
implementation 'com.google.android.material:material:1.7.0'

//Room
implementation "androidx.room:room-runtime:2.2.5"
Expand All @@ -85,9 +85,9 @@ dependencies {
implementation "androidx.preference:preference-ktx:1.1.1"

//Tutorial item highlight library
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.0'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.13.3'

//Palette API for images
implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.palette:palette-ktx:1.0.0'

}
12 changes: 10 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".Fable">
<activity android:name=".MainActivity">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.SEARCH" />
Expand All @@ -24,7 +25,14 @@
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
<service android:name=".exoplayer.AudioPlayerService"/>
<service
android:name=".exoplayer.PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
</application>

</manifest>
12 changes: 6 additions & 6 deletions app/src/main/java/one/fable/fable/Fable.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package one.fable.fable

import android.app.Application
import android.content.Intent
import android.media.AudioManager
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import one.fable.fable.database.FableDatabase
import one.fable.fable.database.daos.AudiobookDao
import one.fable.fable.database.daos.DirectoryDao
import one.fable.fable.exoplayer.AudioPlayerService
import one.fable.fable.exoplayer.ExoPlayerMasterObject
import timber.log.Timber

Expand All @@ -19,8 +16,13 @@ class Fable : Application() {
lateinit var directoryDao: DirectoryDao
fun isdirectoriesDaoInitialized() :Boolean = this::directoryDao.isInitialized

companion object {
lateinit var instance: Fable private set
}

override fun onCreate() {
super.onCreate()
instance = this
Timber.plant(Timber.DebugTree())
initalizeDependecies()

Expand All @@ -34,9 +36,7 @@ class Fable : Application() {
audiobookDao = FableDatabase.getInstance(applicationContext).audiobookDao
directoryDao = FableDatabase.getInstance(applicationContext).directoryDao

ExoPlayerMasterObject.applicationContext = applicationContext
ExoPlayerMasterObject.buildExoPlayer(applicationContext)
ExoPlayerMasterObject.setSharedPreferencesAndListener(PreferenceManager.getDefaultSharedPreferences(applicationContext))
//ExoPlayerMasterObject.setSharedPreferencesAndListener()
ExoPlayerMasterObject.audiobookDao = audiobookDao
}

Expand Down
69 changes: 36 additions & 33 deletions app/src/main/java/one/fable/fable/GlobalSettingsFragment.kt
Original file line number Diff line number Diff line change
@@ -1,70 +1,73 @@
package one.fable.fable

import android.content.SharedPreferences
import android.os.Bundle
import android.text.InputType
import android.text.TextUtils
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.*
import java.util.prefs.PreferenceChangeEvent
import java.util.prefs.PreferenceChangeListener
import timber.log.Timber


class GlobalSettingsFragment : PreferenceFragmentCompat() {
lateinit var sharedPreferences: SharedPreferences
lateinit var seekbarListener: SharedPreferences.OnSharedPreferenceChangeListener
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.global_preferences, rootKey)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

super.onViewCreated(view, savedInstanceState)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)

val rewindPreference : EditTextPreference? = findPreference("rewind_seconds")
val fastForwardPreference : EditTextPreference? = findPreference("fastforward_seconds")
val speedSeekBar : SeekBarPreference? = findPreference("playback_speed_seekbar")
val theme : ListPreference? = findPreference("theme")

val settingChangeEventListener: SharedPreferences.OnSharedPreferenceChangeListener
//val seekbar : SeekBarPreference? = findPreference("playback_speed")


//--Rewind Preference--
rewindPreference?.setOnBindEditTextListener { editText ->
editText.inputType = InputType.TYPE_CLASS_NUMBER
editText.inputType = InputType.TYPE_CLASS_NUMBER //Show only numbers for the rewind preference editor
}
//Add a listener to show a toast when the rewind speed changes
//Don't add to the editTextListener above as it will show the toast when the keyboard appears
rewindPreference?.setOnPreferenceChangeListener { _, _ ->
Toast.makeText(context, "Preference will be reflected after app restart", Toast.LENGTH_LONG).show()
true
}


//--Fast Forward Preference
fastForwardPreference?.setOnBindEditTextListener { editText ->
editText.inputType = InputType.TYPE_CLASS_NUMBER
editText.inputType = InputType.TYPE_CLASS_NUMBER //Show only numbers for the fast forward preference editor
}
//Add a listener to show a toast when the fast forward speed changes
//Don't add to the editTextListener above as it will show the toast when the keyboard appears
fastForwardPreference?.setOnPreferenceChangeListener { _, _ ->
Toast.makeText(context, "Preference will be reflected after app restart", Toast.LENGTH_LONG).show()
true
}

theme?.setOnPreferenceChangeListener(object : Preference.OnPreferenceChangeListener{
override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
when (newValue){
"1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
"-1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
return true
//Theme preference listener
theme?.setOnPreferenceChangeListener { _, newValue ->
when (newValue){
"1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"2" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
"-1" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
})
//AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

speedSeekBar?.title = speedSeekBar?.value?.let { setSpeedSeekBarText(it) }
true
}

seekbarListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
if (key == "playback_speed_seekbar"){
speedSeekBar?.title = setSpeedSeekBarText(sharedPreferences.getInt(key, 10))
//Speed Seekbar Preference
speedSeekBar?.title = speedSeekBar?.value?.let { formatSpeedSeekBarText(it) } //This will initialize the speedseekbar with the applicable text
speedSeekBar?.setOnPreferenceChangeListener { _, newValue ->
try {
speedSeekBar.title = formatSpeedSeekBarText(newValue as Int) //The new value should always be an Int, but just in case, catch it
} catch (e : Exception) {
Timber.e(e)
}
true
}

sharedPreferences.registerOnSharedPreferenceChangeListener(seekbarListener)

}

fun setSpeedSeekBarText(speed: Int) : String{
private fun formatSpeedSeekBarText(speed: Int) : String{
val playbackSpeedFloat = speed/10.0
return "Default playback speed: " + playbackSpeedFloat + "x"
}
Expand Down
39 changes: 31 additions & 8 deletions app/src/main/java/one/fable/fable/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package one.fable.fable

import android.content.ComponentName
import android.content.Intent
import android.media.AudioManager
import android.media.MediaMetadataRetriever
Expand All @@ -8,16 +9,19 @@ import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.widget.MediaController
import android.widget.Toast
import androidx.documentfile.provider.DocumentFile
import androidx.media3.session.SessionToken
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment
import androidx.palette.graphics.Palette
import com.getkeepsafe.taptargetview.TapTarget
import com.getkeepsafe.taptargetview.TapTargetView
import com.google.common.util.concurrent.MoreExecutors
import kotlinx.coroutines.*
import one.fable.fable.database.entities.*
import one.fable.fable.exoplayer.AudioPlayerService
import one.fable.fable.exoplayer.PlaybackService
import one.fable.fable.library.flags
import timber.log.Timber
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -72,14 +76,18 @@ class MainActivity : AppCompatActivity() {
// val navOptions = NavOptions.Builder().setPopUpTo(R.id.libraryFragment, true).build()
// navController.navigate(R.id.libraryFragment, null, navOptions)
// }
startAudioPlayerService()
//startAudioPlayerService()
val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
val mediaControllerFuture = androidx.media3.session.MediaController.Builder(this, sessionToken).buildAsync()
mediaControllerFuture.addListener({}, MoreExecutors.directExecutor())

super.onStart()
}

fun startAudioPlayerService(){
val intent = Intent(applicationContext, AudioPlayerService::class.java)
startService(intent)
}
// fun startAudioPlayerService(){
// val intent = Intent(applicationContext, AudioPlayerService::class.java)
// startService(intent)
// }


fun takePersistablePermissionsToDatabaseEntries(directoryUri : Uri){
Expand Down Expand Up @@ -206,7 +214,7 @@ class MainActivity : AppCompatActivity() {
if(isLocal(authority)){
val mediaMetadataRetriever = MediaMetadataRetriever()
mediaMetadataRetriever.setDataSource(applicationContext, childUri)
duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION).toLong()
duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLong()
(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM))?.let { title = it }
author = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE))?.let { trackTitle = it }
Expand Down Expand Up @@ -396,5 +404,20 @@ fun Long.millisToMinutesSecondsString() : String{ //MM:SS
fun Long.millisToHoursMinutesString() : String{ //HH:MM
return String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toHours(this),
TimeUnit.MILLISECONDS.toMinutes(this) % TimeUnit.HOURS.toSeconds(1))
TimeUnit.MILLISECONDS.toMinutes(this) % TimeUnit.HOURS.toMinutes(1))
}

fun Long.millisToHoursMinutesRemainingString() : String{ //HH:MM
return String.format("%02d hrs %02d min remaining",
TimeUnit.MILLISECONDS.toHours(this),
TimeUnit.MILLISECONDS.toMinutes(this) % TimeUnit.HOURS.toMinutes(1))
}

fun durationRemaining(elapsed : Long, duration: Long) : String {
val remaining = duration - elapsed
return if (remaining <= 60000L) {
"Audiobook Complete"
} else {
remaining.millisToHoursMinutesRemainingString()
}
}
Loading

0 comments on commit 23ac327

Please sign in to comment.