mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 10:44:06 +00:00
Add Sponsor Block and settings
This commit is contained in:
73
Model/SponsorBlock/SponsorBlockAPI.swift
Normal file
73
Model/SponsorBlock/SponsorBlockAPI.swift
Normal file
@@ -0,0 +1,73 @@
|
||||
import Alamofire
|
||||
import Defaults
|
||||
import Foundation
|
||||
import Logging
|
||||
import SwiftyJSON
|
||||
|
||||
final class SponsorBlockAPI: ObservableObject {
|
||||
let logger = Logger(label: "net.yattee.app.sb")
|
||||
|
||||
static let categories = ["sponsor", "selfpromo", "intro", "outro", "interaction", "music_offtopic"]
|
||||
|
||||
@Published var videoID: String?
|
||||
@Published var segments = [Segment]()
|
||||
|
||||
static func categoryDescription(_ name: String) -> String? {
|
||||
guard SponsorBlockAPI.categories.contains(name) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch name {
|
||||
case "selfpromo":
|
||||
return "Self-promotion"
|
||||
case "music_offtopic":
|
||||
return "Offtopic in Music Videos"
|
||||
default:
|
||||
return name.capitalized
|
||||
}
|
||||
}
|
||||
|
||||
func loadSegments(videoID: String) {
|
||||
guard !skipSegmentsURL.isNil, self.videoID != videoID else {
|
||||
return
|
||||
}
|
||||
|
||||
self.videoID = videoID
|
||||
|
||||
requestSegments()
|
||||
}
|
||||
|
||||
private func requestSegments() {
|
||||
guard let url = skipSegmentsURL else {
|
||||
return
|
||||
}
|
||||
|
||||
AF.request(url, parameters: parameters).responseJSON { response in
|
||||
switch response.result {
|
||||
case let .success(value):
|
||||
self.segments = JSON(value).arrayValue.map(SponsorBlockSegment.init).sorted { $0.end < $1.end }
|
||||
|
||||
self.logger.info("loaded \(self.segments.count) SponsorBlock segments")
|
||||
self.segments.forEach {
|
||||
self.logger.info("\($0.start) -> \($0.end)")
|
||||
}
|
||||
case let .failure(error):
|
||||
self.segments = []
|
||||
|
||||
self.logger.error("failed to load SponsorBlock segments: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var skipSegmentsURL: String? {
|
||||
let url = Defaults[.sponsorBlockInstance]
|
||||
return url.isEmpty ? nil : "\(url)/api/skipSegments"
|
||||
}
|
||||
|
||||
private var parameters: [String: String] {
|
||||
[
|
||||
"videoID": videoID!,
|
||||
"categories": JSON(SponsorBlockAPI.categories).rawString(String.Encoding.utf8)!
|
||||
]
|
||||
}
|
||||
}
|
24
Model/SponsorBlock/SponsorBlockSegment.swift
Normal file
24
Model/SponsorBlock/SponsorBlockSegment.swift
Normal file
@@ -0,0 +1,24 @@
|
||||
import Foundation
|
||||
import SwiftyJSON
|
||||
|
||||
final class SponsorBlockSegment: Segment {
|
||||
init(_ json: JSON) {
|
||||
super.init(
|
||||
category: json["category"].string!,
|
||||
segment: json["segment"].array!.map { $0.double! },
|
||||
uuid: json["UUID"].string!,
|
||||
videoDuration: json["videoDuration"].int!
|
||||
)
|
||||
}
|
||||
|
||||
override func title() -> String {
|
||||
switch category {
|
||||
case "selfpromo":
|
||||
return "self-promotion"
|
||||
case "music_offtopic":
|
||||
return "offtopic"
|
||||
default:
|
||||
return category
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user