mirror of
https://github.com/yattee/yattee.git
synced 2024-11-10 00:08:21 +00:00
Aspect ratio improvements
This commit is contained in:
parent
5f858bc6d4
commit
1e21c50b5d
@ -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 = {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user