mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-29 06:37:16 +02:00
Add: sample audio files for Google android auto test team
This commit is contained in:
@@ -13,8 +13,8 @@ android {
|
|||||||
applicationId "com.audiobookshelf.app"
|
applicationId "com.audiobookshelf.app"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 45
|
versionCode 46
|
||||||
versionName "0.9.26-beta"
|
versionName "0.9.27-beta"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
aaptOptions {
|
aaptOptions {
|
||||||
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ class AudiobookManager {
|
|||||||
abStreamDataObj.put("title", local.name)
|
abStreamDataObj.put("title", local.name)
|
||||||
abStreamDataObj.put("author", "")
|
abStreamDataObj.put("author", "")
|
||||||
abStreamDataObj.put("token", null)
|
abStreamDataObj.put("token", null)
|
||||||
abStreamDataObj.put("cover", "")
|
abStreamDataObj.put("cover", local.coverUri)
|
||||||
abStreamDataObj.put("duration", local.duration)
|
abStreamDataObj.put("duration", local.duration)
|
||||||
abStreamDataObj.put("startTime", 0)
|
abStreamDataObj.put("startTime", 0)
|
||||||
abStreamDataObj.put("playbackSpeed", 1)
|
abStreamDataObj.put("playbackSpeed", 1)
|
||||||
@@ -215,7 +215,7 @@ class AudiobookManager {
|
|||||||
return audiobookStreamData
|
return audiobookStreamData
|
||||||
}
|
}
|
||||||
|
|
||||||
fun levenshtein(lhs : CharSequence, rhs : CharSequence) : Int {
|
private fun levenshtein(lhs : CharSequence, rhs : CharSequence) : Int {
|
||||||
val lhsLength = lhs.length + 1
|
val lhsLength = lhs.length + 1
|
||||||
val rhsLength = rhs.length + 1
|
val rhsLength = rhs.length + 1
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class AudiobookStreamData {
|
|||||||
if (playlistUrl != "") {
|
if (playlistUrl != "") {
|
||||||
playlistUri = Uri.parse(playlistUrl)
|
playlistUri = Uri.parse(playlistUrl)
|
||||||
}
|
}
|
||||||
if (cover != "") {
|
if (cover != "" && cover != null) {
|
||||||
coverUri = Uri.parse(cover)
|
coverUri = Uri.parse(cover)
|
||||||
} else {
|
} else {
|
||||||
coverUri = Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon)
|
coverUri = Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class BrowseTree(
|
|||||||
|
|
||||||
val localsMetadata = MediaMetadataCompat.Builder().apply {
|
val localsMetadata = MediaMetadataCompat.Builder().apply {
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, LOCAL_ROOT)
|
putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, LOCAL_ROOT)
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Local Audio")
|
putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Samples")
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, getUriToDrawable(context, R.drawable.exo_icon_localaudio).toString())
|
putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, getUriToDrawable(context, R.drawable.exo_icon_localaudio).toString())
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
|||||||
@@ -4,49 +4,68 @@ import android.Manifest
|
|||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.AssetFileDescriptor
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import android.media.MediaPlayer
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.support.v4.media.MediaMetadataCompat
|
import android.support.v4.media.MediaMetadataCompat
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
class LocalMediaManager {
|
class LocalMediaManager {
|
||||||
private var ctx: Context
|
private var ctx: Context
|
||||||
val tag = "LocalAudioManager"
|
val tag = "LocalAudioManager"
|
||||||
|
|
||||||
constructor(ctx:Context) {
|
constructor(ctx: Context) {
|
||||||
this.ctx = ctx
|
this.ctx = ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LocalAudio(val uri: Uri,
|
data class LocalAudio(val uri: Uri,
|
||||||
val id:String,
|
val id: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val duration: Int,
|
val duration: Int,
|
||||||
val size: Int
|
val size: Int,
|
||||||
|
val coverUri: Uri?
|
||||||
) {
|
) {
|
||||||
fun toMediaMetadata(): MediaMetadataCompat {
|
fun toMediaMetadata(): MediaMetadataCompat {
|
||||||
return MediaMetadataCompat.Builder().apply {
|
return MediaMetadataCompat.Builder().apply {
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, id)
|
putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, id)
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, name)
|
putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, name)
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_TITLE, name)
|
putString(MediaMetadataCompat.METADATA_KEY_TITLE, name)
|
||||||
// putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, book.authorFL)
|
|
||||||
// putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, getCover().toString())
|
if (coverUri != null) {
|
||||||
putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, "android.resource://com.audiobookshelf.app/" + R.drawable.icon)
|
putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, coverUri.toString())
|
||||||
// putString(MediaMetadataCompat.METADATA_KEY_ART_URI, getCover().toString())
|
} else {
|
||||||
// putString(MediaMetadataCompat.METADATA_KEY_AUTHOR, book.authorFL)
|
putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, "android.resource://com.audiobookshelf.app/" + R.drawable.icon)
|
||||||
|
}
|
||||||
}.build()
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val localAudioFiles = mutableListOf<LocalAudio>()
|
val localAudioFiles = mutableListOf<LocalAudio>()
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
|
||||||
|
.also {
|
||||||
|
if (!it.exists()) {
|
||||||
|
it.outputStream().use { cache ->
|
||||||
|
context.assets.open(fileName).use { inputStream ->
|
||||||
|
inputStream.copyTo(cache)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun loadLocalAudio() {
|
fun loadLocalAudio() {
|
||||||
Log.d(tag, "Media store looking for local audio files")
|
Log.d(tag, "Media store looking for local audio files")
|
||||||
|
localAudioFiles.clear()
|
||||||
|
|
||||||
|
localAudioFiles += LocalAudio(Uri.parse("asset:///public/samples/Anthem/AnthemSample.m4b"), "anthem_sample", "Anthem", 60000, 10000, null)
|
||||||
|
localAudioFiles += LocalAudio(Uri.parse("asset:///public/samples/Legend of Sleepy Hollow/LegendOfSleepyHollowSample.m4b"), "sleepy_hollow", "Legend of Sleepy Hollow", 60000, 10000,null)
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
Log.e(tag, "Permission not granted to read from external storage")
|
Log.e(tag, "Permission not granted to read from external storage")
|
||||||
@@ -86,7 +105,7 @@ class LocalMediaManager {
|
|||||||
id
|
id
|
||||||
)
|
)
|
||||||
Log.d(tag, "Found local audio file $name")
|
Log.d(tag, "Found local audio file $name")
|
||||||
localAudioFiles += LocalAudio(contentUri, id.toString(), name, duration, size)
|
localAudioFiles += LocalAudio(contentUri, id.toString(), name, duration, size, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -573,6 +573,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||||||
// Cache the bitmap for the current audiobook so that successive calls to
|
// Cache the bitmap for the current audiobook so that successive calls to
|
||||||
// `getCurrentLargeIcon` don't cause the bitmap to be recreated.
|
// `getCurrentLargeIcon` don't cause the bitmap to be recreated.
|
||||||
currentIconUri = albumArtUri
|
currentIconUri = albumArtUri
|
||||||
|
Log.d(tag, "ART $currentIconUri")
|
||||||
serviceScope.launch {
|
serviceScope.launch {
|
||||||
currentBitmap = albumArtUri?.let {
|
currentBitmap = albumArtUri?.let {
|
||||||
resolveUriAsBitmap(it)
|
resolveUriAsBitmap(it)
|
||||||
@@ -588,11 +589,23 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
|
|||||||
private suspend fun resolveUriAsBitmap(uri: Uri): Bitmap? {
|
private suspend fun resolveUriAsBitmap(uri: Uri): Bitmap? {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
// Block on downloading artwork.
|
// Block on downloading artwork.
|
||||||
Glide.with(ctx).applyDefaultRequestOptions(glideOptions)
|
try {
|
||||||
.asBitmap()
|
Glide.with(ctx).applyDefaultRequestOptions(glideOptions)
|
||||||
.load(uri)
|
.asBitmap()
|
||||||
.submit(NOTIFICATION_LARGE_ICON_SIZE, NOTIFICATION_LARGE_ICON_SIZE)
|
.load(uri)
|
||||||
.get()
|
.placeholder(R.drawable.icon)
|
||||||
|
.error(R.drawable.icon)
|
||||||
|
.submit(NOTIFICATION_LARGE_ICON_SIZE, NOTIFICATION_LARGE_ICON_SIZE)
|
||||||
|
.get()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
|
||||||
|
Glide.with(ctx).applyDefaultRequestOptions(glideOptions)
|
||||||
|
.asBitmap()
|
||||||
|
.load(Uri.parse("android.resource://com.audiobookshelf.app/" + R.drawable.icon))
|
||||||
|
.submit(NOTIFICATION_LARGE_ICON_SIZE, NOTIFICATION_LARGE_ICON_SIZE)
|
||||||
|
.get()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "audiobookshelf-app",
|
"name": "audiobookshelf-app",
|
||||||
"version": "v0.9.26-beta",
|
"version": "v0.9.27-beta",
|
||||||
"author": "advplyr",
|
"author": "advplyr",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nuxt --hostname localhost --port 1337",
|
"dev": "nuxt --hostname localhost --port 1337",
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
<app-bookshelf-list-row :key="book.id" :audiobook="book" :page-width="pageWidth" class="my-2" />
|
<app-bookshelf-list-row :key="book.id" :audiobook="book" :page-width="pageWidth" class="my-2" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="!books.length" class="w-full py-16 text-center text-xl">
|
<div v-show="!books.length && hasFilters" class="w-full py-16 text-center text-xl">
|
||||||
<div class="py-4">No Books</div>
|
<div class="py-4">No Books</div>
|
||||||
<ui-btn v-if="hasFilters" @click="clearFilter">Clear Filter</ui-btn>
|
<ui-btn @click="clearFilter">Clear Filter</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
Reference in New Issue
Block a user