Player controls UI changes

WIP on controls

Chapters

working

Add previews variable

Add lists ids

WIP
This commit is contained in:
Arkadiusz Fal
2022-06-18 14:39:49 +02:00
parent 9c98cf9558
commit 321c265a11
60 changed files with 2524 additions and 1320 deletions

View File

@@ -383,6 +383,8 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
id = videoID
}
let description = json["description"].stringValue
return Video(
id: id,
videoID: videoID,
@@ -391,7 +393,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
length: json["lengthSeconds"].doubleValue,
published: json["publishedText"].stringValue,
views: json["viewCount"].intValue,
description: json["description"].stringValue,
description: description,
genre: json["genre"].stringValue,
channel: extractChannel(from: json),
thumbnails: extractThumbnails(from: json),
@@ -403,7 +405,8 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
dislikes: json["dislikeCount"].int,
keywords: json["keywords"].arrayValue.compactMap { $0.string },
streams: extractStreams(from: json),
related: extractRelated(from: json)
related: extractRelated(from: json),
chapters: extractChapters(from: description)
)
}

View File

@@ -409,6 +409,13 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
let live = details["livestream"]?.bool ?? (details["duration"]?.int == -1)
let description = extractDescription(from: content) ?? ""
var chapters = extractChapters(from: content)
if chapters.isEmpty, !description.isEmpty {
chapters = extractChapters(from: description)
}
return Video(
videoID: extractID(from: content),
title: details["title"]?.string ?? "",
@@ -416,14 +423,15 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
length: details["duration"]?.double ?? 0,
published: published ?? "",
views: details["views"]?.int ?? 0,
description: extractDescription(from: content),
description: description,
channel: Channel(id: channelId, name: author, thumbnailURL: authorThumbnailURL, subscriptionsCount: subscriptionsCount),
thumbnails: thumbnails,
live: live,
likes: details["likes"]?.int,
dislikes: details["dislikes"]?.int,
streams: extractStreams(from: content),
related: extractRelated(from: content)
related: extractRelated(from: content),
chapters: extractChapters(from: content)
)
}
@@ -571,4 +579,21 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
channel: Channel(id: channelId, name: author)
)
}
private func extractChapters(from content: JSON) -> [Chapter] {
guard let chapters = content.dictionaryValue["chapters"]?.array else {
return .init()
}
return chapters.compactMap { chapter in
guard let title = chapter["title"].string,
let image = chapter["image"].url,
let start = chapter["start"].double
else {
return nil
}
return Chapter(title: title, image: image, start: start)
}
}
}

View File

@@ -116,4 +116,54 @@ extension VideosAPI {
return urlComponents.url
}
func extractChapters(from description: String) -> [Chapter] {
guard let chaptersRegularExpression = try? NSRegularExpression(
pattern: "(?<start>(?:[0-9]+:){1,}(?:[0-9]+))(?:\\s)+(?:- ?)?(?<title>.*)",
options: .caseInsensitive
) else { return [] }
let chapterLines = chaptersRegularExpression.matches(
in: description,
range: NSRange(description.startIndex..., in: description)
)
return chapterLines.compactMap { line in
let titleRange = line.range(withName: "title")
let startRange = line.range(withName: "start")
guard let titleSubstringRange = Range(titleRange, in: description),
let startSubstringRange = Range(startRange, in: description),
let titleCapture = String(description[titleSubstringRange]),
let startCapture = String(description[startSubstringRange]) else { return nil }
let startComponents = startCapture.components(separatedBy: ":")
guard startComponents.count <= 3 else { return nil }
var hours: Double?
var minutes: Double?
var seconds: Double?
if startComponents.count == 3 {
hours = Double(startComponents[0])
minutes = Double(startComponents[1])
seconds = Double(startComponents[2])
} else if startComponents.count == 2 {
minutes = Double(startComponents[0])
seconds = Double(startComponents[1])
}
guard var startSeconds = seconds else { return nil }
if let minutes = minutes {
startSeconds += 60 * minutes
}
if let hours = hours {
startSeconds += 60 * 60 * hours
}
return .init(title: titleCapture, start: startSeconds)
}
}
}