mirror of
https://github.com/yattee/yattee.git
synced 2025-08-05 02:04:07 +00:00
Minor fixes, split files into folders
This commit is contained in:
14
Shared/Player/Player.swift
Normal file
14
Shared/Player/Player.swift
Normal file
@@ -0,0 +1,14 @@
|
||||
import SwiftUI
|
||||
|
||||
struct Player: UIViewControllerRepresentable {
|
||||
var video: Video?
|
||||
|
||||
func makeUIViewController(context _: Context) -> PlayerViewController {
|
||||
let controller = PlayerViewController()
|
||||
controller.video = video
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_: PlayerViewController, context _: Context) {}
|
||||
}
|
125
Shared/Player/PlayerViewController.swift
Normal file
125
Shared/Player/PlayerViewController.swift
Normal file
@@ -0,0 +1,125 @@
|
||||
import AVKit
|
||||
import Logging
|
||||
import SwiftUI
|
||||
|
||||
final class PlayerViewController: UIViewController {
|
||||
var video: Video!
|
||||
|
||||
var playerLoaded = false
|
||||
var player = AVPlayer()
|
||||
var playerState: PlayerState! = PlayerState()
|
||||
var playerViewController = AVPlayerViewController()
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
loadPlayer()
|
||||
|
||||
try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
|
||||
try? AVAudioSession.sharedInstance().setActive(true)
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
#if os(iOS)
|
||||
if !playerState.playingOutsideViewController {
|
||||
playerViewController.player?.replaceCurrentItem(with: nil)
|
||||
playerViewController.player = nil
|
||||
|
||||
try? AVAudioSession.sharedInstance().setActive(false)
|
||||
}
|
||||
#endif
|
||||
|
||||
super.viewDidDisappear(animated)
|
||||
}
|
||||
|
||||
func loadPlayer() {
|
||||
guard !playerLoaded else {
|
||||
return
|
||||
}
|
||||
|
||||
playerState.player = player
|
||||
playerViewController.player = playerState.player
|
||||
playerState.loadVideo(video)
|
||||
|
||||
#if os(tvOS)
|
||||
present(playerViewController, animated: false)
|
||||
|
||||
addItemDidPlayToEndTimeObserver()
|
||||
|
||||
#else
|
||||
embedViewController()
|
||||
#endif
|
||||
|
||||
playerViewController.allowsPictureInPicturePlayback = true
|
||||
playerViewController.delegate = self
|
||||
playerLoaded = true
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
func addItemDidPlayToEndTimeObserver() {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(itemDidPlayToEndTime),
|
||||
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
|
||||
object: nil
|
||||
)
|
||||
}
|
||||
|
||||
@objc func itemDidPlayToEndTime() {
|
||||
playerViewController.dismiss(animated: true) {
|
||||
self.dismiss(animated: false)
|
||||
}
|
||||
}
|
||||
#else
|
||||
func embedViewController() {
|
||||
playerViewController.exitsFullScreenWhenPlaybackEnds = true
|
||||
playerViewController.view.frame = view.bounds
|
||||
|
||||
addChild(playerViewController)
|
||||
view.addSubview(playerViewController.view)
|
||||
|
||||
playerViewController.didMove(toParent: self)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extension PlayerViewController: AVPlayerViewControllerDelegate {
|
||||
func playerViewControllerShouldDismiss(_: AVPlayerViewController) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_: AVPlayerViewController) -> Bool {
|
||||
false
|
||||
}
|
||||
|
||||
func playerViewControllerDidEndDismissalTransition(_: AVPlayerViewController) {
|
||||
playerState.playingOutsideViewController = false
|
||||
dismiss(animated: false)
|
||||
}
|
||||
|
||||
func playerViewController(
|
||||
_: AVPlayerViewController,
|
||||
willBeginFullScreenPresentationWithAnimationCoordinator _: UIViewControllerTransitionCoordinator
|
||||
) {
|
||||
playerState.playingOutsideViewController = true
|
||||
}
|
||||
|
||||
func playerViewController(
|
||||
_: AVPlayerViewController,
|
||||
willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
|
||||
) {
|
||||
coordinator.animate(alongsideTransition: nil) { context in
|
||||
if !context.isCancelled {
|
||||
self.playerState.playingOutsideViewController = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func playerViewControllerWillStartPictureInPicture(_: AVPlayerViewController) {
|
||||
playerState.playingOutsideViewController = true
|
||||
}
|
||||
|
||||
func playerViewControllerWillStopPictureInPicture(_: AVPlayerViewController) {
|
||||
playerState.playingOutsideViewController = false
|
||||
}
|
||||
}
|
58
Shared/Player/VideoPlayerView.swift
Normal file
58
Shared/Player/VideoPlayerView.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
import AVKit
|
||||
import Siesta
|
||||
import SwiftUI
|
||||
|
||||
struct VideoPlayerView: View {
|
||||
@EnvironmentObject<NavigationState> private var navigationState
|
||||
|
||||
@ObservedObject private var store = Store<Video>()
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
var resource: Resource {
|
||||
InvidiousAPI.shared.video(video.id)
|
||||
}
|
||||
|
||||
var video: Video
|
||||
|
||||
init(_ video: Video) {
|
||||
self.video = video
|
||||
resource.addObserver(store)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Player(video: video)
|
||||
.frame(alignment: .leading)
|
||||
|
||||
#if !os(tvOS)
|
||||
ScrollView(.vertical) {
|
||||
VStack(alignment: .leading) {
|
||||
Text(video.title)
|
||||
Text(video.author)
|
||||
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
}
|
||||
.keyboardShortcut(.cancelAction)
|
||||
}
|
||||
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
.onAppear {
|
||||
resource.loadIfNeeded()
|
||||
}
|
||||
.onDisappear {
|
||||
resource.removeObservers(ownedBy: store)
|
||||
resource.invalidate()
|
||||
|
||||
navigationState.showingVideoDetails = navigationState.returnToDetails
|
||||
}
|
||||
#if os(macOS)
|
||||
.navigationTitle(video.title)
|
||||
#elseif os(iOS)
|
||||
.navigationBarTitle(video.title, displayMode: .inline)
|
||||
#endif
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user