Improve streams extraction

This commit is contained in:
Arkadiusz Fal
2022-06-17 12:52:10 +02:00
parent d3ef6806b4
commit db6eaf30df
3 changed files with 38 additions and 38 deletions

View File

@@ -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,11 +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
let videoCodec = videoStream.dictionaryValue["codec"]?.string ?? ""
if Self.disallowedVideoCodecs.contains(where: videoCodec.contains) {
return
}
let audioAsset = AVURLAsset(url: audioStream.dictionaryValue["url"]!.url!) let audioAsset = AVURLAsset(url: audioStream.dictionaryValue["url"]!.url!)
let videoAsset = AVURLAsset(url: videoStream.dictionaryValue["url"]!.url!) 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 {

View File

@@ -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"

View File

@@ -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