1
0
mirror of https://github.com/yattee/yattee.git synced 2024-12-13 22:00:31 +05:30
yattee/Model/Player/PlayerSponsorBlock.swift

106 lines
3.1 KiB
Swift
Raw Normal View History

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
import SwiftUI
2021-10-23 22:19:45 +05:30
extension PlayerModel {
func handleSegments(at time: CMTime) {
if let segment = lastSkipped {
if time > .secondsInDefaultTimescale(segment.end + 5) {
2021-10-23 22:19:45 +05:30
resetLastSegment()
}
}
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)
}
}
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) {
backend.seek(to: segment.endTime, seekType: .segmentSkip(segment.category))
2022-02-17 01:53:11 +05:30
DispatchQueue.main.async { [weak self] in
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)")
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
self?.backend.eofPlaybackModeAction()
}
}
2021-10-23 22:19:45 +05:30
}
private func shouldSkip(_ segment: Segment, at time: CMTime) -> Bool {
guard isPlaying,
!restoredSegments.contains(segment),
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)
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
withAnimation {
self?.lastSkipped = nil
2022-06-26 19:39:56 +05:30
self?.controls.objectWillChange.send()
}
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
}
}