Aspect ratio improvements

This commit is contained in:
Arkadiusz Fal 2022-07-10 03:15:15 +02:00
parent 5f858bc6d4
commit 1e21c50b5d
7 changed files with 56 additions and 72 deletions

View File

@ -34,10 +34,13 @@ final class AVPlayerBackend: PlayerBackend {
} }
var aspectRatio: Double { var aspectRatio: Double {
#if os(tvOS) #if os(iOS)
VideoPlayerView.defaultAspectRatio guard let view = model?.playerLayerView else { return VideoPlayerView.defaultAspectRatio }
let videoRect = view.playerLayer.videoRect
return videoRect.width / videoRect.height
#else #else
controller?.aspectRatio ?? VideoPlayerView.defaultAspectRatio VideoPlayerView.defaultAspectRatio
#endif #endif
} }
@ -306,36 +309,38 @@ final class AVPlayerBackend: PlayerBackend {
try? AVAudioSession.sharedInstance().setActive(true) try? AVAudioSession.sharedInstance().setActive(true)
#endif #endif
if self.isAutoplaying(self.model.playerItem!) { self.setRate(self.model.currentRate)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
guard let self = self else {
return
}
if !preservingTime, guard let item = self.model.playerItem, self.isAutoplaying(item) else { return }
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
}
self.model.lastSkipped = segment DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
self.model.play() 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() self.model.play()
} }
} else {
self.model.play()
} }
} }
self.setRate(self.model.currentRate)
} }
let replaceItemAndSeek = { let replaceItemAndSeek = {

View File

@ -204,9 +204,11 @@ final class MPVBackend: PlayerBackend {
self.model.lastSkipped = segment self.model.lastSkipped = segment
self.play() self.play()
self.model.aspectRatio = self.aspectRatio
} }
} else { } else {
self.play() self.play()
self.model.aspectRatio = self.aspectRatio
} }
} }
} }

View File

