[Android] Remote access: allow playing all from a folder

Nicolas Pomepuy git at videolan.org
Thu Feb 22 13:29:25 UTC 2024


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Wed Jan 31 09:49:58 2024 +0100| [ea42816ab8e564be19eb607bce1882f704433246] | committer: Nicolas Pomepuy

Remote access: allow playing all from a folder

> https://code.videolan.org/videolan/vlc-android/commit/ea42816ab8e564be19eb607bce1882f704433246
---

 .../videolan/vlc/webserver/RemoteAccessRouting.kt  | 45 +++++++++++++++++-----
 .../network-sharing-server/src/plugins/api.js      |  4 +-
 .../network-sharing-server/src/plugins/vlcUtils.js |  4 +-
 buildsystem/network-sharing-server/src/routes.js   |  2 +-
 4 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
index 431d4ec7a7..9c6679dcb3 100644
--- a/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
+++ b/application/webserver/src/main/java/org/videolan/vlc/webserver/RemoteAccessRouting.kt
@@ -713,7 +713,25 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) {
             val id = call.request.queryParameters["id"]
             type?.let { type ->
 
-                val medias = appContext.getFromMl {
+                val medias = if (type == "browser") {
+                    val path = call.request.queryParameters["path"] ?: kotlin.run {
+                        call.respond(HttpStatusCode.NotFound)
+                        return at get
+                    }
+                    val decodedPath = Uri.decode(path)
+
+                    val dataset = LiveDataset<MediaLibraryItem>()
+                    var list: Pair<List<MediaLibraryItem>, ArrayList<Pair<Int, String>>>? = null
+                    val provider = withContext(Dispatchers.Main) {
+                        FileBrowserProvider(appContext, dataset, decodedPath, false, false, Medialibrary.SORT_FILENAME, false)
+                    }
+                    try {
+                        list = getMediaFromProvider( provider, dataset)
+                    } catch (e: Exception) {
+                        Log.e(this::class.java.simpleName, e.message, e)
+                    }
+                    list?.first?.map { it as MediaWrapper }?.toTypedArray()
+                } else appContext.getFromMl {
                     when (type) {
                         "video-group" -> {
                             id?.let { id ->
@@ -962,6 +980,18 @@ private suspend fun getLogsFiles(): List<LogFile> = withContext(Dispatchers.IO)
 
 data class LogFile(val path:String, val type:String)
 
+
+private suspend fun getMediaFromProvider(provider: BrowserProvider, dataset: LiveDataset<MediaLibraryItem>): Pair<List<MediaLibraryItem>, ArrayList<Pair<Int, String>>> {
+    dataset.await()
+    val descriptions = ArrayList<Pair<Int, String>>()
+    observeLiveDataUntil(1500, provider.descriptionUpdate) { pair ->
+        descriptions.add(pair)
+        val block = descriptions.size < dataset.getList().size
+        block
+    }
+   return Pair(dataset.getList(), descriptions)
+}
+
 /**
  * Get the content from a [BrowserProvider]
  * Gracefully (or not) waits for the [LiveData] to be set before sending the result back
@@ -972,15 +1002,10 @@ data class LogFile(val path:String, val type:String)
  * @return a populated list
  */
 private suspend fun getProviderContent(context:Context, provider: BrowserProvider, dataset: LiveDataset<MediaLibraryItem>, idPrefix: Long): ArrayList<RemoteAccessServer.PlayQueueItem> {
-    dataset.await()
-    val descriptions = ArrayList<Pair<Int, String>>()
-    observeLiveDataUntil(1500, provider.descriptionUpdate) { pair ->
-        descriptions.add(pair)
-        val block = descriptions.size < dataset.getList().size
-        block
-    }
+    val mediaFromProvider = getMediaFromProvider(provider, dataset)
     val list = ArrayList<RemoteAccessServer.PlayQueueItem>()
-    dataset.getList().forEachIndexed { index, mediaLibraryItem ->
+
+    mediaFromProvider.first.forEachIndexed { index, mediaLibraryItem ->
         val description = try {
             if (mediaLibraryItem is MediaWrapper && mediaLibraryItem.type != MediaWrapper.TYPE_DIR) {
                 if (mediaLibraryItem.uri.scheme.isSchemeFile()) {
@@ -990,7 +1015,7 @@ private suspend fun getProviderContent(context:Context, provider: BrowserProvide
                 } else
                     ""
             } else {
-                val unparsedDescription = descriptions.firstOrNull { it.first == index }?.second
+                val unparsedDescription = mediaFromProvider.second.firstOrNull { it.first == index }?.second
                 val folders = unparsedDescription.getFolderNumber()
                 val files = unparsedDescription.getFilesNumber()
                 if (folders > 0 && files > 0) {
diff --git a/buildsystem/network-sharing-server/src/plugins/api.js b/buildsystem/network-sharing-server/src/plugins/api.js
index e851d5e222..e7bf073f79 100644
--- a/buildsystem/network-sharing-server/src/plugins/api.js
+++ b/buildsystem/network-sharing-server/src/plugins/api.js
@@ -185,12 +185,14 @@ export const vlcApi = {
      * Retrieve the media play API URL
      * @param {String} type the media container type (video-group, video-folder, ...)
      * @param {String} id the media container id
+     * @param {String} path the path of the folder to play
      * @returns the URL
      */
-    playAll: (type, id) => {
+    playAll: (type, id, path) => {
         const params = {}
         if (type) params.type = type
         if (id) params.id = id
+        if (path != "") params.path = path
         return `${API_URL}play-all?${new URLSearchParams(params).toString()}`
     },
     /**
diff --git a/buildsystem/network-sharing-server/src/plugins/vlcUtils.js b/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
index a4e3d947b4..4b4a72c728 100644
--- a/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
+++ b/buildsystem/network-sharing-server/src/plugins/vlcUtils.js
@@ -50,8 +50,8 @@ export default {
         app.config.globalProperties.$playAll = (route) => {
             let type= route.meta.playAllType
             let id = (type == "video-group") ? route.params.groupId : (type == "video-folder") ? route.params.folderId : 0
-            console.log(`Play all: ${type} with id: ${id}`)
-             axios.get(vlcApi.playAll(type, id))
+            let path = (type == "browser") ? route.params.browseId : ""
+             axios.get(vlcApi.playAll(type, id, path))
                  .catch(function (error) {
                      if (error.response.status != 200) {
                          appStore.warning = { type: "warning", message: error.response.data }
diff --git a/buildsystem/network-sharing-server/src/routes.js b/buildsystem/network-sharing-server/src/routes.js
index 94372a284c..ee27506e1e 100644
--- a/buildsystem/network-sharing-server/src/routes.js
+++ b/buildsystem/network-sharing-server/src/routes.js
@@ -34,7 +34,7 @@ const routes = [
     path: '/browse', meta: { showDisplayBar: true },
     children: [
       { path: '', component: BrowseList, name: 'BrowseList', meta: { showDisplayBar: true } },
-      { path: ':browseId', component: BrowseChild, name: 'BrowseChild', meta: { showDisplayBar: true } },
+      { path: ':browseId', component: BrowseChild, name: 'BrowseChild', meta: { showDisplayBar: true, showFAB: true, playAllType: "browser" } },
     ]
   },
   { path: '/playlists', component: PlaylistList, name: 'PlaylistList', meta: { showDisplayBar: true } },



More information about the Android mailing list