2022-06-15 02:50:19 +05:30
|
|
|
import AVFAudio
|
2022-06-15 04:11:49 +05:30
|
|
|
import CoreMedia
|
2021-10-23 22:19:45 +05:30
|
|
|
import Defaults
|
|
|
|
import Foundation
|
2022-06-18 18:09:49 +05:30
|
|
|
import SwiftUI
|
2021-10-23 22:19:45 +05:30
|
|
|
|
|
|
|
extension PlayerModel {
|
|
|
|
func handleSegments(at time: CMTime) {
|
|
|
|
if let segment = lastSkipped {
|
2022-06-18 18:09:49 +05:30
|
|
|
if time > .secondsInDefaultTimescale(segment.end + 5) {
|
2021-10-23 22:19:45 +05:30
|
|
|
resetLastSegment()
|
|
|
|
}
|
|
|
|
}
|
2022-06-18 18:09:49 +05:30
|
|
|
|
2021-10-23 22:19:45 +05:30
|
|
|
guard let firstSegment = sponsorBlock.segments.first(where: { $0.timeInSegment(time) }) else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// find last segment in case they are 2 sec or less after each other
|
|
|
|
// to avoid multiple skips in a row
|
|
|
|
var nextSegments = [firstSegment]
|
|
|
|
|
|
|
|
while let segment = sponsorBlock.segments.first(where: {
|
2022-06-15 02:50:19 +05:30
|
|
|
!nextSegments.contains($0) &&
|
|
|
|
$0.timeInSegment(.secondsInDefaultTimescale(nextSegments.last!.end + 2))
|
2021-10-23 22:19:45 +05:30
|
|
|
}) {
|
|
|
|
nextSegments.append(segment)
|
|
|
|
}
|
|
|
|
|
2022-06-15 02:50:19 +05:30
|
|
|
if let segmentToSkip = nextSegments.last, shouldSkip(segmentToSkip, at: time) {
|
2021-10-23 22:19:45 +05:30
|
|
|
skip(segmentToSkip, at: time)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-21 15:39:18 +05:30
|
|
|
var playerItemEndTimeWithSegments: CMTime? {
|
|
|
|
if let duration = playerItemDuration,
|
|
|
|
let segment = sponsorBlock.segments.last,
|
|
|
|
segment.endTime.seconds >= duration.seconds - 3
|
|
|
|
{
|
|
|
|
return segment.endTime
|
|
|
|
}
|
|
|
|
|
|
|
|
return playerItemDuration
|
|
|
|
}
|
|
|
|
|
2021-10-23 22:19:45 +05:30
|
|
|
private func skip(_ segment: Segment, at time: CMTime) {
|
2022-06-15 02:50:19 +05:30
|
|
|
if let duration = playerItemDuration, segment.endTime.seconds >= duration.seconds - 3 {
|
|
|
|
logger.error("segment end time is: \(segment.end) when player item duration is: \(duration.seconds)")
|
|
|
|
|
|
|
|
DispatchQueue.main.async { [weak self] in
|
2022-09-28 19:57:01 +05:30
|
|
|
guard let self else {
|
2022-06-15 02:50:19 +05:30
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
self.pause()
|
|
|
|
|
2022-07-11 03:54:56 +05:30
|
|
|
self.backend.eofPlaybackModeAction()
|
2022-06-15 02:50:19 +05:30
|
|
|
}
|
|
|
|
|
2021-10-23 22:19:45 +05:30
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-08-28 22:48:49 +05:30
|
|
|
backend.seek(to: segment.endTime, seekType: .segmentSkip(segment.category))
|
2022-02-17 01:53:11 +05:30
|
|
|
|
|
|
|
DispatchQueue.main.async { [weak self] in
|
2022-06-18 18:09:49 +05:30
|
|
|
withAnimation {
|
|
|
|
self?.lastSkipped = segment
|
|
|
|
}
|
2022-02-17 01:53:11 +05:30
|
|
|
self?.segmentRestorationTime = time
|
|
|
|
}
|
2021-10-24 14:46:04 +05:30
|
|
|
logger.info("SponsorBlock skipping to: \(segment.end)")
|
2021-10-23 22:19:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
private func shouldSkip(_ segment: Segment, at time: CMTime) -> Bool {
|
|
|
|
guard isPlaying,
|
|
|
|
!restoredSegments.contains(segment),
|
2022-06-18 18:09:49 +05:30
|
|
|
Defaults[.sponsorBlockCategories].contains(segment.category)
|
2021-10-23 22:19:45 +05:30
|
|
|
else {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return time.seconds - segment.start < 2 && segment.end - time.seconds > 2
|
|
|
|
}
|
|
|
|
|
|
|
|
func restoreLastSkippedSegment() {
|
|
|
|
guard let segment = lastSkipped,
|
|
|
|
let time = segmentRestorationTime
|
|
|
|
else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
restoredSegments.append(segment)
|
2022-08-28 22:48:49 +05:30
|
|
|
backend.seek(to: time, seekType: .segmentRestore)
|
2021-10-23 22:19:45 +05:30
|
|
|
resetLastSegment()
|
|
|
|
}
|
|
|
|
|
|
|
|
private func resetLastSegment() {
|
2022-02-17 01:53:11 +05:30
|
|
|
DispatchQueue.main.async { [weak self] in
|
2022-06-18 18:09:49 +05:30
|
|
|
withAnimation {
|
|
|
|
self?.lastSkipped = nil
|
2022-06-26 19:39:56 +05:30
|
|
|
self?.controls.objectWillChange.send()
|
2022-06-18 18:09:49 +05:30
|
|
|
}
|
2022-02-17 01:53:11 +05:30
|
|
|
self?.segmentRestorationTime = nil
|
|
|
|
}
|
2021-10-23 22:19:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
func resetSegments() {
|
|
|
|
resetLastSegment()
|
2023-05-16 22:21:07 +05:30
|
|
|
DispatchQueue.main.async { [weak self] in
|
|
|
|
self?.restoredSegments = []
|
|
|
|
}
|
2021-10-23 22:19:45 +05:30
|
|
|
}
|
|
|
|
}
|