From f65f7b01c3f22b5fa837834c3a8b10bda09f880b Mon Sep 17 00:00:00 2001 From: advplyr Date: Tue, 19 Apr 2022 19:25:16 -0500 Subject: [PATCH] Fixing gradle dependency issues on android, minor warning fixes --- android/app/build.gradle | 23 ++++++++-- .../audiobookshelf/app/CastOptionsProvider.kt | 2 +- .../com/audiobookshelf/app/MainActivity.kt | 3 +- .../app/device/FolderScanner.kt | 5 +- .../audiobookshelf/app/player/CastManager.kt | 10 ++-- .../audiobookshelf/app/player/CastPlayer.kt | 23 ++++------ .../app/player/MediaSessionCallback.kt | 2 +- .../app/player/PlayerListener.kt | 4 +- .../app/player/PlayerNotificationService.kt | 46 +++++++++---------- .../app/plugins/AbsDownloader.kt | 42 ++++------------- .../app/plugins/AbsFileSystem.kt | 26 ++--------- .../audiobookshelf/app/server/ApiHandler.kt | 2 +- android/build.gradle | 4 +- android/variables.gradle | 1 - components/app/AudioPlayer.vue | 18 +++++--- ios/App/Podfile | 14 +++--- 16 files changed, 94 insertions(+), 131 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index fa2e9cf8..1a9581e6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -29,7 +29,7 @@ android { applicationId "com.audiobookshelf.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 61 + versionCode 69 versionName "0.9.41-beta" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { @@ -53,6 +53,20 @@ repositories { mavenCentral() } +configurations.all { + resolutionStrategy { + force("com.google.android.gms:play-services-base:18.0.1") + force("androidx.appcompat:appcompat:$androidxAppCompatVersion") + force("androidx.core:core-ktx:$androidx_core_ktx_version") + force("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version") + force("androidx.media:media:$androidx_media_version") + force("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version") + force("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version") + +// failOnVersionConflict() + } +} + dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" @@ -61,13 +75,12 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" - testImplementation "junit:junit:$junitVersion" - androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" - androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" +// testImplementation "junit:junit:$junitVersion" +// androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" +// androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" implementation project(':capacitor-cordova-android-plugins') implementation "androidx.core:core-ktx:$androidx_core_ktx_version" - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" diff --git a/android/app/src/main/java/com/audiobookshelf/app/CastOptionsProvider.kt b/android/app/src/main/java/com/audiobookshelf/app/CastOptionsProvider.kt index 9f4d1442..c1f92389 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/CastOptionsProvider.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/CastOptionsProvider.kt @@ -12,7 +12,7 @@ class CastOptionsProvider : OptionsProvider { override fun getCastOptions(context: Context): CastOptions { Log.d("CastOptionsProvider", "getCastOptions") var appId = "FD1F76C5" - var defaultId =CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID +// var defaultId =CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID return CastOptions.Builder() .setReceiverApplicationId(appId).setCastMediaOptions( CastMediaOptions.Builder() diff --git a/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt b/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt index 5c11602e..4d8df4c9 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt @@ -5,7 +5,6 @@ import android.app.DownloadManager import android.content.* import android.content.pm.PackageManager import android.os.* -import android.os.StrictMode.VmPolicy import android.util.Log import androidx.core.app.ActivityCompat import com.anggrayudi.storage.SimpleStorage @@ -132,7 +131,7 @@ class MainActivity : BridgeActivity() { fun stopMyService() { if (mBounded) { - mConnection?.let { unbindService(it) }; + mConnection.let { unbindService(it) }; mBounded = false; } val stopIntent = Intent(this, PlayerNotificationService::class.java) diff --git a/android/app/src/main/java/com/audiobookshelf/app/device/FolderScanner.kt b/android/app/src/main/java/com/audiobookshelf/app/device/FolderScanner.kt index bc82264d..9d8210a5 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/device/FolderScanner.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/device/FolderScanner.kt @@ -105,7 +105,6 @@ class FolderScanner(var ctx: Context) { var coverAbsolutePath:String? = null var filesInFolder = itemFolder.search(false, DocumentFileType.FILE, arrayOf("audio/*", "image/*")) - var isPodcast = localFolder.mediaType == "podcast" var existingLocalFilesRemoved = existingLocalFiles.filter { elf -> filesInFolder.find { fif -> DeviceManager.getBase64Id(fif.id) == elf.id } == null // File was not found in media item folder @@ -116,8 +115,8 @@ class FolderScanner(var ctx: Context) { } filesInFolder.forEach { file -> - var mimeType = file?.mimeType ?: "" - var filename = file?.name ?: "" + var mimeType = file.mimeType ?: "" + var filename = file.name ?: "" var isAudio = mimeType.startsWith("audio") Log.d(tag, "Found $mimeType file $filename in folder $itemFolderName") diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt b/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt index 1104288a..1d2215ae 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/CastManager.kt @@ -77,7 +77,7 @@ class CastManager constructor(val mainActivity:Activity) { builder.setTitle(it.friendlyName) } builder.setOnDismissListener { callback.onCancel() } - builder.setPositiveButton("Stop Casting") { dialog, which -> endSession(true, null) } + builder.setPositiveButton("Stop Casting") { _, _ -> endSession(true, null) } builder.show() } } @@ -286,14 +286,14 @@ class CastManager constructor(val mainActivity:Activity) { } } - override fun onSessionStartFailed(castSession: CastSession, errCode: Int) { - if (callback.onSessionStartFailed(errCode)) { + override fun onSessionStartFailed(castSession: CastSession, error: Int) { + if (callback.onSessionStartFailed(error)) { getSessionManager()?.removeSessionManagerListener(this, CastSession::class.java) } } - override fun onSessionEnded(castSession: CastSession, errCode: Int) { - if (callback.onSessionEndedBeforeStart(errCode)) { + override fun onSessionEnded(castSession: CastSession, error: Int) { + if (callback.onSessionEndedBeforeStart(error)) { getSessionManager()?.removeSessionManagerListener(this, CastSession::class.java) } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt index 20eca534..6a816795 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/CastPlayer.kt @@ -149,7 +149,7 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { private fun toMediaQueueItem(mediaItem: MediaItem): MediaQueueItem { // The MediaQueueItem you build is expected to be in the tag. - return (mediaItem.playbackProperties!!.tag as MediaQueueItem?)!! + return (mediaItem.localConfiguration!!.tag as MediaQueueItem?)!! } @JvmName("setRemoteMediaClient1") @@ -373,7 +373,6 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { listeners.queueEvent( EVENT_POSITION_DISCONTINUITY ) { listener: Listener -> - listener.onPositionDiscontinuity(DISCONTINUITY_REASON_AUTO_TRANSITION) listener.onPositionDiscontinuity( oldPosition, newPosition, DISCONTINUITY_REASON_AUTO_TRANSITION) } @@ -385,9 +384,6 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { } } if (updateTracksAndSelectionsAndNotifyIfChanged()) { - listeners.queueEvent( - EVENT_TRACKS_CHANGED - ) { listener: Listener -> listener.onTracksChanged(currentTrackGroups, currentTrackSelections) } listeners.queueEvent( EVENT_TRACKS_CHANGED) { listener: Listener -> listener.onTracksInfoChanged(currentTracksInfo) } } @@ -640,8 +636,6 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { pendingSeekWindowIndex = C.INDEX_UNSET pendingSeekPositionMs = C.TIME_UNSET - - listeners.sendEvent( /* eventFlag= */C.INDEX_UNSET) { obj: Player.Listener -> obj.onSeekProcessed() } // Playback state change will send metadata to client and stop seek loading listeners.sendEvent(EVENT_PLAYBACK_STATE_CHANGED) { obj: Player.Listener -> obj.onPlaybackStateChanged(currentPlaybackState) } } @@ -651,27 +645,27 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { // We assume the default position is 0. There is no support for seeking to the default position // in RemoteMediaClient. - var positionMs = if (positionMs != C.TIME_UNSET) positionMs else 0 + var positionMsFinal = if (positionMs != C.TIME_UNSET) positionMs else 0 if (mediaStatus != null) { if (currentMediaItemIndex != mediaItemIndex) { Log.d(tag, "seekTo: Changing media item index from $currentMediaItemIndex to $mediaItemIndex") - remoteMediaClient?.queueJumpToItem(myCurrentTimeline.getPeriod(mediaItemIndex, period).uid as Int, positionMs, JSONObject())?.setResultCallback(resultCb) + remoteMediaClient?.queueJumpToItem(myCurrentTimeline.getPeriod(mediaItemIndex, period).uid as Int, positionMsFinal, JSONObject())?.setResultCallback(resultCb) } else { - Log.d(tag, "seekTo: Same media index seek to position $positionMs") - var mediaSeekOptions = MediaSeekOptions.Builder().setPosition(positionMs).build() + Log.d(tag, "seekTo: Same media index seek to position $positionMsFinal") + var mediaSeekOptions = MediaSeekOptions.Builder().setPosition(positionMsFinal).build() remoteMediaClient?.seek(mediaSeekOptions)?.setResultCallback(resultCb) } val oldPosition = getCurrentPositionInfo() pendingSeekCount++ pendingSeekWindowIndex = mediaItemIndex - pendingSeekPositionMs = positionMs + pendingSeekPositionMs = positionMsFinal val newPosition = getCurrentPositionInfo() listeners.queueEvent( EVENT_POSITION_DISCONTINUITY ) { listener: Player.Listener -> listener.onPositionDiscontinuity(oldPosition, newPosition, DISCONTINUITY_REASON_SEEK) } - if (oldPosition.windowIndex != newPosition.windowIndex) { + if (oldPosition.mediaItemIndex != newPosition.mediaItemIndex) { val mediaItem = currentTimeline.getWindow(mediaItemIndex, window).mediaItem listeners.queueEvent( EVENT_MEDIA_ITEM_TRANSITION @@ -680,7 +674,8 @@ class CastPlayer(var castContext: CastContext) : BasePlayer() { updateAvailableCommandsAndNotifyIfChanged() } else if (pendingSeekCount == 0) { Log.w(tag, "seekTo Media Status is null") - listeners.queueEvent( /* eventFlag= */C.INDEX_UNSET) { obj: Player.Listener -> obj.onSeekProcessed() } + // Playback state change will send metadata to client and stop seek loading + listeners.sendEvent(EVENT_PLAYBACK_STATE_CHANGED) { obj: Player.Listener -> obj.onPlaybackStateChanged(currentPlaybackState) } } listeners.flushEvents() } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt index f0ea8f44..9676fdfa 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/MediaSessionCallback.kt @@ -157,7 +157,7 @@ class MediaSessionCallback(var playerNotificationService:PlayerNotificationServi } } else -> { - Log.d(tag, "KeyCode:${keyEvent?.getKeyCode()}") + Log.d(tag, "KeyCode:${keyEvent.getKeyCode()}") return false } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt index 74eca609..d568bfa0 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt @@ -92,10 +92,10 @@ class PlayerListener(var playerNotificationService:PlayerNotificationService) : } } - fun calcPauseSeekBackTime() : Long { + private fun calcPauseSeekBackTime() : Long { if (lastPauseTime <= 0) return 0 var time: Long = System.currentTimeMillis() - lastPauseTime - var seekback: Long = 0 + var seekback: Long if (time < 60000) seekback = 0 else if (time < 120000) seekback = 10000 else if (time < 300000) seekback = 15000 diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt index 00552e02..37695f4c 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt @@ -70,7 +70,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { lateinit var mediaManager: MediaManager lateinit var apiHandler: ApiHandler - lateinit var mPlayer: SimpleExoPlayer + lateinit var mPlayer: ExoPlayer lateinit var currentPlayer:Player var castPlayer:CastPlayer? = null @@ -171,11 +171,11 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { 1000 * 20 // 20s playback rebuffer ).build() - var simpleExoPlayerBuilder = SimpleExoPlayer.Builder(this) - simpleExoPlayerBuilder.setLoadControl(customLoadControl) - simpleExoPlayerBuilder.setSeekBackIncrementMs(10000) - simpleExoPlayerBuilder.setSeekForwardIncrementMs(10000) - mPlayer = simpleExoPlayerBuilder.build() + mPlayer = ExoPlayer.Builder(this) + .setLoadControl(customLoadControl) + .setSeekBackIncrementMs(10000) + .setSeekForwardIncrementMs(10000) + .build() mPlayer.setHandleAudioBecomingNoisy(true) mPlayer.addListener(PlayerListener(this)) var audioAttributes:AudioAttributes = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.CONTENT_TYPE_SPEECH).build() @@ -246,14 +246,12 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { mediaSessionConnector = MediaSessionConnector(mediaSession) val queueNavigator: TimelineQueueNavigator = object : TimelineQueueNavigator(mediaSession) { override fun getMediaDescription(player: Player, windowIndex: Int): MediaDescriptionCompat { - var builder = MediaDescriptionCompat.Builder() + return MediaDescriptionCompat.Builder() .setMediaId(currentPlaybackSession!!.id) .setTitle(currentPlaybackSession!!.displayTitle) .setSubtitle(currentPlaybackSession!!.displayAuthor) - .setIconUri(currentPlaybackSession!!.getCoverUri()) - return builder.build() + .setIconUri(currentPlaybackSession!!.getCoverUri()).build() } - // .setMediaUri(currentPlaybackSession!!.getContentUri()) } mediaSessionConnector.setEnabledPlaybackActions( @@ -311,18 +309,16 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { if (mPlayer == currentPlayer) { var mediaSource:MediaSource + var dataSourceFactory = DefaultHttpDataSource.Factory() + dataSourceFactory.setUserAgent(channelId) if (playbackSession.isLocal) { Log.d(tag, "Playing Local Item") - var dataSourceFactory = DefaultDataSourceFactory(ctx, channelId) mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) } else if (!playbackSession.isHLS) { Log.d(tag, "Direct Playing Item") - var dataSourceFactory = DefaultDataSourceFactory(ctx, channelId) mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) } else { Log.d(tag, "Playing HLS Item") - var dataSourceFactory = DefaultHttpDataSource.Factory() - dataSourceFactory.setUserAgent(channelId) dataSourceFactory.setDefaultRequestProperties(hashMapOf("Authorization" to "Bearer ${DeviceManager.token}")) mediaSource = HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mediaItems[0]) } @@ -426,12 +422,12 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } fun getCurrentTime() : Long { - if (currentPlayer.mediaItemCount > 1) { - var windowIndex = currentPlayer.currentWindowIndex - var currentTrackStartOffset = currentPlaybackSession?.getTrackStartOffsetMs(windowIndex) ?: 0L - return currentPlayer.currentPosition + currentTrackStartOffset + return if (currentPlayer.mediaItemCount > 1) { + val windowIndex = currentPlayer.currentMediaItemIndex + val currentTrackStartOffset = currentPlaybackSession?.getTrackStartOffsetMs(windowIndex) ?: 0L + currentPlayer.currentPosition + currentTrackStartOffset } else { - return currentPlayer.currentPosition + currentPlayer.currentPosition } } @@ -439,13 +435,13 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { return getCurrentTime() / 1000.0 } - fun getBufferedTime() : Long { - if (currentPlayer.mediaItemCount > 1) { - var windowIndex = currentPlayer.currentWindowIndex - var currentTrackStartOffset = currentPlaybackSession?.getTrackStartOffsetMs(windowIndex) ?: 0L - return currentPlayer.bufferedPosition + currentTrackStartOffset + private fun getBufferedTime() : Long { + return if (currentPlayer.mediaItemCount > 1) { + val windowIndex = currentPlayer.currentMediaItemIndex + val currentTrackStartOffset = currentPlaybackSession?.getTrackStartOffsetMs(windowIndex) ?: 0L + currentPlayer.bufferedPosition + currentTrackStartOffset } else { - return currentPlayer.bufferedPosition + currentPlayer.bufferedPosition } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt index a1d65d06..e7b23d95 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDownloader.kt @@ -23,8 +23,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.io.File -import java.util.* - @CapacitorPlugin(name = "AbsDownloader") class AbsDownloader : Plugin() { @@ -54,7 +52,7 @@ class AbsDownloader : Plugin() { ) { @JsonIgnore fun getDownloadRequest(): DownloadManager.Request { - var dlRequest = DownloadManager.Request(uri) + val dlRequest = DownloadManager.Request(uri) dlRequest.setTitle(filename) dlRequest.setDescription("Downloading to $localFolderName for book $itemTitle") dlRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) @@ -86,21 +84,12 @@ class AbsDownloader : Plugin() { folderScanner = FolderScanner(mainActivity) apiHandler = ApiHandler(mainActivity) - var recieverEvent: (evt: String, id: Long) -> Unit = { evt: String, id: Long -> - if (evt == "complete") { - } - if (evt == "clicked") { - Log.d(tag, "Clicked $id back in the downloader") - } - } - mainActivity.registerBroadcastReceiver(recieverEvent) - Log.d(tag, "Build SDK ${Build.VERSION.SDK_INT}") } @PluginMethod fun downloadLibraryItem(call: PluginCall) { - var libraryItemId = call.data.getString("libraryItemId").toString() + val libraryItemId = call.data.getString("libraryItemId").toString() var episodeId = call.data.getString("episodeId").toString() if (episodeId == "null") episodeId = "" var localFolderId = call.data.getString("localFolderId").toString() @@ -154,17 +143,6 @@ class AbsDownloader : Plugin() { return if (cleanedRelPath.startsWith("_")) cleanedRelPath.substring(1) else cleanedRelPath } - fun getAbMetadataText(libraryItem:LibraryItem):String { - var bookMedia = libraryItem.media as com.audiobookshelf.app.data.Book - var fileString = ";ABMETADATA1\n" -// fileString += "#libraryItemId=${libraryItem.id}\n" -// fileString += "title=${bookMedia.metadata.title}\n" -// fileString += "author=${bookMedia.metadata.authorName}\n" -// fileString += "narrator=${bookMedia.metadata.narratorName}\n" -// fileString += "series=${bookMedia.metadata.seriesName}\n" - return fileString - } - fun startLibraryItemDownload(libraryItem: LibraryItem, localFolder: LocalFolder, episode:PodcastEpisode?) { if (libraryItem.mediaType == "book") { var bookTitle = libraryItem.media.metadata.title @@ -259,21 +237,21 @@ class AbsDownloader : Plugin() { downloadItemPart.downloadId = downloadId if (libraryItem.media.coverPath != null && libraryItem.media.coverPath?.isNotEmpty() == true) { - var serverPath = "/api/items/${libraryItem.id}/cover?format=jpeg" - var destinationFilename = "cover.jpg" - var destinationFile = File("$itemFolderPath/$destinationFilename") + serverPath = "/api/items/${libraryItem.id}/cover?format=jpeg" + destinationFilename = "cover.jpg" + destinationFile = File("$itemFolderPath/$destinationFilename") if (destinationFile.exists()) { Log.d(tag, "Podcast cover already exists - not downloading cover again") } else { - var destinationUri = Uri.fromFile(destinationFile) - var downloadUri = Uri.parse("${DeviceManager.serverAddress}${serverPath}&token=${DeviceManager.token}") - var downloadItemPart = DownloadItemPart(DeviceManager.getBase64Id(destinationFile.absolutePath), destinationFilename, destinationFile.absolutePath, podcastTitle, serverPath, localFolder.name, localFolder.id, null,null, false, downloadUri, destinationUri, null, 0) + destinationUri = Uri.fromFile(destinationFile) + downloadUri = Uri.parse("${DeviceManager.serverAddress}${serverPath}&token=${DeviceManager.token}") + downloadItemPart = DownloadItemPart(DeviceManager.getBase64Id(destinationFile.absolutePath), destinationFilename, destinationFile.absolutePath, podcastTitle, serverPath, localFolder.name, localFolder.id, null,null, false, downloadUri, destinationUri, null, 0) downloadItem.downloadItemParts.add(downloadItemPart) - var dlRequest = downloadItemPart.getDownloadRequest() - var downloadId = downloadManager.enqueue(dlRequest) + dlRequest = downloadItemPart.getDownloadRequest() + downloadId = downloadManager.enqueue(dlRequest) downloadItemPart.downloadId = downloadId } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsFileSystem.kt b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsFileSystem.kt index a0cfed27..4beb4436 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsFileSystem.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsFileSystem.kt @@ -110,7 +110,7 @@ class AbsFileSystem : Plugin() { @PluginMethod fun checkStoragePermission(call: PluginCall) { - var res = false + var res: Boolean if (Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.P) { res = SimpleStorage.hasStoragePermission(context) Log.d(TAG, "checkStoragePermission: Check Storage Access $res") @@ -222,32 +222,12 @@ class AbsFileSystem : Plugin() { var docfile = DocumentFileCompat.fromUri(mainActivity, Uri.parse(contentUrl)) var success = docfile?.delete() == true if (success) { - localLibraryItem?.media?.removeAudioTrack(trackLocalFileId) - localLibraryItem?.removeLocalFile(trackLocalFileId) + localLibraryItem.media.removeAudioTrack(trackLocalFileId) + localLibraryItem.removeLocalFile(trackLocalFileId) DeviceManager.dbManager.saveLocalLibraryItem(localLibraryItem) call.resolve(JSObject(jacksonMapper.writeValueAsString(localLibraryItem))) } else { call.resolve(JSObject("{\"success\":false}")) } } - - fun checkUriExists(uri: Uri?): Boolean { - if (uri == null) return false - val resolver = context.contentResolver - var cursor: Cursor? = null - return try { - cursor = resolver.query(uri, null, null, null, null) - //cursor null: content Uri was invalid or some other error occurred - //cursor.moveToFirst() false: Uri was ok but no entry found. - (cursor != null && cursor.moveToFirst()) - } catch (t: Throwable) { - false - } finally { - try { - cursor?.close() - } catch (t: Throwable) { - } - false - } - } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt b/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt index 3972d24f..7c69d89a 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/server/ApiHandler.kt @@ -111,7 +111,7 @@ class ApiHandler(var ctx:Context) { getRequest("/api/libraries") { val libraries = mutableListOf() if (it.has("value")) { - var array = it.getJSONArray("value")!! + var array = it.getJSONArray("value") for (i in 0 until array.length()) { val library = mapper.readValue(array.get(i).toString()) libraries.add(library) diff --git a/android/build.gradle b/android/build.gradle index 65a70ae2..0e60006a 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,8 +8,8 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.3.0-alpha08' - classpath 'com.google.gms:google-services:4.3.10' + classpath 'com.google.gms:google-services:4.3.5' + classpath 'com.android.tools.build:gradle:7.2.0-beta04' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/android/variables.gradle b/android/variables.gradle index 8f562165..5d7677fc 100644 --- a/android/variables.gradle +++ b/android/variables.gradle @@ -12,7 +12,6 @@ ext { androidxJunitVersion = '1.1.2' androidxEspressoCoreVersion = '3.3.0' cordovaAndroidVersion = '10.1.1' - androidx_app_compat_version = '1.2.0' androidx_car_version = '1.0.0-alpha7' androidx_core_ktx_version = '1.7.0' androidx_media_version = '1.5.0' diff --git a/components/app/AudioPlayer.vue b/components/app/AudioPlayer.vue index 8c20829a..4e7bfe52 100644 --- a/components/app/AudioPlayer.vue +++ b/components/app/AudioPlayer.vue @@ -131,7 +131,7 @@ export default { touchStartTime: 0, touchEndY: 0, useChapterTrack: false, - isLoading: true + isLoading: false } }, computed: { @@ -548,8 +548,9 @@ export default { this.$store.commit('setPlayerItem', null) this.showFullscreen = false this.isEnded = false + this.isLoading = false this.playbackSession = null - + AbsAudioPlayer.closePlayback() }, // @@ -567,16 +568,18 @@ export default { }, onMetadata(data) { console.log('onMetadata', JSON.stringify(data)) - this.isLoading = false - this.totalDuration = Number(data.duration.toFixed(2)) this.currentTime = Number(data.currentTime.toFixed(2)) - // Also includes player state data.playerState - if (data.playerState == this.$constants.PlayerState.ENDED) { + // Done loading + if (data.playerState !== 'BUFFERING' && data.playerState !== 'IDLE') { + this.isLoading = false + } + + if (data.playerState === 'ENDED') { console.log('[AudioPlayer] Playback ended') } - this.isEnded = data.playerState == this.$constants.PlayerState.ENDED + this.isEnded = data.playerState === 'ENDED' console.log('received metadata update', data) @@ -590,6 +593,7 @@ export default { this.playbackSession = playbackSession this.isEnded = false + this.isLoading = true this.$store.commit('setPlayerItem', this.playbackSession) // Set track width diff --git a/ios/App/Podfile b/ios/App/Podfile index 584acebb..44119188 100644 --- a/ios/App/Podfile +++ b/ios/App/Podfile @@ -9,13 +9,13 @@ install! 'cocoapods', :disable_input_output_paths => true def capacitor_pods pod 'Capacitor', :path => '../../node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios' - pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app' - pod 'CapacitorDialog', :path => '../../node_modules/@capacitor/dialog' - pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics' - pod 'CapacitorNetwork', :path => '../../node_modules/@capacitor/network' - pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar' - pod 'CapacitorStorage', :path => '../../node_modules/@capacitor/storage' - pod 'RobingenzCapacitorAppUpdate', :path => '../../node_modules/@robingenz/capacitor-app-update' + pod 'CapacitorApp', :path => '..\..\node_modules\@capacitor\app' + pod 'CapacitorDialog', :path => '..\..\node_modules\@capacitor\dialog' + pod 'CapacitorHaptics', :path => '..\..\node_modules\@capacitor\haptics' + pod 'CapacitorNetwork', :path => '..\..\node_modules\@capacitor\network' + pod 'CapacitorStatusBar', :path => '..\..\node_modules\@capacitor\status-bar' + pod 'CapacitorStorage', :path => '..\..\node_modules\@capacitor\storage' + pod 'RobingenzCapacitorAppUpdate', :path => '..\..\node_modules\@robingenz\capacitor-app-update' end target 'App' do