@ -45,6 +45,7 @@ final class PlayerModel: ObservableObject {
@Published var playerSize: CGSize = .zero { didSet { @Published var playerSize: CGSize = .zero { didSet {
backend.setSize(playerSize.width, playerSize.height) backend.setSize(playerSize.width, playerSize.height)
}} }}
@Published var aspectRatio = VideoPlayerView.defaultAspectRatio
@Published var stream: Stream? @Published var stream: Stream?
@Published var currentRate: Float = 1.0 { didSet { backend.setRate(currentRate) } } @Published var currentRate: Float = 1.0 { didSet { backend.setRate(currentRate) } }
@ -70,12 +71,6 @@ final class PlayerModel: ObservableObject {
backend.setNeedsNetworkStateUpdates(true) backend.setNeedsNetworkStateUpdates(true)
}} }}
#if os(iOS)
@Published var motionManager: CMMotionManager!
@Published var lockedOrientation: UIInterfaceOrientation?
@Published var lastOrientation: UIInterfaceOrientation?
#endif
var accounts: AccountsModel var accounts: AccountsModel
var comments: CommentsModel var comments: CommentsModel
var controls: PlayerControlsModel { didSet { var controls: PlayerControlsModel { didSet {
@ -487,6 +482,7 @@ final class PlayerModel: ObservableObject {
currentItem = nil currentItem = nil
backend.closeItem() backend.closeItem()
aspectRatio = VideoPlayerView.defaultAspectRatio
} }
func closePiP() { func closePiP() {

View File

@ -12,7 +12,7 @@ final class AppleAVPlayerViewController: UIViewController {
let persistenceController = PersistenceController.shared let persistenceController = PersistenceController.shared
#if !os(tvOS) #if os(iOS)
var aspectRatio: Double? { var aspectRatio: Double? {
let ratio = Double(playerView.videoBounds.width) / Double(playerView.videoBounds.height) let ratio = Double(playerView.videoBounds.width) / Double(playerView.videoBounds.height)

View File

@ -5,33 +5,22 @@ struct VideoDetailsPaddingModifier: ViewModifier {
static var defaultAdditionalDetailsPadding = 0.0 static var defaultAdditionalDetailsPadding = 0.0
let playerSize: CGSize let playerSize: CGSize
let aspectRatio: Double?
let minimumHeightLeft: Double let minimumHeightLeft: Double
let additionalPadding: Double let additionalPadding: Double
let fullScreen: Bool let fullScreen: Bool
init( init(
playerSize: CGSize, playerSize: CGSize,
aspectRatio: Double? = nil,
minimumHeightLeft: Double? = nil, minimumHeightLeft: Double? = nil,
additionalPadding: Double? = nil, additionalPadding: Double? = nil,
fullScreen: Bool = false fullScreen: Bool = false
) { ) {
self.playerSize = playerSize self.playerSize = playerSize
self.aspectRatio = aspectRatio ?? VideoPlayerView.defaultAspectRatio
self.minimumHeightLeft = minimumHeightLeft ?? VideoPlayerView.defaultMinimumHeightLeft self.minimumHeightLeft = minimumHeightLeft ?? VideoPlayerView.defaultMinimumHeightLeft
self.additionalPadding = additionalPadding ?? Self.defaultAdditionalDetailsPadding self.additionalPadding = additionalPadding ?? Self.defaultAdditionalDetailsPadding
self.fullScreen = fullScreen self.fullScreen = fullScreen
} }
var usedAspectRatio: Double {
guard aspectRatio != nil else {
return VideoPlayerView.defaultAspectRatio
}
return [aspectRatio!, VideoPlayerView.defaultAspectRatio].min()!
}
var playerHeight: Double { var playerHeight: Double {
playerSize.height playerSize.height
} }

View File

@ -33,18 +33,11 @@ struct VideoPlayerSizeModifier: ViewModifier {
} }
var usedAspectRatio: Double { var usedAspectRatio: Double {
guard aspectRatio != nil, aspectRatio != 0 else { guard let aspectRatio = aspectRatio, aspectRatio != 0 else {
return VideoPlayerView.defaultAspectRatio return VideoPlayerView.defaultAspectRatio
} }
let ratio = [aspectRatio!, VideoPlayerView.defaultAspectRatio].min()! return [aspectRatio, VideoPlayerView.defaultAspectRatio].min()!
let viewRatio = geometry.size.width / geometry.size.height
#if os(iOS)
return verticalSizeClass == .regular ? ratio : viewRatio
#else
return ratio
#endif
} }
var usedAspectRatioContentMode: ContentMode { var usedAspectRatioContentMode: ContentMode {

View File

@ -188,7 +188,7 @@ struct VideoPlayerView: View {
.modifier( .modifier(
VideoPlayerSizeModifier( VideoPlayerSizeModifier(
geometry: geometry, geometry: geometry,
aspectRatio: player.backend.aspectRatio, aspectRatio: player.aspectRatio,
fullScreen: fullScreenLayout fullScreen: fullScreenLayout
) )
) )
@ -212,17 +212,17 @@ struct VideoPlayerView: View {
guard drag > 0 else { return } guard drag > 0 else { return }
guard drag < 100 else {
player.hide()
return
}
viewVerticalOffset = drag viewVerticalOffset = drag
} }
.onEnded { _ in .onEnded { _ in
if viewVerticalOffset > 100 { if viewVerticalOffset > 100 {
player.backend.setNeedsDrawing(false) if player.playingFullScreen {
player.hide() viewVerticalOffset = 0
player.exitFullScreen()
} else {
player.backend.setNeedsDrawing(false)
player.hide()
}
} else { } else {
viewVerticalOffset = 0 viewVerticalOffset = 0
player.backend.setNeedsDrawing(true) player.backend.setNeedsDrawing(true)
@ -260,7 +260,6 @@ struct VideoPlayerView: View {
.background(colorScheme == .dark ? Color.black : Color.white) .background(colorScheme == .dark ? Color.black : Color.white)
.modifier(VideoDetailsPaddingModifier( .modifier(VideoDetailsPaddingModifier(
playerSize: player.playerSize, playerSize: player.playerSize,
aspectRatio: player.backend.aspectRatio,
fullScreen: fullScreenDetails fullScreen: fullScreenDetails
)) ))
} }
@ -299,15 +298,6 @@ struct VideoPlayerView: View {
switch player.activeBackend { switch player.activeBackend {
case .mpv: case .mpv:
player.mpvPlayerView player.mpvPlayerView
.overlay(GeometryReader { proxy in
Color.clear
.onAppear {
player.playerSize = proxy.size
}
.onChange(of: proxy.size) { _ in
player.playerSize = proxy.size
}
})
case .appleAVPlayer: case .appleAVPlayer:
player.avPlayerView player.avPlayerView
#if os(iOS) #if os(iOS)
@ -323,6 +313,15 @@ struct VideoPlayerView: View {
#endif #endif
} }
} }
.overlay(GeometryReader { proxy in
Color.clear
.onAppear {
player.playerSize = proxy.size
}
.onChange(of: proxy.size) { _ in
player.playerSize = proxy.size
}
})
#if os(iOS) #if os(iOS)
.padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0) .padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0)
#endif #endif
@ -346,7 +345,7 @@ struct VideoPlayerView: View {
guard fullScreenLayout else { return 0 } guard fullScreenLayout else { return 0 }
let idiom = UIDevice.current.userInterfaceIdiom 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 return safeAreaInsets.top.isZero ? safeAreaInsets.bottom : safeAreaInsets.top
} }