From 33377f7e0ed3aad63bab4391bb1cafabdb99bc50 Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Wed, 19 Nov 2025 18:03:43 +0100 Subject: [PATCH] Fix nil crash when accessing stream.format This commit addresses crashes caused by accessing nil format values on streams: - QualityProfile.swift: Add guard check for stream.format to prevent nil access crash - MPVBackend.swift: Add nil check in canPlay method before comparing format - PlayerStreams.swift: Add nil check before comparing format in asset processing The crashes occurred when stream.format was nil and accessed as an implicitly unwrapped optional, causing "Unexpectedly found nil while implicitly unwrapping an Optional value" errors. --- Model/Player/Backends/MPVBackend.swift | 2 +- Model/Player/PlayerStreams.swift | 2 +- Model/QualityProfile.swift | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index e67da018..c3a28409 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -220,7 +220,7 @@ final class MPVBackend: PlayerBackend { typealias AreInIncreasingOrder = (Stream, Stream) -> Bool func canPlay(_ stream: Stream) -> Bool { - stream.format != .av1 + stream.format != nil && stream.format != .av1 } func playStream(_ stream: Stream, of video: Video, preservingTime: Bool, upgrading: Bool) { diff --git a/Model/Player/PlayerStreams.swift b/Model/Player/PlayerStreams.swift index 74ebe008..1712a753 100644 --- a/Model/Player/PlayerStreams.swift +++ b/Model/Player/PlayerStreams.swift @@ -73,7 +73,7 @@ extension PlayerModel { for stream in streams { streamProcessingQueue.async(group: streamProcessingGroup) { let forbiddenAssetTestGroup = DispatchGroup() - if !hasAllowedAsset, !hasForbiddenAsset, !instance.proxiesVideos, stream.format != Stream.Format.unknown { + if !hasAllowedAsset, !hasForbiddenAsset, !instance.proxiesVideos, stream.format != nil && stream.format != Stream.Format.unknown { let (nonHLSAssets, hlsURLs) = self.getAssets(from: [stream]) if let firstStream = nonHLSAssets.first { let asset = firstStream.0 diff --git a/Model/QualityProfile.swift b/Model/QualityProfile.swift index 178da97d..8fe633f8 100644 --- a/Model/QualityProfile.swift +++ b/Model/QualityProfile.swift @@ -81,6 +81,11 @@ struct QualityProfile: Hashable, Identifiable, Defaults.Serializable { return false } + // Safety check: Ensure stream has a format + guard let streamFormat = stream.format else { + return false + } + let defaultResolution = Stream.Resolution.custom(height: 720, refreshRate: 30) let resolutionMatch = resolution.value ?? defaultResolution >= streamResolution @@ -88,7 +93,7 @@ struct QualityProfile: Hashable, Identifiable, Defaults.Serializable { return true } - let formatMatch = formats.compactMap(\.streamFormat).contains(stream.format) + let formatMatch = formats.compactMap(\.streamFormat).contains(streamFormat) return resolutionMatch && formatMatch }