Fix: Sleep timer for multi-track playback sessions - use duration of all tracks stored in playback session instead of duration from exoplayer #140

This commit is contained in:
advplyr 2022-04-25 17:22:12 -05:00
parent d18972e2f3
commit 2dd822e04d
5 changed files with 29 additions and 28 deletions

View file

@ -51,8 +51,8 @@ data class LocalLibraryItem(
@JsonIgnore @JsonIgnore
fun updateFromScan(audioTracks:MutableList<AudioTrack>, _localFiles:MutableList<LocalFile>) { fun updateFromScan(audioTracks:MutableList<AudioTrack>, _localFiles:MutableList<LocalFile>) {
media.setAudioTracks(audioTracks)
localFiles = _localFiles localFiles = _localFiles
media.setAudioTracks(audioTracks)
if (coverContentUrl != null) { if (coverContentUrl != null) {
if (localFiles.find { it.contentUrl == coverContentUrl } == null) { if (localFiles.find { it.contentUrl == coverContentUrl } == null) {

View file

@ -57,6 +57,8 @@ class PlaybackSession(
@get:JsonIgnore @get:JsonIgnore
val currentTimeMs get() = (currentTime * 1000L).toLong() val currentTimeMs get() = (currentTime * 1000L).toLong()
@get:JsonIgnore @get:JsonIgnore
val totalDurationMs get() = (getTotalDuration() * 1000L).toLong()
@get:JsonIgnore
val localLibraryItemId get() = localLibraryItem?.id ?: "" val localLibraryItemId get() = localLibraryItem?.id ?: ""
@get:JsonIgnore @get:JsonIgnore
val localMediaProgressId get() = if (episodeId.isNullOrEmpty()) localLibraryItemId else "$localLibraryItemId-$localEpisodeId" val localMediaProgressId get() = if (episodeId.isNullOrEmpty()) localLibraryItemId else "$localLibraryItemId-$localEpisodeId"

View file

@ -36,7 +36,7 @@ class FolderScanner(var ctx: Context) {
} }
} }
var df: DocumentFile? = DocumentFileCompat.fromUri(ctx, Uri.parse(localFolder.contentUrl)) val df: DocumentFile? = DocumentFileCompat.fromUri(ctx, Uri.parse(localFolder.contentUrl))
if (df == null) { if (df == null) {
Log.e(tag, "Folder Doc File Invalid $localFolder.contentUrl") Log.e(tag, "Folder Doc File Invalid $localFolder.contentUrl")
@ -49,7 +49,7 @@ class FolderScanner(var ctx: Context) {
var mediaItemsUpToDate = 0 var mediaItemsUpToDate = 0
// Search for files in media item folder // Search for files in media item folder
var foldersFound = df.search(false, DocumentFileType.FOLDER) val foldersFound = df.search(false, DocumentFileType.FOLDER)
// Match folders found with local library items already saved in db // Match folders found with local library items already saved in db
var existingLocalLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(localFolder.id) var existingLocalLibraryItems = DeviceManager.dbManager.getLocalLibraryItemsInFolder(localFolder.id)
@ -57,7 +57,7 @@ class FolderScanner(var ctx: Context) {
// Remove existing items no longer there // Remove existing items no longer there
existingLocalLibraryItems = existingLocalLibraryItems.filter { lli -> existingLocalLibraryItems = existingLocalLibraryItems.filter { lli ->
Log.d(tag, "scanForMediaItems Checking Existing LLI ${lli.id}") Log.d(tag, "scanForMediaItems Checking Existing LLI ${lli.id}")
var fileFound = foldersFound.find { f -> lli.id == getLocalLibraryItemId(f.id) } val fileFound = foldersFound.find { f -> lli.id == getLocalLibraryItemId(f.id) }
if (fileFound == null) { if (fileFound == null) {
Log.d(tag, "Existing local library item is no longer in file system ${lli.media.metadata.title}") Log.d(tag, "Existing local library item is no longer in file system ${lli.media.metadata.title}")
DeviceManager.dbManager.removeLocalLibraryItem(lli.id) DeviceManager.dbManager.removeLocalLibraryItem(lli.id)
@ -68,9 +68,9 @@ class FolderScanner(var ctx: Context) {
foldersFound.forEach { itemFolder -> foldersFound.forEach { itemFolder ->
Log.d(tag, "Iterating over Folder Found ${itemFolder.name} | ${itemFolder.getSimplePath(ctx)} | URI: ${itemFolder.uri}") Log.d(tag, "Iterating over Folder Found ${itemFolder.name} | ${itemFolder.getSimplePath(ctx)} | URI: ${itemFolder.uri}")
var existingItem = existingLocalLibraryItems.find { emi -> emi.id == getLocalLibraryItemId(itemFolder.id) } val existingItem = existingLocalLibraryItems.find { emi -> emi.id == getLocalLibraryItemId(itemFolder.id) }
var result = scanLibraryItemFolder(itemFolder, localFolder, existingItem, forceAudioProbe) val result = scanLibraryItemFolder(itemFolder, localFolder, existingItem, forceAudioProbe)
if (result == ItemScanResult.REMOVED) mediaItemsRemoved++ if (result == ItemScanResult.REMOVED) mediaItemsRemoved++
else if (result == ItemScanResult.UPDATED) mediaItemsUpdated++ else if (result == ItemScanResult.UPDATED) mediaItemsUpdated++
@ -90,25 +90,23 @@ class FolderScanner(var ctx: Context) {
} }
fun scanLibraryItemFolder(itemFolder:DocumentFile, localFolder:LocalFolder, existingItem:LocalLibraryItem?, forceAudioProbe:Boolean):ItemScanResult { fun scanLibraryItemFolder(itemFolder:DocumentFile, localFolder:LocalFolder, existingItem:LocalLibraryItem?, forceAudioProbe:Boolean):ItemScanResult {
var itemFolderName = itemFolder.name ?: "" val itemFolderName = itemFolder.name ?: ""
var itemId = getLocalLibraryItemId(itemFolder.id) val itemId = getLocalLibraryItemId(itemFolder.id)
var existingLocalFiles = existingItem?.localFiles ?: mutableListOf() val existingLocalFiles = existingItem?.localFiles ?: mutableListOf()
var existingAudioTracks = existingItem?.media?.getAudioTracks() ?: mutableListOf() val existingAudioTracks = existingItem?.media?.getAudioTracks() ?: mutableListOf()
var isNewOrUpdated = existingItem == null var isNewOrUpdated = existingItem == null
var audioTracks = mutableListOf<AudioTrack>() val audioTracks = mutableListOf<AudioTrack>()
var localFiles = mutableListOf<LocalFile>() val localFiles = mutableListOf<LocalFile>()
var index = 1 var index = 1
var startOffset = 0.0 var startOffset = 0.0
var coverContentUrl:String? = null var coverContentUrl:String? = null
var coverAbsolutePath:String? = null var coverAbsolutePath:String? = null
// itemFolder.search(false, DocumentFileType.FILE, arrayOf("audio")) val filesInFolder = itemFolder.search(false, DocumentFileType.FILE, arrayOf("audio/*", "image/*", "video/mp4"))
var filesInFolder = itemFolder.search(false, DocumentFileType.FILE, arrayOf("audio/*", "image/*", "video/mp4")) val existingLocalFilesRemoved = existingLocalFiles.filter { elf ->
var existingLocalFilesRemoved = existingLocalFiles.filter { elf ->
filesInFolder.find { fif -> DeviceManager.getBase64Id(fif.id) == elf.id } == null // File was not found in media item folder filesInFolder.find { fif -> DeviceManager.getBase64Id(fif.id) == elf.id } == null // File was not found in media item folder
} }
if (existingLocalFilesRemoved.isNotEmpty()) { if (existingLocalFilesRemoved.isNotEmpty()) {
@ -117,14 +115,14 @@ class FolderScanner(var ctx: Context) {
} }
filesInFolder.forEach { file -> filesInFolder.forEach { file ->
var mimeType = file.mimeType ?: "" val mimeType = file.mimeType ?: ""
var filename = file.name ?: "" val filename = file.name ?: ""
var isAudio = mimeType.startsWith("audio") || mimeType == "video/mp4" val isAudio = mimeType.startsWith("audio") || mimeType == "video/mp4"
Log.d(tag, "Found $mimeType file $filename in folder $itemFolderName") Log.d(tag, "Found $mimeType file $filename in folder $itemFolderName")
var localFileId = DeviceManager.getBase64Id(file.id) val localFileId = DeviceManager.getBase64Id(file.id)
var localFile = LocalFile(localFileId,filename,file.uri.toString(),file.getBasePath(ctx), file.getAbsolutePath(ctx),file.getSimplePath(ctx),mimeType,file.length()) val localFile = LocalFile(localFileId,filename,file.uri.toString(),file.getBasePath(ctx), file.getAbsolutePath(ctx),file.getSimplePath(ctx),mimeType,file.length())
localFiles.add(localFile) localFiles.add(localFile)
Log.d(tag, "File attributes Id:${localFileId}|ContentUrl:${localFile.contentUrl}|isDownloadsDocument:${file.isDownloadsDocument}") Log.d(tag, "File attributes Id:${localFileId}|ContentUrl:${localFile.contentUrl}|isDownloadsDocument:${file.isDownloadsDocument}")
@ -132,7 +130,7 @@ class FolderScanner(var ctx: Context) {
if (isAudio) { if (isAudio) {
var audioTrackToAdd:AudioTrack? = null var audioTrackToAdd:AudioTrack? = null
var existingAudioTrack = existingAudioTracks.find { eat -> eat.localFileId == localFileId } val existingAudioTrack = existingAudioTracks.find { eat -> eat.localFileId == localFileId }
if (existingAudioTrack != null) { // Update existing audio track if (existingAudioTrack != null) { // Update existing audio track
if (existingAudioTrack.index != index) { if (existingAudioTrack.index != index) {
Log.d(tag, "scanLibraryItemFolder Updating Audio track index from ${existingAudioTrack.index} to $index") Log.d(tag, "scanLibraryItemFolder Updating Audio track index from ${existingAudioTrack.index} to $index")
@ -150,7 +148,7 @@ class FolderScanner(var ctx: Context) {
Log.d(tag, "scanLibraryItemFolder Scanning Audio File Path ${localFile.absolutePath} | ForceAudioProbe=${forceAudioProbe}") Log.d(tag, "scanLibraryItemFolder Scanning Audio File Path ${localFile.absolutePath} | ForceAudioProbe=${forceAudioProbe}")
// TODO: Make asynchronous // TODO: Make asynchronous
var audioProbeResult = probeAudioFile(localFile.absolutePath) val audioProbeResult = probeAudioFile(localFile.absolutePath)
if (existingAudioTrack != null) { if (existingAudioTrack != null) {
// Update audio probe data on existing audio track // Update audio probe data on existing audio track
@ -172,7 +170,7 @@ class FolderScanner(var ctx: Context) {
index++ index++
audioTracks.add(audioTrackToAdd) audioTracks.add(audioTrackToAdd)
} else { } else {
var existingLocalFile = existingLocalFiles.find { elf -> elf.id == localFileId } val existingLocalFile = existingLocalFiles.find { elf -> elf.id == localFileId }
if (existingLocalFile == null) { if (existingLocalFile == null) {
Log.d(tag, "scanLibraryItemFolder new local file found ${localFile.absolutePath}") Log.d(tag, "scanLibraryItemFolder new local file found ${localFile.absolutePath}")
@ -209,8 +207,8 @@ class FolderScanner(var ctx: Context) {
return ItemScanResult.UPDATED return ItemScanResult.UPDATED
} else if (audioTracks.isNotEmpty()) { } else if (audioTracks.isNotEmpty()) {
Log.d(tag, "Found local media item named $itemFolderName with ${audioTracks.size} tracks and ${localFiles.size} local files") Log.d(tag, "Found local media item named $itemFolderName with ${audioTracks.size} tracks and ${localFiles.size} local files")
var localMediaItem = LocalMediaItem(itemId, itemFolderName, localFolder.mediaType, localFolder.id, itemFolder.uri.toString(), itemFolder.getSimplePath(ctx), itemFolder.getBasePath(ctx), itemFolder.getAbsolutePath(ctx),audioTracks,localFiles,coverContentUrl,coverAbsolutePath) val localMediaItem = LocalMediaItem(itemId, itemFolderName, localFolder.mediaType, localFolder.id, itemFolder.uri.toString(), itemFolder.getSimplePath(ctx), itemFolder.getBasePath(ctx), itemFolder.getAbsolutePath(ctx),audioTracks,localFiles,coverContentUrl,coverAbsolutePath)
var localLibraryItem = localMediaItem.getLocalLibraryItem() val localLibraryItem = localMediaItem.getLocalLibraryItem()
DeviceManager.dbManager.saveLocalLibraryItem(localLibraryItem) DeviceManager.dbManager.saveLocalLibraryItem(localLibraryItem)
return ItemScanResult.ADDED return ItemScanResult.ADDED
} else { } else {

View file

@ -454,7 +454,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
} }
fun getDuration() : Long { fun getDuration() : Long {
return currentPlayer.duration return currentPlaybackSession?.totalDurationMs ?: 0L
} }
fun getCurrentBookTitle() : String? { fun getCurrentBookTitle() : String? {

View file

@ -13,8 +13,9 @@
<p class="text-sm text-gray-400">by {{ author }}</p> <p class="text-sm text-gray-400">by {{ author }}</p>
<p v-if="numTracks" class="text-gray-300 text-sm my-1"> <p v-if="numTracks" class="text-gray-300 text-sm my-1">
{{ $elapsedPretty(duration) }} {{ $elapsedPretty(duration) }}
<span class="px-4">{{ $bytesPretty(size) }}</span> <span v-if="!isLocal" class="px-4">{{ $bytesPretty(size) }}</span>
</p> </p>
<p v-if="numTracks" class="text-gray-300 text-sm my-1">{{ numTracks }} Tracks</p>
<div v-if="!isPodcast && progressPercent > 0" class="px-4 py-2 bg-primary text-sm font-semibold rounded-md text-gray-200 mt-4 relative" :class="resettingProgress ? 'opacity-25' : ''"> <div v-if="!isPodcast && progressPercent > 0" class="px-4 py-2 bg-primary text-sm font-semibold rounded-md text-gray-200 mt-4 relative" :class="resettingProgress ? 'opacity-25' : ''">
<p class="leading-6">Your Progress: {{ Math.round(progressPercent * 100) }}%</p> <p class="leading-6">Your Progress: {{ Math.round(progressPercent * 100) }}%</p>