mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 08:20:32 +05:30
feat: add sponsorblock option to skip segment only once (#4584)
This commit is contained in:
parent
451ff6e49a
commit
3fb9e899cb
@ -12,7 +12,8 @@ data class Segment(
|
|||||||
val segment: List<Double> = listOf(),
|
val segment: List<Double> = listOf(),
|
||||||
val userID: String? = null,
|
val userID: String? = null,
|
||||||
val videoDuration: Double? = null,
|
val videoDuration: Double? = null,
|
||||||
val votes: Int? = null
|
val votes: Int? = null,
|
||||||
|
var skipped: Boolean = false
|
||||||
) {
|
) {
|
||||||
val segmentStartAndEnd = segment[0] to segment[1]
|
val segmentStartAndEnd = segment[0] to segment[1]
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,6 @@ enum class SbSkipOptions {
|
|||||||
OFF,
|
OFF,
|
||||||
VISIBLE,
|
VISIBLE,
|
||||||
MANUAL,
|
MANUAL,
|
||||||
AUTOMATIC
|
AUTOMATIC,
|
||||||
|
AUTOMATIC_ONCE
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ object PlayerHelper {
|
|||||||
context: Context,
|
context: Context,
|
||||||
segments: List<Segment>,
|
segments: List<Segment>,
|
||||||
sponsorBlockConfig: MutableMap<String, SbSkipOptions>
|
sponsorBlockConfig: MutableMap<String, SbSkipOptions>
|
||||||
): Long? {
|
): Segment? {
|
||||||
for (segment in segments.filter { it.category != SPONSOR_HIGHLIGHT_CATEGORY }) {
|
for (segment in segments.filter { it.category != SPONSOR_HIGHLIGHT_CATEGORY }) {
|
||||||
val (start, end) = segment.segmentStartAndEnd
|
val (start, end) = segment.segmentStartAndEnd
|
||||||
val (segmentStart, segmentEnd) = (start * 1000f).toLong() to (end * 1000f).toLong()
|
val (segmentStart, segmentEnd) = (start * 1000f).toLong() to (end * 1000f).toLong()
|
||||||
@ -493,7 +493,12 @@ object PlayerHelper {
|
|||||||
if ((duration - currentPosition).absoluteValue < 500) continue
|
if ((duration - currentPosition).absoluteValue < 500) continue
|
||||||
|
|
||||||
if (currentPosition in segmentStart until segmentEnd) {
|
if (currentPosition in segmentStart until segmentEnd) {
|
||||||
if (sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC) {
|
if (sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC ||
|
||||||
|
(
|
||||||
|
sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE &&
|
||||||
|
segment.skipped == false
|
||||||
|
)
|
||||||
|
) {
|
||||||
if (sponsorBlockNotifications) {
|
if (sponsorBlockNotifications) {
|
||||||
runCatching {
|
runCatching {
|
||||||
Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT)
|
Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT)
|
||||||
@ -501,8 +506,14 @@ object PlayerHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
seekTo(segmentEnd)
|
seekTo(segmentEnd)
|
||||||
} else if (sponsorBlockConfig[segment.category] == SbSkipOptions.MANUAL) {
|
segment.skipped = true
|
||||||
return segmentEnd
|
} else if (sponsorBlockConfig[segment.category] == SbSkipOptions.MANUAL ||
|
||||||
|
(
|
||||||
|
sponsorBlockConfig[segment.category] == SbSkipOptions.AUTOMATIC_ONCE &&
|
||||||
|
segment.skipped == true
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return segment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,18 @@ import com.github.libretube.receivers.NotificationReceiver.Companion.ACTION_DOWN
|
|||||||
import com.github.libretube.receivers.NotificationReceiver.Companion.ACTION_DOWNLOAD_RESUME
|
import com.github.libretube.receivers.NotificationReceiver.Companion.ACTION_DOWNLOAD_RESUME
|
||||||
import com.github.libretube.receivers.NotificationReceiver.Companion.ACTION_DOWNLOAD_STOP
|
import com.github.libretube.receivers.NotificationReceiver.Companion.ACTION_DOWNLOAD_STOP
|
||||||
import com.github.libretube.ui.activities.MainActivity
|
import com.github.libretube.ui.activities.MainActivity
|
||||||
|
import java.io.File
|
||||||
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.SocketTimeoutException
|
||||||
|
import java.net.URL
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.StandardOpenOption
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import kotlin.io.path.absolute
|
||||||
|
import kotlin.io.path.createFile
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.fileSize
|
||||||
|
import kotlin.math.min
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@ -54,18 +66,6 @@ import kotlinx.coroutines.withContext
|
|||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import okio.source
|
import okio.source
|
||||||
import java.io.File
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.net.SocketTimeoutException
|
|
||||||
import java.net.URL
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.StandardOpenOption
|
|
||||||
import java.util.concurrent.Executors
|
|
||||||
import kotlin.io.path.absolute
|
|
||||||
import kotlin.io.path.createFile
|
|
||||||
import kotlin.io.path.deleteIfExists
|
|
||||||
import kotlin.io.path.fileSize
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download service with custom implementation of downloading using [HttpURLConnection].
|
* Download service with custom implementation of downloading using [HttpURLConnection].
|
||||||
|
@ -676,11 +676,12 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
|
|||||||
if (!sponsorBlockEnabled || segments.isEmpty()) return
|
if (!sponsorBlockEnabled || segments.isEmpty()) return
|
||||||
|
|
||||||
exoPlayer.checkForSegments(requireContext(), segments, sponsorBlockConfig)
|
exoPlayer.checkForSegments(requireContext(), segments, sponsorBlockConfig)
|
||||||
?.let { segmentEnd ->
|
?.let { segment ->
|
||||||
if (viewModel.isMiniPlayerVisible.value == true) return@let
|
if (viewModel.isMiniPlayerVisible.value == true) return@let
|
||||||
binding.sbSkipBtn.isVisible = true
|
binding.sbSkipBtn.isVisible = true
|
||||||
binding.sbSkipBtn.setOnClickListener {
|
binding.sbSkipBtn.setOnClickListener {
|
||||||
exoPlayer.seekTo(segmentEnd)
|
exoPlayer.seekTo((segment.segmentStartAndEnd.second * 1000f).toLong())
|
||||||
|
segment.skipped = true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -446,6 +446,7 @@
|
|||||||
<item>@string/visible</item>
|
<item>@string/visible</item>
|
||||||
<item>@string/manual</item>
|
<item>@string/manual</item>
|
||||||
<item>@string/automatic</item>
|
<item>@string/automatic</item>
|
||||||
|
<item>@string/automatic_once</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="sb_skip_options_values">
|
<string-array name="sb_skip_options_values">
|
||||||
@ -453,6 +454,7 @@
|
|||||||
<item>visible</item>
|
<item>visible</item>
|
||||||
<item>manual</item>
|
<item>manual</item>
|
||||||
<item>automatic</item>
|
<item>automatic</item>
|
||||||
|
<item>automatic_once</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string-array name="orientation">
|
<string-array name="orientation">
|
||||||
|
@ -430,6 +430,7 @@
|
|||||||
<string name="off">Off</string>
|
<string name="off">Off</string>
|
||||||
<string name="manual">Manual</string>
|
<string name="manual">Manual</string>
|
||||||
<string name="automatic">Automatic</string>
|
<string name="automatic">Automatic</string>
|
||||||
|
<string name="automatic_once">Automatic once</string>
|
||||||
<string name="visible">Show in seek bar</string>
|
<string name="visible">Show in seek bar</string>
|
||||||
<string name="fallback_piped_proxy">Fallback to Piped proxy</string>
|
<string name="fallback_piped_proxy">Fallback to Piped proxy</string>
|
||||||
<string name="fallback_piped_proxy_desc">Load videos via the proxy if connecting to YouTube directly doesn\'t work for the current video (increases the initial loading times). If disabled, YouTube music content likely won\'t play due to YT restrictions.</string>
|
<string name="fallback_piped_proxy_desc">Load videos via the proxy if connecting to YouTube directly doesn\'t work for the current video (increases the initial loading times). If disabled, YouTube music content likely won\'t play due to YT restrictions.</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user