Commit f30d5d50 authored by Geoffrey Métais's avatar Geoffrey Métais

Expand playlists/folders in background

parent afc6b8df
......@@ -415,7 +415,7 @@ public class PlaybackService extends MediaBrowserServiceCompat{
/*
* Launch the activity if needed
*/
if (action.startsWith(Constants.ACTION_REMOTE_GENERIC) && !playlistManager.getPlayer().isPlaying() && !playlistManager.hasCurrentMedia()) {
if (action.startsWith(Constants.ACTION_REMOTE_GENERIC) && !isPlaying() && !playlistManager.hasCurrentMedia()) {
final Intent activityIntent = getPackageManager().getLaunchIntentForPackage(getPackageName());
if (activityIntent != null)
context.startActivity(activityIntent);
......@@ -427,10 +427,8 @@ public class PlaybackService extends MediaBrowserServiceCompat{
if (action.equalsIgnoreCase(Constants.ACTION_REMOTE_PLAYPAUSE)) {
if (!playlistManager.hasCurrentMedia())
loadLastAudioPlaylist();
if (playlistManager.getPlayer().isPlaying())
pause();
else
play();
if (isPlaying()) pause();
else play();
} else if (action.equalsIgnoreCase(Constants.ACTION_REMOTE_PLAY)) {
if (!isPlaying() && playlistManager.hasCurrentMedia())
play();
......@@ -637,7 +635,7 @@ public class PlaybackService extends MediaBrowserServiceCompat{
final MediaWrapper mw = playlistManager.getCurrentMedia();
if (mw != null) {
final boolean coverOnLockscreen = mSettings.getBoolean("lockscreen_cover", true);
final boolean playing = playlistManager.getPlayer().isPlaying();
final boolean playing = isPlaying();
final MediaSessionCompat.Token sessionToken = mMediaSession.getSessionToken();
final Context ctx = this;
ExecutorHolder.executorService.execute(new Runnable() {
......@@ -1156,7 +1154,7 @@ public class PlaybackService extends MediaBrowserServiceCompat{
.putExtra("artist", media.getArtist())
.putExtra("album", media.getAlbum())
.putExtra("duration", media.getLength())
.putExtra("playing", playlistManager.getPlayer().isPlaying())
.putExtra("playing", isPlaying())
.putExtra("package", "org.videolan.vlc"));
}
......
......@@ -3,12 +3,10 @@ package org.videolan.vlc.media
import android.net.Uri
import android.support.annotation.MainThread
import android.support.v4.media.session.PlaybackStateCompat
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newSingleThreadContext
import org.videolan.libvlc.IVLCVout
import org.videolan.libvlc.Media
import org.videolan.libvlc.MediaPlayer
import org.videolan.libvlc.RendererItem
import org.videolan.libvlc.*
import org.videolan.medialibrary.media.MediaWrapper
import org.videolan.vlc.RendererDelegate
import org.videolan.vlc.VLCApplication
......@@ -23,7 +21,6 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
private val settings by lazy(LazyThreadSafetyMode.NONE) { VLCApplication.getSettings() }
private var mediaplayer = newMediaPlayer()
@Volatile var expanding = false
var switchToVideo = false
var seekable = false
var pausable = false
......@@ -230,12 +227,24 @@ class PlayerController : IVLCVout.Callback, MediaPlayer.EventListener {
fun setVolume(volume: Int) = mediaplayer.setVolume(volume)
suspend fun expand(): MediaList? {
return mediaplayer.media?.let {
mediaplayer.setEventListener(null)
val ml = async { it.subItems() }.await()
it.release()
mediaplayer.setEventListener(this@PlayerController)
return ml
}
}
override fun onEvent(event: MediaPlayer.Event?) {
if (event === null) return
when(event.type) {
MediaPlayer.Event.Playing -> playbackState = PlaybackStateCompat.STATE_PLAYING
MediaPlayer.Event.Paused -> playbackState = PlaybackStateCompat.STATE_PAUSED
MediaPlayer.Event.Stopped -> playbackState = PlaybackStateCompat.STATE_STOPPED
MediaPlayer.Event.Stopped,
MediaPlayer.Event.EncounteredError,
MediaPlayer.Event.EndReached -> playbackState = PlaybackStateCompat.STATE_STOPPED
MediaPlayer.Event.PausableChanged -> pausable = event.pausable
MediaPlayer.Event.SeekableChanged -> seekable = event.seekable
}
......
......@@ -48,6 +48,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
var savedTime = 0L
private var random = Random(System.currentTimeMillis())
private var newMedia = false
@Volatile var expanding = false
fun hasMedia() = mediaList.size() != 0
fun hasCurrentMedia() = isValidPosition(currentIndex)
......@@ -140,7 +141,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
saveMediaList()
savePosition(true)
saveCurrentMedia()
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun play() = player.play()
......@@ -199,7 +200,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
if (shuffling) previous.clear()
shuffling = !shuffling
savePosition()
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun setRepeatType(repeatType: Int) {
......@@ -207,7 +208,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
if (mediaList.isAudioList && settings.getBoolean("audio_save_repeat", false))
settings.edit().putInt(AUDIO_REPEAT_MODE_KEY, repeating).apply()
savePosition()
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun playIndex(index: Int, flags: Int = 0) {
......@@ -316,25 +317,29 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
override fun onItemAdded(index: Int, mrl: String?) {
if (BuildConfig.DEBUG) Log.i(TAG, "CustomMediaListItemAdded")
if (currentIndex >= index && !player.expanding) ++currentIndex
determinePrevAndNextIndices()
executeUpdate()
saveMediaList()
if (currentIndex >= index && !expanding) ++currentIndex
launch(UI, CoroutineStart.UNDISPATCHED) {
determinePrevAndNextIndices()
executeUpdate()
saveMediaList()
}
}
override fun onItemRemoved(index: Int, mrl: String?) {
if (BuildConfig.DEBUG) Log.i(TAG, "CustomMediaListItemDeleted")
if (currentIndex >= index && !player.expanding) --currentIndex
determinePrevAndNextIndices()
if (currentIndex == index && !player.expanding) {
when {
nextIndex != -1 -> next()
currentIndex != -1 -> playIndex(currentIndex, 0)
else -> stop()
if (currentIndex >= index && !expanding) --currentIndex
launch(UI, CoroutineStart.UNDISPATCHED) {
determinePrevAndNextIndices()
if (currentIndex == index && !expanding) {
when {
nextIndex != -1 -> next()
currentIndex != -1 -> playIndex(currentIndex, 0)
else -> stop()
}
}
executeUpdate()
saveMediaList()
}
executeUpdate()
saveMediaList()
}
private fun executeUpdate() {
......@@ -379,7 +384,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
}
@Synchronized
fun saveCurrentMedia() {
private fun saveCurrentMedia() {
settings.edit()
.putString(if (mediaList.isAudioList) "current_song" else "current_media", mediaList.getMRL(Math.max(currentIndex, 0)))
.apply()
......@@ -410,16 +415,18 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
// If we are in random mode, we completely reset the stored previous track
// as their indices changed.
previous.clear()
determinePrevAndNextIndices()
executeUpdate()
saveMediaList()
launch(UI, CoroutineStart.UNDISPATCHED) {
determinePrevAndNextIndices()
executeUpdate()
saveMediaList()
}
}
private fun determinePrevAndNextIndices(expand: Boolean = false) {
private suspend fun determinePrevAndNextIndices(expand: Boolean = false) {
if (expand) {
player.expanding = true
expanding = true
nextIndex = expand(getCurrentMedia()!!.type == MediaWrapper.TYPE_STREAM)
player.expanding = false
expanding = false
} else {
nextIndex = -1
}
......@@ -483,16 +490,12 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
* @return the index of the media was expanded, and -1 if no media was expanded
*/
@MainThread
private fun expand(updateHistory: Boolean): Int {
val media = player.getMedia()
if (media === null) return -1
val mrl = if (updateHistory) media.uri.toString() else null
val ml = media.subItems()
media.release()
private suspend fun expand(updateHistory: Boolean): Int {
val ml = player.expand()
var ret = -1
if (ml != null && ml.count > 0) {
val mrl = if (updateHistory) getCurrentMedia()?.location else null
mediaList.remove(currentIndex)
for (i in ml.count - 1 downTo 0) {
val child = ml.getMediaAt(i)
......@@ -500,8 +503,7 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
mediaList.insert(currentIndex, MediaWrapper(child))
child.release()
}
if (mrl !== null && ml.count == 1)
Medialibrary.getInstance().addToHistory(mrl, mediaList.getMedia(currentIndex)!!.title)
if (mrl !== null && ml.count == 1) medialibrary.addToHistory(mrl, getCurrentMedia()!!.title)
ret = currentIndex
}
ml?.release()
......@@ -589,23 +591,23 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
*/
fun moveItem(positionStart: Int, positionEnd: Int) {
mediaList.move(positionStart, positionEnd)
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun insertItem(position: Int, mw: MediaWrapper) {
mediaList.insert(position, mw)
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun remove(position: Int) {
mediaList.remove(position)
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun removeLocation(location: String) {
mediaList.remove(location)
determinePrevAndNextIndices()
launch(UI, CoroutineStart.UNDISPATCHED) { determinePrevAndNextIndices() }
}
fun getMediaListSize()= mediaList.size()
......@@ -654,9 +656,11 @@ class PlaylistManager(val service: PlaybackService) : MediaWrapperList.EventList
MediaPlayer.Event.EndReached -> {
saveMediaMeta()
if (isBenchmark) player.setPreviousStats()
determinePrevAndNextIndices(true)
if (nextIndex == -1) savePosition(true)
next()
launch(UI, CoroutineStart.UNDISPATCHED) {
determinePrevAndNextIndices(true)
if (nextIndex == -1) savePosition(true)
next()
}
}
MediaPlayer.Event.EncounteredError -> next()
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment