mirror of
https://github.com/yattee/yattee.git
synced 2024-11-10 08:18:19 +00:00
79 lines
2.1 KiB
Swift
79 lines
2.1 KiB
Swift
import Foundation
|
|
|
|
struct VideoURLParser {
|
|
let url: URL
|
|
|
|
var id: String? {
|
|
if urlComponents?.host == "youtu.be", let path = urlComponents?.path {
|
|
return String(path.suffix(from: path.index(path.startIndex, offsetBy: 1)))
|
|
}
|
|
|
|
return queryItemValue("v")
|
|
}
|
|
|
|
var time: TimeInterval? {
|
|
guard let time = queryItemValue("t") else {
|
|
return nil
|
|
}
|
|
|
|
let timeComponents = parseTime(time)
|
|
|
|
guard !timeComponents.isEmpty,
|
|
let hours = TimeInterval(timeComponents["hours"] ?? "0"),
|
|
let minutes = TimeInterval(timeComponents["minutes"] ?? "0"),
|
|
let seconds = TimeInterval(timeComponents["seconds"] ?? "0")
|
|
else {
|
|
if let time = TimeInterval(time) {
|
|
return time
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
return seconds + (minutes * 60) + (hours * 60 * 60)
|
|
}
|
|
|
|
func queryItemValue(_ name: String) -> String? {
|
|
queryItems.first { $0.name == name }?.value
|
|
}
|
|
|
|
private var queryItems: [URLQueryItem] {
|
|
urlComponents?.queryItems ?? []
|
|
}
|
|
|
|
private var urlComponents: URLComponents? {
|
|
URLComponents(url: url, resolvingAgainstBaseURL: false)
|
|
}
|
|
|
|
private func parseTime(_ time: String) -> [String: String] {
|
|
let results = timeRegularExpression.matches(
|
|
in: time,
|
|
range: NSRange(time.startIndex..., in: time)
|
|
)
|
|
|
|
guard let match = results.first else {
|
|
return [:]
|
|
}
|
|
|
|
var components: [String: String] = [:]
|
|
|
|
for name in ["hours", "minutes", "seconds"] {
|
|
let matchRange = match.range(withName: name)
|
|
|
|
if let substringRange = Range(matchRange, in: time) {
|
|
let capture = String(time[substringRange])
|
|
components[name] = capture
|
|
}
|
|
}
|
|
|
|
return components
|
|
}
|
|
|
|
private var timeRegularExpression: NSRegularExpression {
|
|
try! NSRegularExpression(
|
|
pattern: "(?:(?<hours>[0-9+])+h)?(?:(?<minutes>[0-9]+)m)?(?:(?<seconds>[0-9]*)s)?",
|
|
options: .caseInsensitive
|
|
)
|
|
}
|
|
}
|