Merge pull request #3726 from Bnyro/master

Fix importing large playlists or CSV playlist from YT
This commit is contained in:
Bnyro 2023-05-08 16:47:13 +02:00 committed by GitHub
commit 2a6dd792a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 19 deletions

View File

@ -148,19 +148,20 @@ object PlaylistsHelper {
) )
} else { } else {
// if not logged in, all video information needs to become fetched manually // if not logged in, all video information needs to become fetched manually
runCatching { // Only do so with 20 videos at once to prevent performance issues
val streamItems = playlist.videos.map { playlist.videos.mapIndexed { index, id -> id to index }
async { .groupBy { it.second % 20 }.forEach { (_, videos) ->
runCatching { videos.map {
RetrofitInstance.api.getStreams(it).toStreamItem(it) async {
}.getOrNull() runCatching {
} val stream = RetrofitInstance.api.getStreams(it.first).toStreamItem(
it.first
)
addToPlaylist(playlistId, stream)
}
}
}.awaitAll()
} }
.awaitAll()
.filterNotNull()
addToPlaylist(playlistId, *streamItems.toTypedArray())
}
} }
} }
}.awaitAll() }.awaitAll()

View File

@ -105,10 +105,14 @@ object ImportHelper {
activity.contentResolver.openInputStream(uri)?.use { activity.contentResolver.openInputStream(uri)?.use {
val lines = it.bufferedReader().use { reader -> reader.lines().toList() } val lines = it.bufferedReader().use { reader -> reader.lines().toList() }
playlist.name = lines[1].split(",").reversed()[2] playlist.name = lines[1].split(",").reversed()[2]
val splitIndex = lines.indexOfFirst { line -> line.isBlank() } var splitIndex = lines.indexOfFirst { line -> line.isBlank() }
// seek until playlist items table
while (lines.getOrNull(splitIndex + 1).orEmpty().isBlank()) {
splitIndex++
}
lines.subList(splitIndex + 2, lines.size).forEach { line -> lines.subList(splitIndex + 2, lines.size).forEach { line ->
line.split(",").firstOrNull()?.let { videoId -> line.split(",").firstOrNull()?.let { videoId ->
if (videoId.isNotBlank()) playlist.videos = playlist.videos + videoId if (videoId.isNotBlank()) playlist.videos += videoId.trim()
} }
} }
importPlaylists.add(playlist) importPlaylists.add(playlist)

View File

@ -110,6 +110,10 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.upstream.DefaultDataSource import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.util.MimeTypes import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import java.util.*
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -118,10 +122,6 @@ import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
import java.util.*
import java.util.concurrent.Executors
import kotlin.math.abs
class PlayerFragment : Fragment(), OnlinePlayerOptions { class PlayerFragment : Fragment(), OnlinePlayerOptions {
private var _binding: FragmentPlayerBinding? = null private var _binding: FragmentPlayerBinding? = null

View File

@ -13,6 +13,7 @@ import com.github.libretube.ui.base.BasePreferenceFragment
import com.github.libretube.ui.dialogs.BackupDialog import com.github.libretube.ui.dialogs.BackupDialog
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -63,7 +64,7 @@ class BackupRestoreSettings : BasePreferenceFragment() {
*/ */
private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) { private val getPlaylistsFile = registerForActivityResult(ActivityResultContracts.GetContent()) {
it?.let { it?.let {
lifecycleScope.launch(Dispatchers.IO) { CoroutineScope(Dispatchers.IO).launch {
ImportHelper.importPlaylists(requireActivity(), it) ImportHelper.importPlaylists(requireActivity(), it)
} }
} }