Skip to content

Commit

Permalink
Resume playback from the last position when user plays it again
Browse files Browse the repository at this point in the history
  • Loading branch information
vipulyaara committed Sep 5, 2024
1 parent 4c044fc commit f945b4b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import com.sarahang.playback.core.PlaybackConnection
import com.sarahang.playback.core.albumId
import com.sarahang.playback.core.fileId
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.kafka.base.AppInitializer
import org.kafka.base.CoroutineDispatchers
Expand All @@ -29,22 +34,42 @@ class AudioProgressInitializer @Inject constructor(

override fun init() {
coroutineScope.launch(dispatchers.io) {
playbackConnection.nowPlaying
playbackConnection.playbackProgress
.filter { it.isPlaying }
.buffer(1)
.map { it.position + it.elapsed }
.filter { it % 5000 < 1000 }
.onEach { debug { "Updating recent audio position: $it" } }
.distinctUntilChanged()
.collectLatest { timestamp ->
debug { "Updating progress for $timestamp" }

playbackConnection.nowPlaying.value.albumId?.let { albumId ->
playbackConnection.nowPlaying.value.fileId.let { fileId ->
val audioItem = recentAudioDao.getByAlbumId(albumId)
if (audioItem == null) {
val audio = RecentAudioItem(fileId = fileId, albumId = albumId)
recentAudioDao.insert(audio)
} else {
recentAudioDao.updateNowPlaying(albumId = albumId, fileId = fileId)
}
}
val nowPlaying = playbackConnection.nowPlaying.value
nowPlaying.albumId?.let { albumId ->
updateRecentAudio(
albumId = albumId,
fileId = nowPlaying.fileId,
timestamp = timestamp
)
}
}
}
}

private suspend fun updateRecentAudio(albumId: String, fileId: String, timestamp: Long) {
val audioItem = recentAudioDao.getByAlbumId(albumId)
if (audioItem == null) {
val audio = RecentAudioItem(
fileId = fileId,
albumId = albumId,
currentTimestamp = timestamp,
duration = 0 // duration is not available
)
recentAudioDao.insert(audio)
} else {
recentAudioDao.updateNowPlaying(
albumId = albumId,
fileId = fileId,
currentTimestamp = timestamp
)
}
}
}
4 changes: 2 additions & 2 deletions data/database/src/main/java/com/kafka/data/dao/RecentsDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ abstract class RecentAudioDao : EntityDao<RecentAudioItem> {
@Query("select * from recent_audio where albumId = :albumId")
abstract fun observeByAlbumId(albumId: String): Flow<RecentAudioItem?>

@Query("update recent_audio set fileId = :fileId where albumId = :albumId")
abstract suspend fun updateNowPlaying(albumId: String, fileId: String)
@Query("update recent_audio set fileId = :fileId, currentTimestamp = :currentTimestamp where albumId = :albumId")
abstract suspend fun updateNowPlaying(albumId: String, fileId: String, currentTimestamp: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ class ResumeAlbum @Inject constructor(

analytics.log { playItem(itemId = params, index = index) }

playbackConnection.playAlbum(params, index)
playbackConnection.playAlbum(params, index, audio?.currentTimestamp)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class IsResumableAudio @Inject constructor(
val files = audioDataSource.findAudiosByItemId(params.itemId)

files.map { it.id }.indexOf(recentAudio?.fileId) > 0
|| (recentAudio?.currentTimestamp ?: 0) > 0
}.flowOn(dispatchers.io)
}

Expand Down

0 comments on commit f945b4b

Please sign in to comment.