Prefer VP9/WEBM over H.264/MP4 (fix #128)

This commit is contained in:
Arkadiusz Fal 2022-05-21 21:30:01 +02:00
parent acf9af936a
commit 0b274f92bd
2 changed files with 65 additions and 19 deletions

View File

@ -69,16 +69,33 @@ final class MPVBackend: PlayerBackend {
clientTimer.eventHandler = getClientUpdates clientTimer.eventHandler = getClientUpdates
} }
typealias AreInIncreasingOrder = (Stream, Stream) -> Bool
func bestPlayable(_ streams: [Stream], maxResolution: ResolutionSetting) -> Stream? { func bestPlayable(_ streams: [Stream], maxResolution: ResolutionSetting) -> Stream? {
streams streams
.filter { $0.kind == .adaptive && $0.resolution <= maxResolution.value } .filter { $0.kind == .adaptive && $0.resolution <= maxResolution.value }
.max { $0.resolution < $1.resolution } ?? .max { lhs, rhs in
let predicates: [AreInIncreasingOrder] = [
{ $0.format > $1.format },
{ $0.resolution < $1.resolution }
]
for predicate in predicates {
if !predicate(lhs, rhs), !predicate(rhs, lhs) {
continue
}
return predicate(lhs, rhs)
}
return false
} ??
streams.first { $0.kind == .hls } ?? streams.first { $0.kind == .hls } ??
streams.first streams.first
} }
func canPlay(_ stream: Stream) -> Bool { func canPlay(_ stream: Stream) -> Bool {
stream.resolution != .unknown && stream.format != "AV1" stream.resolution != .unknown && stream.format != .av1
} }
func playStream(_ stream: Stream, of video: Video, preservingTime: Bool, upgrading _: Bool) { func playStream(_ stream: Stream, of video: Video, preservingTime: Bool, upgrading _: Bool) {

View File

@ -79,6 +79,49 @@ class Stream: Equatable, Hashable, Identifiable {
} }
} }
enum Format: String, Comparable {
case webm
case avc1
case av1
case mp4
case unknown
private var sortOrder: Int {
switch self {
case .webm:
return 0
case .mp4:
return 1
case .avc1:
return 2
case .av1:
return 3
case .unknown:
return 4
}
}
static func < (lhs: Self, rhs: Self) -> Bool {
lhs.sortOrder < rhs.sortOrder
}
static func from(_ string: String) -> Self {
let lowercased = string.lowercased()
if lowercased.contains("webm") {
return .webm
} else if lowercased.contains("avc1") {
return .avc1
} else if lowercased.contains("av01") {
return .av1
} else if lowercased.contains("mpeg_4") || lowercased.contains("mp4") {
return .mp4
} else {
return .unknown
}
}
}
let id = UUID() let id = UUID()
var instance: Instance! var instance: Instance!
@ -88,6 +131,7 @@ class Stream: Equatable, Hashable, Identifiable {
var resolution: Resolution! var resolution: Resolution!
var kind: Kind! var kind: Kind!
var format: Format!
var encoding: String! var encoding: String!
var videoFormat: String! var videoFormat: String!
@ -109,7 +153,7 @@ class Stream: Equatable, Hashable, Identifiable {
self.resolution = resolution self.resolution = resolution
self.kind = kind self.kind = kind
self.encoding = encoding self.encoding = encoding
self.videoFormat = videoFormat format = .from(videoFormat ?? "")
} }
var quality: String { var quality: String {
@ -120,23 +164,8 @@ class Stream: Equatable, Hashable, Identifiable {
return kind == .hls ? "adaptive (HLS)" : "\(resolution.name)\(kind == .stream ? " (\(kind.rawValue))" : "")" return kind == .hls ? "adaptive (HLS)" : "\(resolution.name)\(kind == .stream ? " (\(kind.rawValue))" : "")"
} }
var format: String {
let lowercasedFormat = (videoFormat ?? "unknown").lowercased()
if lowercasedFormat.contains("webm") {
return "WEBM"
} else if lowercasedFormat.contains("avc1") {
return "avc1"
} else if lowercasedFormat.contains("av01") {
return "AV1"
} else if lowercasedFormat.contains("mpeg_4") || lowercasedFormat.contains("mp4") {
return "MP4"
} else {
return lowercasedFormat
}
}
var description: String { var description: String {
let formatString = format == "unknown" ? "" : " (\(format))" let formatString = format == .unknown ? "" : " (\(format.rawValue))"
return "\(quality)\(formatString) - \(instance?.description ?? "")" return "\(quality)\(formatString) - \(instance?.description ?? "")"
} }