diff --git a/Model/Player/Backends/AVPlayerBackend.swift b/Model/Player/Backends/AVPlayerBackend.swift index b7904bf7..1a411012 100644 --- a/Model/Player/Backends/AVPlayerBackend.swift +++ b/Model/Player/Backends/AVPlayerBackend.swift @@ -34,10 +34,13 @@ final class AVPlayerBackend: PlayerBackend { } var aspectRatio: Double { - #if os(tvOS) - VideoPlayerView.defaultAspectRatio + #if os(iOS) + guard let view = model?.playerLayerView else { return VideoPlayerView.defaultAspectRatio } + + let videoRect = view.playerLayer.videoRect + return videoRect.width / videoRect.height #else - controller?.aspectRatio ?? VideoPlayerView.defaultAspectRatio + VideoPlayerView.defaultAspectRatio #endif } @@ -306,36 +309,38 @@ final class AVPlayerBackend: PlayerBackend { try? AVAudioSession.sharedInstance().setActive(true) #endif - if self.isAutoplaying(self.model.playerItem!) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in - guard let self = self else { - return - } + self.setRate(self.model.currentRate) - if !preservingTime, - let segment = self.model.sponsorBlock.segments.first, - segment.start < 3, - self.model.lastSkipped.isNil - { - self.avPlayer.seek( - to: segment.endTime, - toleranceBefore: .secondsInDefaultTimescale(1), - toleranceAfter: .zero - ) { finished in - guard finished else { - return - } + guard let item = self.model.playerItem, self.isAutoplaying(item) else { return } - self.model.lastSkipped = segment - self.model.play() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in + guard let self = self else { + return + } + + self.model.aspectRatio = self.aspectRatio + + if !preservingTime, + let segment = self.model.sponsorBlock.segments.first, + segment.start < 3, + self.model.lastSkipped.isNil + { + self.avPlayer.seek( + to: segment.endTime, + toleranceBefore: .secondsInDefaultTimescale(1), + toleranceAfter: .zero + ) { finished in + guard finished else { + return } - } else { + + self.model.lastSkipped = segment self.model.play() } + } else { + self.model.play() } } - - self.setRate(self.model.currentRate) } let replaceItemAndSeek = { diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index e6fc3c1b..6332e337 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -204,9 +204,11 @@ final class MPVBackend: PlayerBackend { self.model.lastSkipped = segment self.play() + self.model.aspectRatio = self.aspectRatio } } else { self.play() + self.model.aspectRatio = self.aspectRatio } } } diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 1cd8cd10..a3477ebd 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -45,6 +45,7 @@ final class PlayerModel: ObservableObject { @Published var playerSize: CGSize = .zero { didSet { backend.setSize(playerSize.width, playerSize.height) }} + @Published var aspectRatio = VideoPlayerView.defaultAspectRatio @Published var stream: Stream? @Published var currentRate: Float = 1.0 { didSet { backend.setRate(currentRate) } } @@ -70,12 +71,6 @@ final class PlayerModel: ObservableObject { backend.setNeedsNetworkStateUpdates(true) }} - #if os(iOS) - @Published var motionManager: CMMotionManager! - @Published var lockedOrientation: UIInterfaceOrientation? - @Published var lastOrientation: UIInterfaceOrientation? - #endif - var accounts: AccountsModel var comments: CommentsModel var controls: PlayerControlsModel { didSet { @@ -487,6 +482,7 @@ final class PlayerModel: ObservableObject { currentItem = nil backend.closeItem() + aspectRatio = VideoPlayerView.defaultAspectRatio } func closePiP() { diff --git a/Shared/Player/AppleAVPlayerViewController.swift b/Shared/Player/AppleAVPlayerViewController.swift index 2a1a5cad..fb25b4ee 100644 --- a/Shared/Player/AppleAVPlayerViewController.swift +++ b/Shared/Player/AppleAVPlayerViewController.swift @@ -12,7 +12,7 @@ final class AppleAVPlayerViewController: UIViewController { let persistenceController = PersistenceController.shared - #if !os(tvOS) + #if os(iOS) var aspectRatio: Double? { let ratio = Double(playerView.videoBounds.width) / Double(playerView.videoBounds.height) diff --git a/Shared/Player/VideoDetailsPaddingModifier.swift b/Shared/Player/VideoDetailsPaddingModifier.swift index 089fa0b5..77ae70fe 100644 --- a/Shared/Player/VideoDetailsPaddingModifier.swift +++ b/Shared/Player/VideoDetailsPaddingModifier.swift @@ -5,33 +5,22 @@ struct VideoDetailsPaddingModifier: ViewModifier { static var defaultAdditionalDetailsPadding = 0.0 let playerSize: CGSize - let aspectRatio: Double? let minimumHeightLeft: Double let additionalPadding: Double let fullScreen: Bool init( playerSize: CGSize, - aspectRatio: Double? = nil, minimumHeightLeft: Double? = nil, additionalPadding: Double? = nil, fullScreen: Bool = false ) { self.playerSize = playerSize - self.aspectRatio = aspectRatio ?? VideoPlayerView.defaultAspectRatio self.minimumHeightLeft = minimumHeightLeft ?? VideoPlayerView.defaultMinimumHeightLeft self.additionalPadding = additionalPadding ?? Self.defaultAdditionalDetailsPadding self.fullScreen = fullScreen } - var usedAspectRatio: Double { - guard aspectRatio != nil else { - return VideoPlayerView.defaultAspectRatio - } - - return [aspectRatio!, VideoPlayerView.defaultAspectRatio].min()! - } - var playerHeight: Double { playerSize.height } diff --git a/Shared/Player/VideoPlayerSizeModifier.swift b/Shared/Player/VideoPlayerSizeModifier.swift index 1f979de1..f7cc76ac 100644 --- a/Shared/Player/VideoPlayerSizeModifier.swift +++ b/Shared/Player/VideoPlayerSizeModifier.swift @@ -33,18 +33,11 @@ struct VideoPlayerSizeModifier: ViewModifier { } var usedAspectRatio: Double { - guard aspectRatio != nil, aspectRatio != 0 else { + guard let aspectRatio = aspectRatio, aspectRatio != 0 else { return VideoPlayerView.defaultAspectRatio } - let ratio = [aspectRatio!, VideoPlayerView.defaultAspectRatio].min()! - let viewRatio = geometry.size.width / geometry.size.height - - #if os(iOS) - return verticalSizeClass == .regular ? ratio : viewRatio - #else - return ratio - #endif + return [aspectRatio, VideoPlayerView.defaultAspectRatio].min()! } var usedAspectRatioContentMode: ContentMode { diff --git a/Shared/Player/VideoPlayerView.swift b/Shared/Player/VideoPlayerView.swift index 448f63dd..8e79ac7f 100644 --- a/Shared/Player/VideoPlayerView.swift +++ b/Shared/Player/VideoPlayerView.swift @@ -188,7 +188,7 @@ struct VideoPlayerView: View { .modifier( VideoPlayerSizeModifier( geometry: geometry, - aspectRatio: player.backend.aspectRatio, + aspectRatio: player.aspectRatio, fullScreen: fullScreenLayout ) ) @@ -212,17 +212,17 @@ struct VideoPlayerView: View { guard drag > 0 else { return } - guard drag < 100 else { - player.hide() - return - } - viewVerticalOffset = drag } .onEnded { _ in if viewVerticalOffset > 100 { - player.backend.setNeedsDrawing(false) - player.hide() + if player.playingFullScreen { + viewVerticalOffset = 0 + player.exitFullScreen() + } else { + player.backend.setNeedsDrawing(false) + player.hide() + } } else { viewVerticalOffset = 0 player.backend.setNeedsDrawing(true) @@ -260,7 +260,6 @@ struct VideoPlayerView: View { .background(colorScheme == .dark ? Color.black : Color.white) .modifier(VideoDetailsPaddingModifier( playerSize: player.playerSize, - aspectRatio: player.backend.aspectRatio, fullScreen: fullScreenDetails )) } @@ -299,15 +298,6 @@ struct VideoPlayerView: View { switch player.activeBackend { case .mpv: player.mpvPlayerView - .overlay(GeometryReader { proxy in - Color.clear - .onAppear { - player.playerSize = proxy.size - } - .onChange(of: proxy.size) { _ in - player.playerSize = proxy.size - } - }) case .appleAVPlayer: player.avPlayerView #if os(iOS) @@ -323,6 +313,15 @@ struct VideoPlayerView: View { #endif } } + .overlay(GeometryReader { proxy in + Color.clear + .onAppear { + player.playerSize = proxy.size + } + .onChange(of: proxy.size) { _ in + player.playerSize = proxy.size + } + }) #if os(iOS) .padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0) #endif @@ -346,7 +345,7 @@ struct VideoPlayerView: View { guard fullScreenLayout else { return 0 } let idiom = UIDevice.current.userInterfaceIdiom - guard idiom == .pad else { return safeAreaInsets.top } + guard idiom == .pad else { return 0 } return safeAreaInsets.top.isZero ? safeAreaInsets.bottom : safeAreaInsets.top }