Add PiP for iOS

This commit is contained in:
Arkadiusz Fal
2022-05-20 23:23:14 +02:00
parent a93b9a2fe5
commit acf9af936a
9 changed files with 137 additions and 21 deletions

View File

@@ -1,25 +1,14 @@
import AVKit
import Defaults
import SwiftUI
struct AppleAVPlayerView: UIViewControllerRepresentable {
@EnvironmentObject<CommentsModel> private var comments
@EnvironmentObject<NavigationModel> private var navigation
struct AppleAVPlayerView: UIViewRepresentable {
@EnvironmentObject<PlayerModel> private var player
@EnvironmentObject<SubscriptionsModel> private var subscriptions
func makeUIViewController(context _: Context) -> UIViewController {
let controller = AppleAVPlayerViewController()
controller.commentsModel = comments
controller.navigationModel = navigation
controller.playerModel = player
controller.subscriptionsModel = subscriptions
player.avPlayerBackend.controller = controller
return controller
func makeUIView(context _: Context) -> some UIView {
player.playerLayerView = PlayerLayerView(frame: .zero)
return player.playerLayerView
}
func updateUIViewController(_: UIViewController, context _: Context) {
player.rebuildTVMenu()
}
func updateUIView(_: UIViewType, context _: Context) {}
}

View File

@@ -173,6 +173,9 @@ struct PlayerControls: View {
HStack {
#if !os(tvOS)
fullscreenButton
#if os(iOS)
pipButton
#endif
rateButton
Spacer()
@@ -235,6 +238,26 @@ struct PlayerControls: View {
.init(get: { player.currentRate }, set: { rate in player.currentRate = rate })
}
private var pipButton: some View {
button("PiP", systemImage: "pip") {
if player.activeBackend == .mpv {
player.avPlayerBackend.switchToMPVOnPipClose = true
}
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.enterPiPOnPlay = true
player.pipController?.startPictureInPicture()
}
}
}
var mediumButtonsBar: some View {
HStack {
#if !os(tvOS)

View File

@@ -0,0 +1,23 @@
import AVFoundation
import Foundation
import UIKit
final class PlayerLayerView: UIView {
var playerLayer = AVPlayerLayer()
override init(frame: CGRect) {
super.init(frame: frame)
layer.addSublayer(playerLayer)
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
playerLayer.frame = bounds
}
}

View File

@@ -226,6 +226,17 @@ struct VideoPlayerView: View {
})
case .appleAVPlayer:
player.avPlayerView
#if os(iOS)
.onAppear {
player.pipController = .init(playerLayer: player.playerLayerView.playerLayer)
let pipDelegate = PiPDelegate()
pipDelegate.player = player
player.pipDelegate = pipDelegate
player.pipController!.delegate = pipDelegate
player.playerLayerView.playerLayer.player = player.avPlayerBackend.avPlayer
}
#endif
}
#if !os(tvOS)