yattee/Model/Player/PlayerControlsModel.swift

122 lines
3.4 KiB
Swift
Raw Normal View History

2022-02-16 20:23:11 +00:00
import CoreMedia
import Foundation
import SwiftUI
final class PlayerControlsModel: ObservableObject {
@Published var isLoadingVideo = true
@Published var isPlaying = true
@Published var currentTime = CMTime.zero
@Published var duration = CMTime.zero
@Published var presentingControls = false { didSet { handlePresentationChange() } }
@Published var timer: Timer?
@Published var playingFullscreen = false
var player: PlayerModel!
var playbackTime: String {
guard let current = currentTime.seconds.formattedAsPlaybackTime(),
let duration = duration.seconds.formattedAsPlaybackTime()
else {
return "--:-- / --:--"
}
var withoutSegments = ""
if let withoutSegmentsDuration = playerItemDurationWithoutSponsorSegments,
self.duration.seconds != withoutSegmentsDuration
{
withoutSegments = " (\(withoutSegmentsDuration.formattedAsPlaybackTime() ?? "--:--"))"
}
return "\(current) / \(duration)\(withoutSegments)"
}
var playerItemDurationWithoutSponsorSegments: Double? {
guard let duration = player.playerItemDurationWithoutSponsorSegments else {
return nil
}
return duration.seconds
}
func handlePresentationChange() {
if presentingControls {
DispatchQueue.main.async { [weak self] in
self?.player.backend.startControlsUpdates()
self?.resetTimer()
}
} else {
player.backend.stopControlsUpdates()
timer?.invalidate()
timer = nil
}
}
func show() {
2022-02-21 20:57:12 +00:00
player.backend.updateControls()
2022-02-16 20:23:11 +00:00
withAnimation(PlayerControls.animation) {
presentingControls = true
}
}
func hide() {
withAnimation(PlayerControls.animation) {
presentingControls = false
}
}
func toggle() {
2022-02-21 20:57:12 +00:00
if !presentingControls {
player.backend.updateControls()
}
2022-02-16 20:23:11 +00:00
2022-02-21 20:57:12 +00:00
withAnimation(PlayerControls.animation) {
2022-02-16 20:23:11 +00:00
presentingControls.toggle()
}
}
func toggleFullscreen(_ value: Bool) {
withAnimation(Animation.easeOut) {
resetTimer()
withAnimation(PlayerControls.animation) {
playingFullscreen = !value
}
2022-02-27 20:31:17 +00:00
#if os(iOS)
if playingFullscreen {
guard !(UIApplication.shared.windows.first?.windowScene?.interfaceOrientation.isLandscape ?? true) else {
return
}
Orientation.lockOrientation(.landscape, andRotateTo: .landscapeRight)
} else {
Orientation.lockOrientation(.allButUpsideDown, andRotateTo: .portrait)
2022-02-16 20:23:11 +00:00
}
2022-02-27 20:31:17 +00:00
#endif
2022-02-16 20:23:11 +00:00
}
}
func reset() {
currentTime = .zero
duration = .zero
}
func resetTimer() {
2022-03-27 11:42:20 +00:00
if !presentingControls {
show()
}
2022-02-16 20:23:11 +00:00
removeTimer()
timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) { _ in
withAnimation(PlayerControls.animation) { [weak self] in
self?.presentingControls = false
self?.player.backend.stopControlsUpdates()
}
}
}
func removeTimer() {
timer?.invalidate()
timer = nil
}
}