mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Improve streams extraction
This commit is contained in:
parent
15cdde17a6
commit
e6e18de106
@ -4,6 +4,7 @@ import Siesta
|
|||||||
import SwiftyJSON
|
import SwiftyJSON
|
||||||
|
|
||||||
final class PipedAPI: Service, ObservableObject, VideosAPI {
|
final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||||
|
static var disallowedVideoCodecs = ["av01"]
|
||||||
static var authorizedEndpoints = ["subscriptions", "subscribe", "unsubscribe", "user/playlists"]
|
static var authorizedEndpoints = ["subscriptions", "subscribe", "unsubscribe", "user/playlists"]
|
||||||
|
|
||||||
@Published var account: Account!
|
@Published var account: Account!
|
||||||
@ -500,17 +501,19 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
|||||||
let videoStreams = content.dictionaryValue["videoStreams"]?.arrayValue ?? []
|
let videoStreams = content.dictionaryValue["videoStreams"]?.arrayValue ?? []
|
||||||
|
|
||||||
videoStreams.forEach { videoStream in
|
videoStreams.forEach { videoStream in
|
||||||
guard let audioAssetUrl = audioStream.dictionaryValue["url"]?.url,
|
let videoCodec = videoStream.dictionaryValue["codec"]?.string ?? ""
|
||||||
let videoAssetUrl = videoStream.dictionaryValue["url"]?.url
|
if Self.disallowedVideoCodecs.contains(where: videoCodec.contains) {
|
||||||
else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let audioAsset = AVURLAsset(url: audioAssetUrl)
|
let audioAsset = AVURLAsset(url: audioStream.dictionaryValue["url"]!.url!)
|
||||||
let videoAsset = AVURLAsset(url: videoAssetUrl)
|
let videoAsset = AVURLAsset(url: videoStream.dictionaryValue["url"]!.url!)
|
||||||
|
|
||||||
let videoOnly = videoStream.dictionaryValue["videoOnly"]?.boolValue ?? true
|
let videoOnly = videoStream.dictionaryValue["videoOnly"]?.boolValue ?? true
|
||||||
let resolution = Stream.Resolution.from(resolution: videoStream.dictionaryValue["quality"]!.stringValue)
|
let quality = videoStream.dictionaryValue["quality"]?.string ?? "unknown"
|
||||||
|
let qualityComponents = quality.components(separatedBy: "p")
|
||||||
|
let fps = Int(qualityComponents[1].isEmpty ? "30" : qualityComponents[1])
|
||||||
|
let resolution = Stream.Resolution.from(resolution: quality, fps: fps)
|
||||||
let videoFormat = videoStream.dictionaryValue["format"]?.stringValue
|
let videoFormat = videoStream.dictionaryValue["format"]?.stringValue
|
||||||
|
|
||||||
if videoOnly {
|
if videoOnly {
|
||||||
|
@ -5,32 +5,30 @@ import Foundation
|
|||||||
// swiftlint:disable:next final_class
|
// swiftlint:disable:next final_class
|
||||||
class Stream: Equatable, Hashable, Identifiable {
|
class Stream: Equatable, Hashable, Identifiable {
|
||||||
enum Resolution: String, CaseIterable, Comparable, Defaults.Serializable {
|
enum Resolution: String, CaseIterable, Comparable, Defaults.Serializable {
|
||||||
case hd4320p60
|
|
||||||
case hd4320p
|
|
||||||
case hd2160p60
|
case hd2160p60
|
||||||
case hd2160p50
|
case hd2160p50
|
||||||
case hd2160p48
|
case hd2160p48
|
||||||
case hd2160p
|
case hd2160p30
|
||||||
case hd1440p60
|
case hd1440p60
|
||||||
case hd1440p50
|
case hd1440p50
|
||||||
case hd1440p48
|
case hd1440p48
|
||||||
case hd1440p
|
case hd1440p30
|
||||||
case hd1080p60
|
case hd1080p60
|
||||||
case hd1080p50
|
case hd1080p50
|
||||||
case hd1080p48
|
case hd1080p48
|
||||||
case hd1080p
|
case hd1080p30
|
||||||
case hd720p60
|
case hd720p60
|
||||||
case hd720p50
|
case hd720p50
|
||||||
case hd720p48
|
case hd720p48
|
||||||
case hd720p
|
case hd720p30
|
||||||
case sd480p
|
case sd480p30
|
||||||
case sd360p
|
case sd360p30
|
||||||
case sd240p
|
case sd240p30
|
||||||
case sd144p
|
case sd144p30
|
||||||
case unknown
|
case unknown
|
||||||
|
|
||||||
var name: String {
|
var name: String {
|
||||||
"\(height)p\(refreshRate != -1 ? ", \(refreshRate) fps" : "")"
|
"\(height)p\(refreshRate != -1 && refreshRate != 30 ? ", \(refreshRate) fps" : "")"
|
||||||
}
|
}
|
||||||
|
|
||||||
var height: Int {
|
var height: Int {
|
||||||
@ -48,11 +46,16 @@ class Stream: Equatable, Hashable, Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let refreshRatePart = rawValue.components(separatedBy: "p")[1]
|
let refreshRatePart = rawValue.components(separatedBy: "p")[1]
|
||||||
|
|
||||||
|
if refreshRatePart.isEmpty {
|
||||||
|
return 30
|
||||||
|
}
|
||||||
|
|
||||||
return Int(refreshRatePart.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()) ?? -1
|
return Int(refreshRatePart.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()) ?? -1
|
||||||
}
|
}
|
||||||
|
|
||||||
static func from(resolution: String) -> Resolution {
|
static func from(resolution: String, fps: Int? = nil) -> Resolution {
|
||||||
allCases.first { "\($0)".contains(resolution) } ?? .unknown
|
allCases.first { $0.rawValue.contains(resolution) && $0.refreshRate == (fps ?? 30) } ?? .unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
static func < (lhs: Resolution, rhs: Resolution) -> Bool {
|
static func < (lhs: Resolution, rhs: Resolution) -> Bool {
|
||||||
@ -157,7 +160,7 @@ class Stream: Equatable, Hashable, Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var quality: String {
|
var quality: String {
|
||||||
if resolution == .hd2160p {
|
if resolution == .hd2160p30 {
|
||||||
return "4K (2160p)"
|
return "4K (2160p)"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,13 +168,7 @@ class Stream: Equatable, Hashable, Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var shortQuality: String {
|
var shortQuality: String {
|
||||||
if resolution == .hd4320p60 || resolution == .hd4320p {
|
if resolution.height == 2160 {
|
||||||
return "8K"
|
|
||||||
} else if resolution == .hd2160p60 ||
|
|
||||||
resolution == .hd2160p50 ||
|
|
||||||
resolution == .hd2160p48 ||
|
|
||||||
resolution == .hd2160p
|
|
||||||
{
|
|
||||||
return "4K"
|
return "4K"
|
||||||
} else if kind == .hls {
|
} else if kind == .hls {
|
||||||
return "HLS"
|
return "HLS"
|
||||||
|
@ -93,25 +93,23 @@ extension Defaults.Keys {
|
|||||||
|
|
||||||
enum ResolutionSetting: String, CaseIterable, Defaults.Serializable {
|
enum ResolutionSetting: String, CaseIterable, Defaults.Serializable {
|
||||||
case best
|
case best
|
||||||
case hd4320p60
|
|
||||||
case hd4320p
|
|
||||||
case hd2160p60
|
case hd2160p60
|
||||||
case hd2160p
|
case hd2160p30
|
||||||
case hd1440p60
|
case hd1440p60
|
||||||
case hd1440p
|
case hd1440p30
|
||||||
case hd1080p60
|
case hd1080p60
|
||||||
case hd1080p
|
case hd1080p30
|
||||||
case hd720p60
|
case hd720p60
|
||||||
case hd720p
|
case hd720p30
|
||||||
case sd480p
|
case sd480p30
|
||||||
case sd360p
|
case sd360p30
|
||||||
case sd240p
|
case sd240p30
|
||||||
case sd144p
|
case sd144p30
|
||||||
|
|
||||||
var value: Stream.Resolution {
|
var value: Stream.Resolution {
|
||||||
switch self {
|
switch self {
|
||||||
case .best:
|
case .best:
|
||||||
return .hd4320p60
|
return .hd2160p60
|
||||||
default:
|
default:
|
||||||
return Stream.Resolution(rawValue: rawValue)!
|
return Stream.Resolution(rawValue: rawValue)!
|
||||||
}
|
}
|
||||||
@ -121,13 +119,9 @@ enum ResolutionSetting: String, CaseIterable, Defaults.Serializable {
|
|||||||
switch self {
|
switch self {
|
||||||
case .best:
|
case .best:
|
||||||
return "Best available quality"
|
return "Best available quality"
|
||||||
case .hd4320p60:
|
|
||||||
return "8K, 60fps"
|
|
||||||
case .hd4320p:
|
|
||||||
return "8K"
|
|
||||||
case .hd2160p60:
|
case .hd2160p60:
|
||||||
return "4K, 60fps"
|
return "4K, 60fps"
|
||||||
case .hd2160p:
|
case .hd2160p30:
|
||||||
return "4K"
|
return "4K"
|
||||||
default:
|
default:
|
||||||
return value.name
|
return value.name
|
||||||
|
Loading…
Reference in New Issue
Block a user