Add Open in PiP option (fix #137)

This commit is contained in:
Arkadiusz Fal 2022-05-29 16:38:37 +02:00
parent 3b1f6b21f3
commit 9abba2d19c
5 changed files with 61 additions and 22 deletions

View File

@ -37,6 +37,9 @@ final class PiPDelegate: NSObject, AVPictureInPictureControllerDelegate {
_: AVPictureInPictureController,
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
) {
completionHandler(true)
player?.show()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
completionHandler(true)
}
}
}

View File

@ -109,6 +109,29 @@ final class PlayerControlsModel: ObservableObject {
}
}
func startPiP(startImmediately: Bool = true) {
if player.activeBackend == .mpv {
player.avPlayerBackend.switchToMPVOnPipClose = true
}
#if !os(macOS)
player.exitFullScreen()
#endif
if player.activeBackend != PlayerBackendType.appleAVPlayer {
player.saveTime { [weak player] in
player?.changeActiveBackend(from: .mpv, to: .appleAVPlayer)
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak player] in
player?.avPlayerBackend.startPictureInPictureOnPlay = true
if startImmediately {
player?.pipController?.startPictureInPicture()
}
}
}
func removeTimer() {
timer?.invalidate()
timer = nil

View File

@ -205,7 +205,7 @@ final class PlayerModel: ObservableObject {
backend.pause()
}
func play(_ video: Video, at time: CMTime? = nil) {
func play(_ video: Video, at time: CMTime? = nil, showingPlayer: Bool = true) {
var delay = 0.0
#if !os(macOS)
delay = 0.3
@ -223,7 +223,9 @@ final class PlayerModel: ObservableObject {
return
}
show()
if showingPlayer {
show()
}
}
func playStream(
@ -268,6 +270,7 @@ final class PlayerModel: ObservableObject {
func saveTime(completionHandler: @escaping () -> Void = {}) {
guard let currentTime = backend.currentTime, currentTime.seconds > 0 else {
completionHandler()
return
}
@ -341,6 +344,10 @@ final class PlayerModel: ObservableObject {
}
func changeActiveBackend(from: PlayerBackendType, to: PlayerBackendType) {
guard activeBackend != to else {
return
}
Defaults[.activeBackend] = to
self.activeBackend = to

View File

@ -265,25 +265,7 @@ struct PlayerControls: View {
private var pipButton: some View {
button("PiP", systemImage: "pip") {
if player.activeBackend == .mpv {
player.avPlayerBackend.switchToMPVOnPipClose = true
}
#if !os(macOS)
player.exitFullScreen()
#endif
if player.activeBackend != PlayerBackendType.appleAVPlayer {
player.saveTime {
player.changeActiveBackend(from: .mpv, to: .appleAVPlayer)
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
print(player.pipController?.isPictureInPicturePossible ?? false ? "possible" : "NOT possible")
player.avPlayerBackend.startPictureInPictureOnPlay = true
player.pipController?.startPictureInPicture()
}
model.startPiP()
}
}

View File

@ -1,4 +1,5 @@
import CoreData
import CoreMedia
import Defaults
import SwiftUI
@ -53,6 +54,9 @@ struct VideoContextMenuView: View {
Section {
playNowButton
#if os(iOS)
playNowInPictureInPictureButton
#endif
}
Section {
@ -133,6 +137,26 @@ struct VideoContextMenuView: View {
}
}
private var playNowInPictureInPictureButton: some View {
Button {
player.controls.startPiP(startImmediately: false)
var time: CMTime?
if saveHistory,
let stoppedAt = watch?.stoppedAt,
!watch!.finished
{
time = .secondsInDefaultTimescale(stoppedAt)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
player.play(video, at: time, showingPlayer: false)
}
} label: {
Label("Play in PiP", systemImage: "pip")
}
}
private var playNextButton: some View {
Button {
player.playNext(video)