2021-07-19 04:02:46 +05:30
|
|
|
import AVKit
|
2021-10-06 01:50:09 +05:30
|
|
|
import Defaults
|
2021-07-19 04:02:46 +05:30
|
|
|
import Siesta
|
|
|
|
import SwiftUI
|
|
|
|
|
|
|
|
struct VideoPlayerView: View {
|
2021-09-19 02:06:42 +05:30
|
|
|
static let defaultAspectRatio: Double = 1.77777778
|
|
|
|
static var defaultMinimumHeightLeft: Double {
|
2021-08-23 00:43:33 +05:30
|
|
|
#if os(macOS)
|
|
|
|
300
|
|
|
|
#else
|
|
|
|
200
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
@State private var fullScreen = false
|
2021-07-19 04:02:46 +05:30
|
|
|
|
2021-08-23 00:43:33 +05:30
|
|
|
#if os(iOS)
|
2021-10-06 01:50:09 +05:30
|
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
2021-08-23 00:43:33 +05:30
|
|
|
@Environment(\.verticalSizeClass) private var verticalSizeClass
|
2021-11-02 03:26:18 +05:30
|
|
|
|
|
|
|
private var idiom: UIUserInterfaceIdiom {
|
|
|
|
UIDevice.current.userInterfaceIdiom
|
|
|
|
}
|
2021-08-23 00:43:33 +05:30
|
|
|
#endif
|
2021-08-17 04:16:18 +05:30
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
@EnvironmentObject<PlayerModel> private var player
|
2021-09-25 13:48:22 +05:30
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
var body: some View {
|
|
|
|
#if os(macOS)
|
|
|
|
HSplitView {
|
|
|
|
content
|
|
|
|
}
|
|
|
|
.frame(idealWidth: 1000, maxWidth: 1100, minHeight: 700)
|
|
|
|
#else
|
|
|
|
HStack(spacing: 0) {
|
|
|
|
content
|
|
|
|
}
|
|
|
|
#if os(iOS)
|
|
|
|
.navigationBarHidden(true)
|
|
|
|
#endif
|
|
|
|
#endif
|
2021-07-19 04:02:46 +05:30
|
|
|
}
|
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
var content: some View {
|
|
|
|
Group {
|
2021-10-28 22:44:55 +05:30
|
|
|
Group {
|
2021-10-06 01:50:09 +05:30
|
|
|
#if os(tvOS)
|
2021-10-28 22:44:55 +05:30
|
|
|
player.playerView
|
2021-10-06 01:50:09 +05:30
|
|
|
#else
|
|
|
|
GeometryReader { geometry in
|
|
|
|
VStack(spacing: 0) {
|
|
|
|
#if os(iOS)
|
|
|
|
if verticalSizeClass == .regular {
|
|
|
|
PlaybackBar()
|
|
|
|
}
|
|
|
|
#elseif os(macOS)
|
|
|
|
PlaybackBar()
|
|
|
|
#endif
|
2021-07-19 04:02:46 +05:30
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
if player.currentItem.isNil {
|
|
|
|
playerPlaceholder(geometry: geometry)
|
|
|
|
} else {
|
2021-10-28 22:44:55 +05:30
|
|
|
player.playerView
|
|
|
|
.modifier(VideoPlayerSizeModifier(geometry: geometry))
|
2021-08-23 00:43:33 +05:30
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
}
|
2021-08-23 00:43:33 +05:30
|
|
|
#if os(iOS)
|
2021-10-06 01:50:09 +05:30
|
|
|
.onSwipeGesture(
|
|
|
|
up: {
|
|
|
|
withAnimation {
|
|
|
|
fullScreen = true
|
2021-08-23 00:43:33 +05:30
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
},
|
|
|
|
down: { dismiss() }
|
|
|
|
)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
.background(.black)
|
|
|
|
|
|
|
|
Group {
|
|
|
|
#if os(iOS)
|
|
|
|
if verticalSizeClass == .regular {
|
|
|
|
VideoDetails(sidebarQueue: sidebarQueueBinding, fullScreen: $fullScreen)
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
VideoDetails(fullScreen: $fullScreen)
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
.background()
|
|
|
|
.modifier(VideoDetailsPaddingModifier(geometry: geometry, fullScreen: fullScreen))
|
2021-08-23 00:43:33 +05:30
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#if os(macOS)
|
|
|
|
.frame(minWidth: 650)
|
|
|
|
#endif
|
|
|
|
#if os(iOS)
|
|
|
|
if sidebarQueue {
|
|
|
|
PlayerQueueView(fullScreen: $fullScreen)
|
|
|
|
.frame(maxWidth: 350)
|
2021-07-19 04:02:46 +05:30
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
#elseif os(macOS)
|
|
|
|
PlayerQueueView(fullScreen: $fullScreen)
|
|
|
|
.frame(minWidth: 250)
|
2021-07-19 04:02:46 +05:30
|
|
|
#endif
|
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
func playerPlaceholder(geometry: GeometryProxy) -> some View {
|
|
|
|
HStack {
|
|
|
|
Spacer()
|
|
|
|
VStack {
|
|
|
|
Spacer()
|
|
|
|
VStack(spacing: 10) {
|
|
|
|
#if !os(tvOS)
|
|
|
|
Image(systemName: "ticket")
|
2021-10-20 02:57:04 +05:30
|
|
|
.font(.system(size: 120))
|
2021-10-06 01:50:09 +05:30
|
|
|
#endif
|
|
|
|
}
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
.foregroundColor(.gray)
|
|
|
|
Spacer()
|
2021-07-19 04:02:46 +05:30
|
|
|
}
|
2021-10-06 01:50:09 +05:30
|
|
|
.contentShape(Rectangle())
|
|
|
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: geometry.size.width / VideoPlayerView.defaultAspectRatio)
|
2021-07-19 04:02:46 +05:30
|
|
|
}
|
2021-08-23 00:43:33 +05:30
|
|
|
|
2021-10-06 01:50:09 +05:30
|
|
|
#if os(iOS)
|
|
|
|
var sidebarQueue: Bool {
|
2021-11-02 03:26:18 +05:30
|
|
|
horizontalSizeClass == .regular && idiom == .pad
|
2021-10-06 01:50:09 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
var sidebarQueueBinding: Binding<Bool> {
|
|
|
|
Binding(
|
|
|
|
get: { self.sidebarQueue },
|
|
|
|
set: { _ in }
|
|
|
|
)
|
|
|
|
}
|
|
|
|
#endif
|
2021-08-23 00:43:33 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
struct VideoPlayerView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
2021-10-06 01:50:09 +05:30
|
|
|
VideoPlayerView()
|
|
|
|
.injectFixtureEnvironmentObjects()
|
|
|
|
|
|
|
|
VideoPlayerView()
|
|
|
|
.injectFixtureEnvironmentObjects()
|
|
|
|
.previewInterfaceOrientation(.landscapeRight)
|
2021-08-23 00:43:33 +05:30
|
|
|
}
|
2021-07-19 04:02:46 +05:30
|
|
|
}
|