diff --git a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt
index afbc3f422..a8e7cbdb9 100644
--- a/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt
+++ b/app/src/main/java/com/github/libretube/api/PlaylistsHelper.kt
@@ -11,6 +11,7 @@ import com.github.libretube.constants.YOUTUBE_FRONTEND_URL
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.LocalPlaylist
import com.github.libretube.enums.PlaylistType
+import com.github.libretube.extensions.parallelMap
import com.github.libretube.extensions.toID
import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.helpers.ProxyHelper
@@ -188,20 +189,16 @@ object PlaylistsHelper {
} else {
// if not logged in, all video information needs to become fetched manually
// Only do so with 20 videos at once to prevent performance issues
- playlist.videos.mapIndexed { index, id -> id to index }
- .groupBy { it.second % 20 }.forEach { (_, videos) ->
- videos.map {
- async {
- runCatching {
- val stream = RetrofitInstance.api.getStreams(it.first)
- .toStreamItem(
- it.first
- )
- addToPlaylist(playlistId, stream)
- }
+ val streams = playlist.videos.mapIndexed { index, id -> id to index }
+ .groupBy { it.second % 20 }.map { (_, videos) ->
+ videos.parallelMap {
+ runCatching {
+ RetrofitInstance.api.getStreams(it.first)
+ .toStreamItem(it.first)
}
- }.awaitAll()
+ }.mapNotNull { it.getOrNull() }
}
+ addToPlaylist(playlistId, *streams.flatten().toTypedArray())
}
}
}.awaitAll()
diff --git a/app/src/main/java/com/github/libretube/extensions/ParallelMap.kt b/app/src/main/java/com/github/libretube/extensions/ParallelMap.kt
new file mode 100644
index 000000000..401f90151
--- /dev/null
+++ b/app/src/main/java/com/github/libretube/extensions/ParallelMap.kt
@@ -0,0 +1,10 @@
+package com.github.libretube.extensions
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.coroutineScope
+
+suspend fun List.parallelMap(f: suspend (A) -> B): List = coroutineScope {
+ map { async(Dispatchers.IO) { f(it) } }.awaitAll()
+}