From 904944e16288fa3159e0a8963a0505e9a8076a4f Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy <nicolas@videolabs.io> Date: Thu, 13 Mar 2025 09:07:07 +0100 Subject: [PATCH 1/4] Send playback errors to the remote access --- .../vlc/remoteaccessserver/RemoteAccessServer.kt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt index f795451019..609087140d 100644 --- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt +++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessServer.kt @@ -59,7 +59,6 @@ import io.ktor.server.plugins.cachingheaders.CachingHeaders import io.ktor.server.plugins.callloging.CallLogging import io.ktor.server.plugins.compression.Compression import io.ktor.server.plugins.compression.matchContentType -import io.ktor.server.plugins.compression.minimumSize import io.ktor.server.plugins.cors.routing.CORS import io.ktor.server.plugins.origin import io.ktor.server.plugins.partialcontent.PartialContent @@ -152,6 +151,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac var service: PlaybackService? = null private val networkSharesResult = ArrayList<MediaLibraryItem>() private val networkDiscoveryRunning = AtomicBoolean(false) + private var lastPlayedLocation = "" private val _serverStatus = MutableLiveData(ServerStatus.NOT_INIT) @@ -709,6 +709,14 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac * @param event the event sent */ override fun onMediaPlayerEvent(event: MediaPlayer.Event) { + service?.currentMediaLocation?.let { + if (it.isNotEmpty() && lastPlayedLocation != service?.currentMediaLocation) { + lastPlayedLocation = it + } + } + if (event.type == MediaPlayer.Event.EncounteredError) { + AppScope.launch { RemoteAccessWebSockets.sendToAll(GenericError(context.getString(R.string.invalid_location, lastPlayedLocation))) } + } if (event.type != MediaPlayer.Event.TimeChanged) return if (System.currentTimeMillis() - lastNowPlayingSendTime < NOW_PLAYING_TIMEOUT) return lastNowPlayingSendTime = System.currentTimeMillis() @@ -913,6 +921,7 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac data class MLRefreshNeeded(val refreshNeeded: Boolean = true) : WSMessage(WSMessageType.ML_REFRESH_NEEDED) data class BrowserDescription(val path: String, val description: String) : WSMessage(WSMessageType.BROWSER_DESCRIPTION) data class PlaybackControlForbidden(val forbidden: Boolean = true): WSMessage(WSMessageType.PLAYBACK_CONTROL_FORBIDDEN) + data class GenericError(val text: String): WSMessage(WSMessageType.ERROR) data class NetworkShares(val shares: List<PlayQueueItem>): WSMessage(WSMessageType.NETWORK_SHARES) data class SearchResults(val albums: List<PlayQueueItem>, val artists: List<PlayQueueItem>, val genres: List<PlayQueueItem>, val playlists: List<PlayQueueItem>, val videos: List<PlayQueueItem>, val tracks: List<PlayQueueItem>) data class BreadcrumbItem(val title: String, val path: String) @@ -961,6 +970,8 @@ class RemoteAccessServer(private val context: Context) : PlaybackService.Callbac BROWSER_DESCRIPTION, @Json(name = "playback-control-forbidden") PLAYBACK_CONTROL_FORBIDDEN, + @Json(name = "error") + ERROR, @Json(name = "network-shares") NETWORK_SHARES } -- GitLab From 555ce56cc711f9ebc1224bb419667bf0c2d9ff6f Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy <nicolas@videolabs.io> Date: Thu, 13 Mar 2025 10:39:33 +0100 Subject: [PATCH 2/4] Fix the remote access stream ids --- .../org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt index cbfe36f289..2728e3ca12 100644 --- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt +++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt @@ -850,7 +850,7 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) { } val list = ArrayList<RemoteAccessServer.PlayQueueItem>(stream.size) stream.forEachIndexed { index, mediaLibraryItem -> - list.add(RemoteAccessServer.PlayQueueItem(3000L + index, mediaLibraryItem.title, " ", 0, mediaLibraryItem.artworkMrl + list.add(RemoteAccessServer.PlayQueueItem(mediaLibraryItem.id, mediaLibraryItem.title, " ", 0, mediaLibraryItem.artworkMrl ?: "", false, "", (mediaLibraryItem as MediaWrapper).uri.toString(), true, favorite = mediaLibraryItem.isFavorite)) } call.respondJson(convertToJson(list)) -- GitLab From 8198ca7eb8c377bbb8fd7a39de6f17e9f170c4b5 Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy <nicolas@videolabs.io> Date: Thu, 13 Mar 2025 10:40:47 +0100 Subject: [PATCH 3/4] Fix the remote access play endpoint by relaxing the media collision --- .../remoteaccessserver/RemoteAccessRouting.kt | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt index 2728e3ca12..1d60bf14a2 100644 --- a/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt +++ b/application/remote-access-server/src/main/java/org/videolan/vlc/remoteaccessserver/RemoteAccessRouting.kt @@ -118,6 +118,16 @@ import org.videolan.vlc.providers.BrowserProvider import org.videolan.vlc.providers.FileBrowserProvider import org.videolan.vlc.providers.StorageProvider import org.videolan.vlc.providers.medialibrary.sanitizeGroups +import org.videolan.vlc.remoteaccessserver.RemoteAccessServer.Companion.getServerFiles +import org.videolan.vlc.remoteaccessserver.RemoteAccessServer.PlayerStatus +import org.videolan.vlc.remoteaccessserver.RemoteAccessSession.verifyLogin +import org.videolan.vlc.remoteaccessserver.utils.MediaZipUtils +import org.videolan.vlc.remoteaccessserver.utils.serveAudios +import org.videolan.vlc.remoteaccessserver.utils.servePlaylists +import org.videolan.vlc.remoteaccessserver.utils.serveSearch +import org.videolan.vlc.remoteaccessserver.utils.serveVideos +import org.videolan.vlc.remoteaccessserver.websockets.RemoteAccessWebSockets +import org.videolan.vlc.remoteaccessserver.websockets.WSIncomingMessage import org.videolan.vlc.util.FileUtils import org.videolan.vlc.util.Permissions import org.videolan.vlc.util.RemoteAccessUtils @@ -132,16 +142,6 @@ import org.videolan.vlc.util.slugify import org.videolan.vlc.util.toByteArray import org.videolan.vlc.viewmodels.browser.FavoritesProvider import org.videolan.vlc.viewmodels.browser.PathOperationDelegate -import org.videolan.vlc.remoteaccessserver.RemoteAccessServer.Companion.getServerFiles -import org.videolan.vlc.remoteaccessserver.RemoteAccessServer.PlayerStatus -import org.videolan.vlc.remoteaccessserver.RemoteAccessSession.verifyLogin -import org.videolan.vlc.remoteaccessserver.utils.MediaZipUtils -import org.videolan.vlc.remoteaccessserver.utils.serveAudios -import org.videolan.vlc.remoteaccessserver.utils.servePlaylists -import org.videolan.vlc.remoteaccessserver.utils.serveSearch -import org.videolan.vlc.remoteaccessserver.utils.serveVideos -import org.videolan.vlc.remoteaccessserver.websockets.RemoteAccessWebSockets -import org.videolan.vlc.remoteaccessserver.websockets.WSIncomingMessage import java.io.BufferedWriter import java.io.File import java.io.FileNotFoundException @@ -950,7 +950,10 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) { val medias = appContext.getFromMl { if (path?.isNotBlank() == true) { - arrayOf(MLServiceLocator.getAbstractMediaWrapper(Uri.parse(path))) + if (id.toLong() > 0) + arrayOf(getMedia(id.toLong())) + else + arrayOf(MLServiceLocator.getAbstractMediaWrapper(Uri.parse(path))) } else when (type) { "album" -> getAlbum(id.toLong()).tracks "artist" -> getArtist(id.toLong()).tracks @@ -969,7 +972,7 @@ fun Route.setupRouting(appContext: Context, scope: CoroutineScope) { } if (medias.isEmpty()) call.respond(HttpStatusCode.NotFound) else { - if (medias.size == 1 && medias[0].id == RemoteAccessServer.getInstance(appContext).service?.currentMediaWrapper?.id) { + if (medias.size == 1 && medias[0].id == RemoteAccessServer.getInstance(appContext).service?.currentMediaWrapper?.id && medias[0].uri == RemoteAccessServer.getInstance(appContext).service?.currentMediaWrapper?.uri) { call.respond(HttpStatusCode.OK) return@get } -- GitLab From 2b5efeec34bc9f3a35a03c70ca5ab53f34b7a21e Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy <nicolas@videolabs.io> Date: Tue, 18 Mar 2025 13:35:20 +0100 Subject: [PATCH 4/4] Bump the remote access version to 0.5.0 --- build.gradle | 2 +- buildsystem/compile-remoteaccess.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 27fd9e7d87..227e656f4b 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ ext { versionCode = 3060330 versionName = project.hasProperty('forceVlc4') && project.getProperty('forceVlc4') ? '4.0.0-preview - ' + versionCode : '3.6.4 Beta 3' vlcMajorVersion = project.hasProperty('forceVlc4') && project.getProperty('forceVlc4') ? 4 : 3 - remoteAccessVersion = '0.4.0' + remoteAccessVersion = '0.5.0' libvlcVersion = vlcMajorVersion == 3 ? '3.6.0' :'4.0.0-eap18' medialibraryVersion = vlcMajorVersion == 3 ? '0.13.13-rc15' : '0.13.13-vlc4-rc15' minSdkVersion = 17 diff --git a/buildsystem/compile-remoteaccess.sh b/buildsystem/compile-remoteaccess.sh index 1ebe51f2ec..81a7164914 100755 --- a/buildsystem/compile-remoteaccess.sh +++ b/buildsystem/compile-remoteaccess.sh @@ -57,7 +57,7 @@ done ############################## diagnostic "Setting up the Remote Access project" - REMOTE_ACCESS_TESTED_HASH=c0e259d9af41d24fc82d7bbafc7df2345d129bc2 + REMOTE_ACCESS_TESTED_HASH=a0fb5c209f506da0dd1cb1f9ff01b9f9a49eb489 REMOTE_ACCESS_REPOSITORY=https://code.videolan.org/videolan/remoteaccess : ${VLC_REMOTE_ACCESS_PATH:="$(pwd -P)/application/remote-access-client/remoteaccess"} -- GitLab