fix: clip metadata intervals to playable duration
This commit is contained in:
@@ -4,8 +4,8 @@ import CoreFoundation
|
||||
struct MiruroInterval: Sendable, Equatable {
|
||||
enum Kind: Sendable { case intro, outro }
|
||||
let kind: Kind
|
||||
let start: Double
|
||||
let end: Double
|
||||
var start: Double
|
||||
var end: Double
|
||||
let episode: Int
|
||||
var rawKind: String = ""
|
||||
var provider: String? = nil
|
||||
@@ -20,13 +20,16 @@ struct MiruroMetadata: Sendable {
|
||||
func visibleIntervals(episode: Int, duration: Double) -> [MiruroInterval] {
|
||||
guard duration.isFinite, duration > 0 else { return [] }
|
||||
var intro: MiruroInterval?, outro: MiruroInterval?
|
||||
for row in intervals {
|
||||
for var row in intervals {
|
||||
guard row.episode == episode, row.start.isFinite, row.end.isFinite,
|
||||
row.start >= 0, row.end > row.start, row.end <= duration,
|
||||
row.end > row.start,
|
||||
!(row.provider?.range(of: "crunchyroll", options: .caseInsensitive) != nil),
|
||||
(row.votes ?? 0).isFinite, (row.votes ?? 0) >= 0 else { continue }
|
||||
if let length = row.referenceLength, length.isFinite, length > 0,
|
||||
abs(length - duration) / duration > 0.05 { continue }
|
||||
row.start = max(0, row.start)
|
||||
row.end = min(duration, row.end)
|
||||
guard row.end > row.start else { continue }
|
||||
// Strictly greater preserves input order on ties, equivalent to stable descending votes.
|
||||
switch row.kind {
|
||||
case .intro:
|
||||
|
||||
@@ -1614,8 +1614,10 @@ final class PlayerModel: ObservableObject {
|
||||
precondition(lifecycle.accept(metadata, identity: a, generation: first), "Current metadata is accepted")
|
||||
precondition(lifecycle.visibleIntervals(duration: 0).isEmpty, "Unknown duration hides bands")
|
||||
precondition(lifecycle.visibleIntervals(duration: 100).count == 2, "Actual duration permits exact-end bands")
|
||||
precondition(lifecycle.visibleIntervals(duration: 95).count == 1, "Duration shrink revalidates raw bands")
|
||||
precondition(lifecycle.visibleIntervals(duration: 100).count == 2, "Duration growth restores raw bands")
|
||||
precondition(lifecycle.visibleIntervals(duration: 95) == [
|
||||
metadata.intervals[0], MiruroInterval(kind: .outro, start: 90, end: 95, episode: 1)
|
||||
], "Duration shrink clips raw bands")
|
||||
precondition(lifecycle.visibleIntervals(duration: 100) == metadata.intervals, "Duration growth restores raw bands")
|
||||
_ = lifecycle.replace(identity: b, episode: 2)
|
||||
precondition(lifecycle.metadata == nil, "Replacement clears title and intervals")
|
||||
precondition(!lifecycle.accept(metadata, identity: a, generation: first), "Different-identity result is stale")
|
||||
|
||||
Reference in New Issue
Block a user