diff --git a/Gifski.xcodeproj/project.pbxproj b/Gifski.xcodeproj/project.pbxproj index e717fb5c..5c113c4b 100644 --- a/Gifski.xcodeproj/project.pbxproj +++ b/Gifski.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 53; objects = { /* Begin PBXBuildFile section */ @@ -342,7 +342,7 @@ }; }; buildConfigurationList = E3AE627E1E5CD2F300035A2F /* Build configuration list for PBXProject "Gifski" */; - compatibilityVersion = "Xcode 11.0"; + compatibilityVersion = "Xcode 11.4"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -700,7 +700,6 @@ E3AE62911E5CD2F300035A2F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Gifski/Gifski.entitlements; @@ -724,12 +723,6 @@ "$(inherited)", /usr/local/opt/gcc/lib/gcc/9, ); - OTHER_LDFLAGS = ( - "-weak_framework", - Combine, - "-weak_framework", - SwiftUI, - ); PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.Gifski; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -744,7 +737,6 @@ E3AE62921E5CD2F300035A2F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Gifski/Gifski.entitlements; @@ -768,12 +760,6 @@ "$(inherited)", /usr/local/opt/gcc/lib/gcc/9, ); - OTHER_LDFLAGS = ( - "-weak_framework", - Combine, - "-weak_framework", - SwiftUI, - ); PRODUCT_BUNDLE_IDENTIFIER = com.sindresorhus.Gifski; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Gifski/VideoValidator.swift b/Gifski/VideoValidator.swift index a0593d28..0cd914e1 100644 --- a/Gifski/VideoValidator.swift +++ b/Gifski/VideoValidator.swift @@ -32,7 +32,12 @@ struct VideoValidator { return .failure } - let asset = AVURLAsset(url: inputUrl) + let asset = AVURLAsset( + url: inputUrl, + options: [ + AVURLAssetPreferPreciseDurationAndTimingKey: true + ] + ) Crashlytics.record(key: "AVAsset debug info", value: asset.debugInfo) diff --git a/Gifski/util.swift b/Gifski/util.swift index 58ffbc33..df145756 100644 --- a/Gifski/util.swift +++ b/Gifski/util.swift @@ -885,7 +885,7 @@ extension AVAsset { Extension: \(describing: (self as? AVURLAsset)?.url.fileExtension) Video codec: \(describing: videoCodec?.debugDescription) Audio codec: \(describing: audioCodec) - Duration: \(describing: durationFormatter.string(from: duration.seconds)) + Duration: \(describing: durationFormatter.stringSafe(from: duration.seconds)) Dimension: \(describing: dimensions?.formatted) Frame rate: \(describing: frameRate?.rounded(toDecimalPlaces: 2).formatted) File size: \(fileSizeFormatted) @@ -903,7 +903,7 @@ extension AVAsset { ---- Type: \(track.mediaType.debugDescription) Codec: \(describing: track.mediaType == .video ? track.codec?.debugDescription : track.codecString) - Duration: \(describing: durationFormatter.string(from: track.timeRange.duration.seconds)) + Duration: \(describing: durationFormatter.stringSafe(from: track.timeRange.duration.seconds)) Dimensions: \(describing: track.dimensions?.formatted) Natural size: \(describing: track.naturalSize) Frame rate: \(describing: track.frameRate?.rounded(toDecimalPlaces: 2).formatted) @@ -3023,3 +3023,20 @@ extension AVPlayer { } } } + + +extension DateComponentsFormatter { + /// Like `string(from: TimeInterval)` but does not cause an `NSInternalInconsistencyException` exception for `NaN` and `Infinity`. + /// This is especially useful when formatting `CMTime#seconds` which can often be `NaN`. + func stringSafe(from timeInterval: TimeInterval) -> String? { + guard !timeInterval.isNaN else { + return "NaN" + } + + guard timeInterval.isFinite else { + return "Infinity" + } + + return string(from: timeInterval) + } +}