2021-06-14 18:05:02 +00:00
|
|
|
import AVFoundation
|
2021-09-25 08:18:22 +00:00
|
|
|
import Defaults
|
2021-06-14 18:05:02 +00:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
// swiftlint:disable:next final_class
|
2021-07-22 12:43:13 +00:00
|
|
|
class Stream: Equatable, Hashable {
|
2021-09-25 08:18:22 +00:00
|
|
|
enum ResolutionSetting: String, Defaults.Serializable, CaseIterable {
|
|
|
|
case hd720pFirstThenBest, hd1080p, hd720p, sd480p, sd360p, sd240p, sd144p
|
|
|
|
|
|
|
|
var value: Stream.Resolution {
|
|
|
|
switch self {
|
|
|
|
case .hd720pFirstThenBest:
|
|
|
|
return .hd720p
|
|
|
|
default:
|
|
|
|
return Stream.Resolution(rawValue: rawValue)!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var description: String {
|
|
|
|
switch self {
|
|
|
|
case .hd720pFirstThenBest:
|
|
|
|
return "Default: adaptive"
|
|
|
|
default:
|
|
|
|
return "\(value.height)p".replacingOccurrences(of: " ", with: "")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Resolution: String, CaseIterable, Comparable, Defaults.Serializable {
|
2021-07-22 12:43:13 +00:00
|
|
|
case hd1080p, hd720p, sd480p, sd360p, sd240p, sd144p
|
|
|
|
|
|
|
|
var height: Int {
|
|
|
|
Int(rawValue.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())!
|
|
|
|
}
|
|
|
|
|
|
|
|
static func from(resolution: String) -> Resolution? {
|
|
|
|
allCases.first { "\($0)".contains(resolution) }
|
|
|
|
}
|
|
|
|
|
|
|
|
static func < (lhs: Resolution, rhs: Resolution) -> Bool {
|
|
|
|
lhs.height < rhs.height
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Kind: String, Comparable {
|
|
|
|
case stream, adaptive
|
|
|
|
|
|
|
|
private var sortOrder: Int {
|
|
|
|
switch self {
|
|
|
|
case .stream:
|
|
|
|
return 0
|
|
|
|
case .adaptive:
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static func < (lhs: Kind, rhs: Kind) -> Bool {
|
|
|
|
lhs.sortOrder < rhs.sortOrder
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-14 18:05:02 +00:00
|
|
|
var audioAsset: AVURLAsset
|
|
|
|
var videoAsset: AVURLAsset
|
|
|
|
|
2021-07-22 12:43:13 +00:00
|
|
|
var resolution: Resolution
|
|
|
|
var kind: Kind
|
2021-06-14 18:05:02 +00:00
|
|
|
|
|
|
|
var encoding: String
|
|
|
|
|
2021-07-22 12:43:13 +00:00
|
|
|
init(audioAsset: AVURLAsset, videoAsset: AVURLAsset, resolution: Resolution, kind: Kind, encoding: String) {
|
2021-06-14 18:05:02 +00:00
|
|
|
self.audioAsset = audioAsset
|
|
|
|
self.videoAsset = videoAsset
|
|
|
|
self.resolution = resolution
|
2021-07-22 12:43:13 +00:00
|
|
|
self.kind = kind
|
2021-06-14 18:05:02 +00:00
|
|
|
self.encoding = encoding
|
|
|
|
}
|
|
|
|
|
|
|
|
var description: String {
|
|
|
|
"\(resolution.height)p"
|
|
|
|
}
|
|
|
|
|
2021-06-15 16:35:21 +00:00
|
|
|
var assets: [AVURLAsset] {
|
|
|
|
[audioAsset, videoAsset]
|
|
|
|
}
|
|
|
|
|
2021-07-22 12:43:13 +00:00
|
|
|
var oneMeaningfullAsset: Bool {
|
|
|
|
assets.dropFirst().allSatisfy { $0 == assets.first }
|
|
|
|
}
|
|
|
|
|
2021-06-15 16:35:21 +00:00
|
|
|
var assetsLoaded: Bool {
|
|
|
|
assets.allSatisfy { $0.statusOfValue(forKey: "playable", error: nil) == .loaded }
|
|
|
|
}
|
|
|
|
|
2021-06-15 21:21:57 +00:00
|
|
|
var loadedAssets: [AVURLAsset] {
|
|
|
|
assets.filter { $0.statusOfValue(forKey: "playable", error: nil) == .loaded }
|
|
|
|
}
|
|
|
|
|
2021-06-15 16:35:21 +00:00
|
|
|
func cancelLoadingAssets() {
|
|
|
|
assets.forEach { $0.cancelLoading() }
|
|
|
|
}
|
|
|
|
|
2021-06-14 18:05:02 +00:00
|
|
|
static func == (lhs: Stream, rhs: Stream) -> Bool {
|
2021-07-22 12:43:13 +00:00
|
|
|
lhs.resolution == rhs.resolution && lhs.kind == rhs.kind
|
|
|
|
}
|
|
|
|
|
|
|
|
func hash(into hasher: inout Hasher) {
|
|
|
|
hasher.combine(videoAsset.url)
|
2021-06-14 18:05:02 +00:00
|
|
|
}
|
|
|
|
}
|