From a5a38a3f661a48868614b108f3bf42b4a767613b Mon Sep 17 00:00:00 2001 From: Bnyro Date: Thu, 19 Jan 2023 17:08:57 +0100 Subject: [PATCH] Cleanup the logic of handling description links --- .../libretube/ui/fragments/PlayerFragment.kt | 101 +++--------------- .../com/github/libretube/util/TextUtils.kt | 49 +++++++++ 2 files changed, 65 insertions(+), 85 deletions(-) diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 13c3ebe63..13bac02c2 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -113,15 +113,15 @@ import com.google.android.exoplayer2.ui.StyledPlayerView import com.google.android.exoplayer2.upstream.DefaultDataSource import com.google.android.exoplayer2.util.MimeTypes 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.Dispatchers import kotlinx.coroutines.launch import org.chromium.net.CronetEngine import retrofit2.HttpException +import java.io.IOException +import java.util.* +import java.util.concurrent.Executors +import kotlin.math.abs class PlayerFragment : BaseFragment(), OnlinePlayerOptions { @@ -1066,91 +1066,22 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { private fun handleLink(link: String) { val uri = Uri.parse(link) // get video id if the link is a valid youtube video link - val videoId = getVideoIdIfVideoLink(link, uri) - if (!videoId.isNullOrEmpty()) { - // check if the video is the current video and has a valid time - if (videoId == this.videoId) { - val timeInMillis = getTimeInMillis(uri) - if (timeInMillis != -1L) { - // seek to the time - exoPlayer.seekTo(timeInMillis) - } - // else do nothing as the video is already playing - } else { - // youtube video link without time or not the current video - // open new player - playNextVideo(videoId) - } - } else { - // not a youtube video link - // handle normally - val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link)) + val videoId = TextUtils.getVideoIdFromUri(link) + if (videoId.isNullOrEmpty()) { + // not a youtube video link, thus handle normally + val intent = Intent(Intent.ACTION_VIEW, uri) startActivity(intent) } - } - - /** - * Get video id if the link is a valid youtube video link - */ - private fun getVideoIdIfVideoLink(link: String, uri: Uri): String? { - if (link.contains("youtube.com")) { - // the link may be in an unsupported format, so we should try/catch it - return try { - uri.getQueryParameter("v") - } catch (e: Exception) { - null + // check if the video is the current video and has a valid time + if (videoId == this.videoId) { + // try finding the time stamp of the url and seek to it if found + TextUtils.getTimeInSeconds(uri)?.let { + exoPlayer.seekTo(it) } - } else if (link.contains("youtu.be")) { - return uri.lastPathSegment + } else { + // youtube video link without time or not the current video, thus open new player + playNextVideo(videoId) } - - return null - } - - /** - * Get time in milliseconds from a youtube video link - */ - private fun getTimeInMillis(uri: Uri): Long { - var time = uri.getQueryParameter("t") ?: return -1L - - var timeInSeconds = 0L - var found = false - - // Check if the time has hours - if (time.contains("h")) { - time.substringBefore("h").toLongOrNull()?.let { - timeInSeconds += it * 60 * 60 - time = time.substringAfter("h") - found = true - } - } - - // Check if the time has minutes - if (time.contains("m")) { - time.substringBefore("m").toLongOrNull()?.let { - timeInSeconds += it * 60 - time = time.substringAfter("m") - found = true - } - } - - // Check if the time has seconds - if (time.contains("s")) { - time.substringBefore("s").toLongOrNull()?.let { - timeInSeconds += it - found = true - } - } - - // Time may not contain h, m or s. In that case, it is just a number of seconds - if (!found) { - time.toLongOrNull()?.let { - timeInSeconds += it - found = true - } - } - - return if (found) timeInSeconds * 1000 else -1 } /** diff --git a/app/src/main/java/com/github/libretube/util/TextUtils.kt b/app/src/main/java/com/github/libretube/util/TextUtils.kt index 6d100523d..201a2957a 100644 --- a/app/src/main/java/com/github/libretube/util/TextUtils.kt +++ b/app/src/main/java/com/github/libretube/util/TextUtils.kt @@ -1,5 +1,6 @@ package com.github.libretube.util +import android.net.Uri import java.net.URL import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -52,4 +53,52 @@ object TextUtils { val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale) return dateObj.format(formatter) } + + /** + * Get time in seconds from a youtube video link + */ + fun getTimeInSeconds(uri: Uri): Long? { + var time = uri.getQueryParameter("t") ?: return -1L + + var timeInSeconds: Long? = null + + // Find all spans containing hours, minutes or seconds + listOf(Pair("h", 60 * 60), Pair("m", 60), Pair("s", 1)).forEach { (separator, timeFactor) -> + if (time.contains(separator)) { + time.substringBefore(separator).toLongOrNull()?.let { + timeInSeconds = (timeInSeconds ?: 0L) + it * timeFactor + time = time.substringAfter(separator) + } + } + } + + // Time may not contain h, m or s. In that case, it is just a number of seconds + if (timeInSeconds == null) { + time.toLongOrNull()?.let { + timeInSeconds = it + } + } + + return timeInSeconds + } + + /** + * Get video id if the link is a valid youtube video link + */ + fun getVideoIdFromUri(link: String): String? { + val uri = Uri.parse(link) + + if (link.contains("youtube.com")) { + // the link may be in an unsupported format, so we should try/catch it + return try { + uri.getQueryParameter("v") + } catch (e: Exception) { + null + } + } else if (link.contains("youtu.be")) { + return uri.lastPathSegment + } + + return null + } }