[Android] Force playing as audio when casting as audio only

Nicolas Pomepuy git at videolan.org
Thu Mar 27 13:43:49 UTC 2025


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Tue Mar 25 11:29:11 2025 +0100| [6267ed056ef9546ac32ba523f1b6fe383fc37b67] | committer: Duncan McNamara

Force playing as audio when casting as audio only

Fixes #3011

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

 .../src/org/videolan/vlc/gui/video/VideoGridFragment.kt | 13 +++++++++++--
 .../src/org/videolan/vlc/media/MediaUtils.kt            | 10 +++++++---
 .../videolan/vlc/viewmodels/mobile/VideosViewModel.kt   | 17 +++++++++++------
 3 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
index 9a38654da3..7e2ddff9f5 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.kt
@@ -78,6 +78,7 @@ import org.videolan.tools.dp
 import org.videolan.tools.isStarted
 import org.videolan.tools.putSingle
 import org.videolan.tools.retrieveParent
+import org.videolan.vlc.PlaybackService
 import org.videolan.vlc.R
 import org.videolan.vlc.databinding.VideoGridBinding
 import org.videolan.vlc.gui.SecondaryActivity
@@ -771,11 +772,16 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
                     multiSelectHelper.toggleSelection(position)
                     invalidateActionMode()
                 } else {
+                    val castAsAudio = castAsAudio()
+                    if (castAsAudio) {
+                        item.addFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
+                        PlaylistManager.playingAsAudio = true
+                    }
                     when(DefaultPlaybackActionMediaType.VIDEO.getCurrentPlaybackAction(settings)) {
-                        DefaultPlaybackAction.PLAY -> viewModel.playVideo(activity, item, position)
+                        DefaultPlaybackAction.PLAY -> viewModel.playVideo(activity, item, position, forceAudio = castAsAudio)
                         DefaultPlaybackAction.ADD_TO_QUEUE -> MediaUtils.appendMedia(activity, item)
                         DefaultPlaybackAction.INSERT_NEXT -> MediaUtils.insertNext(activity, item)
-                        else  -> viewModel.playVideo(activity, item, position, forceAll = true)
+                        else  -> viewModel.playVideo(activity, item, position, forceAll = true, forceAudio = castAsAudio)
                     }
                 }
             }
@@ -797,6 +803,9 @@ class VideoGridFragment : MediaBrowserFragment<VideosViewModel>(), SwipeRefreshL
             }
         }
     }
+
+    private fun castAsAudio(): Boolean = PlaybackService.renderer.value != null && settings.getBoolean("casting_audio_only", false)
+
     companion object {
         fun newInstance() = VideoGridFragment()
     }
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 b450c90d17..8a792afb2d 100644
--- a/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt
+++ b/application/vlc-android/src/org/videolan/vlc/media/MediaUtils.kt
@@ -230,10 +230,11 @@ object MediaUtils {
         })
     }
 
-    fun playAll(context: Activity?, provider: MedialibraryProvider<MediaWrapper>, position: Int, shuffle: Boolean) = context?.scope?.launch {
+    fun playAll(context: Activity?, provider: MedialibraryProvider<MediaWrapper>, position: Int, shuffle: Boolean, forceAudio: Boolean = false) = context?.scope?.launch {
         provider.loadPagedList(context, {
             provider.getAll().toList()
         }, { l, service ->
+            if (forceAudio) l[position].addFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
             l.takeIf { l.isNotEmpty() }?.let { list ->
                 service.load(list, if (shuffle) SecureRandom().nextInt(min(list.size, MEDIALIBRARY_PAGE_SIZE)) else position)
                 if (shuffle && !service.isShuffling) service.shuffle()
@@ -241,12 +242,13 @@ object MediaUtils {
         })
     }
 
-    fun playAllTracks(context: Context?, provider: VideoGroupsProvider, mediaToPlay: MediaWrapper?, shuffle: Boolean) = context?.scope?.launch {
+    fun playAllTracks(context: Context?, provider: VideoGroupsProvider, mediaToPlay: MediaWrapper?, shuffle: Boolean, forceAudio: Boolean = false) = context?.scope?.launch {
         provider.loadPagedList(context, {
             provider.getAll().flatMap {
                 it.media(Medialibrary.SORT_DEFAULT, false, Settings.includeMissing, false, it.mediaCount(), 0).toList()
             }
         }, {l, service ->
+            if (forceAudio) l[l.indexOf(mediaToPlay)].addFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
             l.takeIf { l.isNotEmpty() }?.let { list ->
                 service.load(list, if (shuffle) SecureRandom().nextInt(min(list.size, MEDIALIBRARY_PAGE_SIZE)) else list.indexOf(mediaToPlay))
                 if (shuffle && !service.isShuffling) service.shuffle()
@@ -254,10 +256,12 @@ object MediaUtils {
         })
     }
 
-    fun playAllTracks(context: Context?, provider: FoldersProvider, position: Int, shuffle: Boolean) = context?.scope?.launch {
+    fun playAllTracks(context: Context?, provider: FoldersProvider, position: Int, shuffle: Boolean, forceAudio: Boolean = false) = context?.scope?.launch {
         SuspendDialogCallback(context) { service ->
             val count = withContext(Dispatchers.IO) { provider.getTotalCount() }
             fun play(list: List<MediaWrapper>) {
+                if (forceAudio) list[position].addFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
+
                 service.load(list, if (shuffle) SecureRandom().nextInt(min(count, MEDIALIBRARY_PAGE_SIZE)) else position)
                 if (shuffle && !service.isShuffling) service.shuffle()
             }
diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/VideosViewModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/VideosViewModel.kt
index 7905e0730a..a8ae4716fc 100644
--- a/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/VideosViewModel.kt
+++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/VideosViewModel.kt
@@ -126,19 +126,24 @@ class VideosViewModel(context: Context, type: VideoGroupingType, val folder: Fol
         MediaUtils.appendMedia(context, list)
     }
 
-    internal fun playVideo(context: FragmentActivity?, mw: MediaWrapper, position: Int, fromStart: Boolean = false, forceAll:Boolean = false) {
+    internal fun playVideo(context: FragmentActivity?, mw: MediaWrapper, position: Int, fromStart: Boolean = false, forceAll:Boolean = false, forceAudio: Boolean = false) {
         if (context === null) return
         if (!mw.isPresent) {
             UiTools.snackerMissing(context)
             return
         }
-        mw.removeFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
-        PlaylistManager.playingAsAudio = false
+        if (forceAudio) {
+            mw.addFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
+            PlaylistManager.playingAsAudio = true
+        } else {
+            mw.removeFlags(MediaWrapper.MEDIA_FORCE_AUDIO)
+            PlaylistManager.playingAsAudio = false
+        }
         if (forceAll) {
             when(val prov = provider) {
-                is VideosProvider -> MediaUtils.playAll(context, prov, position, false)
-                is FoldersProvider -> MediaUtils.playAllTracks(context, prov, position, false)
-                is VideoGroupsProvider -> MediaUtils.playAllTracks(context, prov, mw, false)
+                is VideosProvider -> MediaUtils.playAll(context, prov, position, false, forceAudio)
+                is FoldersProvider -> MediaUtils.playAllTracks(context, prov, position, false, forceAudio)
+                is VideoGroupsProvider -> MediaUtils.playAllTracks(context, prov, mw, false, forceAudio)
             }
         } else {
             if (fromStart) mw.addFlags(MediaWrapper.MEDIA_FROM_START)



More information about the Android mailing list