[Android] MediaQueue progress: optimizations
Geoffrey Métais
git at videolan.org
Mon Feb 24 07:23:48 CET 2020
vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Fri Feb 21 17:52:30 2020 +0100| [a3fd50b9b6151a8346db4527804a9c7177ecbd9f] | committer: Geoffrey Métais
MediaQueue progress: optimizations
* Prevent crash when current position is -1
* Store total time in ViewModel instead of recalculating
* extract values for readability
> https://code.videolan.org/videolan/vlc-android/commit/a3fd50b9b6151a8346db4527804a9c7177ecbd9f
---
.../src/org/videolan/vlc/gui/audio/AudioPlayer.kt | 30 +++++++++-------------
.../src/org/videolan/vlc/media/MediaUtils.kt | 6 ++---
.../org/videolan/vlc/viewmodels/PlaylistModel.kt | 16 ++++++++----
3 files changed, 25 insertions(+), 27 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
index 0e819cb37..8458fe2a2 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayer.kt
@@ -49,8 +49,8 @@ import androidx.vectordrawable.graphics.drawable.AnimatedVectorDrawableCompat
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.*
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.onEach
import org.videolan.medialibrary.Tools
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.resources.*
@@ -70,6 +70,7 @@ import org.videolan.vlc.gui.view.AudioMediaSwitcher
import org.videolan.vlc.gui.view.AudioMediaSwitcher.AudioMediaSwitcherListener
import org.videolan.vlc.manageAbRepeatStep
import org.videolan.vlc.media.PlaylistManager.Companion.hasMedia
+import org.videolan.vlc.util.launchWhenStarted
import org.videolan.vlc.util.share
import org.videolan.vlc.viewmodels.PlaybackProgress
import org.videolan.vlc.viewmodels.PlaylistModel
@@ -110,13 +111,11 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
playlistModel = PlaylistModel.get(this)
playlistModel.progress.observe(this at AudioPlayer, Observer { it?.let { updateProgress(it) } })
playlistAdapter.setModel(playlistModel)
- lifecycleScope.launchWhenStarted {
- playlistModel.dataset.asFlow().conflate().collect {
- doUpdate()
- playlistAdapter.update(it)
- delay(50L)
- }
- }
+ playlistModel.dataset.asFlow().conflate().onEach {
+ doUpdate()
+ playlistAdapter.update(it)
+ delay(50L)
+ }.launchWhenStarted(lifecycleScope)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
@@ -291,6 +290,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
}
private fun updateProgress(progress: PlaybackProgress) {
+ if (playlistModel.currentMediaPosition == -1) return
binding.length.text = progress.lengthText
binding.timeline.max = progress.length.toInt()
binding.progressBar.max = progress.length.toInt()
@@ -299,29 +299,23 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, IAudioPlay
val displayTime = if (showRemainingTime) Tools.millisToString(progress.time - progress.length) else progress.timeText
binding.headerTime.text = displayTime
binding.time.text = displayTime
- binding.timeline.progress = playlistModel.service?.getTime(progress.time)
- ?: progress.time.toInt()
+ binding.timeline.progress = progress.time.toInt()
binding.progressBar.progress = progress.time.toInt()
}
- val totalLength = playlistModel.medias?.map { if (it.length != 0L) it.length else it.time }?.sum()
- ?: 0L
val elapsedTracksTime = playlistModel.medias?.run {
subList(0, playlistModel.currentMediaPosition).map {
if (it.length != 0L) it.length else it.time
}.sum()
} ?: 0L
- val mediaProgress = playlistModel.service?.getTime(progress.time)?.toLong() ?: progress.time
- val totalTime = elapsedTracksTime + mediaProgress
+ val totalTime = elapsedTracksTime + progress.time
+ val currentProgressText = if (totalTime == 0L) "0s" else Tools.millisToString(totalTime, true, false, false)
val textTrack = getString(R.string.track_index, "${playlistModel.currentMediaPosition + 1} / ${playlistModel.medias?.size}")
- val textProgress = getString(R.string.audio_queue_progress, "${if (totalTime == 0L) "0s" else Tools.millisToString(totalTime, true, false, false)} / ${Tools.millisToString(totalLength, true, false, false)}")
-
+ val textProgress = getString(R.string.audio_queue_progress, "$currentProgressText / ${playlistModel.totalTime}")
binding.audioPlayProgress.text = "$textTrack • $textProgress"
binding.songsList.setPadding(binding.songsList.paddingLeft, binding.songsList.paddingTop, binding.songsList.paddingRight, binding.audioPlayProgress.height + 8.dp)
-
-
}
override fun onSelectionSet(position: Int) {
diff --git a/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt b/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt
index 234dbd6f5..fe2c225eb 100644
--- a/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt
+++ b/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt
@@ -3,11 +3,8 @@ package org.videolan.vlc.media
import android.app.Activity
import android.app.ProgressDialog
import android.content.Context
-import android.content.DialogInterface
import android.content.Intent
import android.net.Uri
-import android.os.Handler
-import android.os.Looper
import android.provider.MediaStore
import android.provider.OpenableColumns
import android.text.TextUtils
@@ -20,7 +17,8 @@ import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.actor
-import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.first
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.MLServiceLocator
import org.videolan.medialibrary.Tools
diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
index cf5247861..55c206093 100644
--- a/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
+++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/PlaylistModel.kt
@@ -24,13 +24,10 @@ import android.support.v4.media.session.PlaybackStateCompat
import androidx.annotation.MainThread
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.ObsoleteCoroutinesApi
+import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.withContext
import org.videolan.medialibrary.Tools
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.tools.livedata.LiveDataset
@@ -51,6 +48,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
private var filtering = false
val progress = MediatorLiveData<PlaybackProgress>()
val playerState = MutableLiveData<PlayerState>()
+ var totalTime = ""
val connected : Boolean
get() = service !== null
@@ -72,6 +70,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
}
override fun update() {
+ updateTotalTime()
service?.run {
dataset.value = media.toMutableList()
playerState.value = PlayerState(isPlaying, title, artist)
@@ -155,7 +154,7 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
}
val length : Long
- get() = service?.length ?: 0L
+ get() = service?.length ?: 0L
val playing : Boolean
get() = service?.isPlaying ?: false
@@ -226,6 +225,13 @@ class PlaylistModel : ViewModel(), PlaybackService.Callback by EmptyPBSCallback
}
}
+ private fun updateTotalTime() = viewModelScope.launch{
+ val totalLength = medias?.map {
+ if (it.length != 0L) it.length else it.time
+ }?.sum() ?: 0L
+ totalTime = Tools.millisToString(totalLength, true, false, false)
+ }
+
companion object {
fun get(fragment: Fragment) = ViewModelProviders.of(fragment.requireActivity()).get(PlaylistModel::class.java)
}
More information about the Android
mailing list