Dav*_*ese 5 ios swift avkit picture-in-picture swiftui
我正在设计一个应用程序,允许用户在 SwiftUI 视图中观看特定视频。我想支持 PiP,AVPictureInPictureController.isPictureInPictureSupported() 始终返回 true,而 pipController.isPictureInPicturePossible 有时返回 true,但通常在视频实际播放时不会返回 true。我可能误解了如何使用 AVPictureInPictureController。
我的应用程序使用以下代码初始化一个称为 FullScreenVideoView 的视图:
init(player: KHKVideoPlayer, aspectRatio: CGFloat, presentingViewController pvc: UIViewController?) {
self.aspectRatio = aspectRatio
self.pvc = pvc
self.model = FullScreenVideoViewerModel(player: player)
self.playerController = KHKPlayerController(player: player.avPlayer, cornerRadius: 0)
if AVPictureInPictureController.isPictureInPictureSupported() {
self.pipController = AVPictureInPictureController(playerLayer: AVPlayerLayer(player: player.avPlayer))!
}
self.isMuted = player.avPlayer.isMuted
}
Run Code Online (Sandbox Code Playgroud)
然后,在视图主体内,它通过调用初始化程序中定义的playerController来显示视频:
playerController
.frame(height: aspectRatio * geometry.size.width)
.onTapGesture {
if self.model.player.avPlayer.isPlaying {
self.model.pause()
} else {
self.model.play()
}
}
Run Code Online (Sandbox Code Playgroud)
PlayerController 是 AVPlayerViewController 的包装器:
struct KHKPlayerController: UIViewControllerRepresentable {
typealias UIViewControllerType = AVPlayerViewController
var player: AVPlayer
var cornerRadius: CGFloat?
init(player: AVPlayer) {
self.player = player
}
init(player: AVPlayer, cornerRadius: CGFloat) {
self.player = player
self.cornerRadius = cornerRadius
}
func makeUIViewController(context: Context) -> AVPlayerViewController {
let playerVC = AVPlayerViewController()
playerVC.showsPlaybackControls = false
playerVC.player = player
playerVC.view.layer.masksToBounds = true
playerVC.view.layer.cornerRadius = cornerRadius ?? 8
return playerVC
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) {
}
Run Code Online (Sandbox Code Playgroud)
}
应该有一个按钮来启动画中画:
RectangleButton(action: {
print("pip is possible: \(pipController?.isPictureInPicturePossible ?? false)")
pipController?.startPictureInPicture()
}, imageSystemName: "pip.enter", foregroundColor: UI.Constants.primaryColor, backgroundColor: UI.Constants.tertiaryColor, width: 35, height: 25, cornerRadius: 3)
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感激。我找不到任何有关在 SwiftUI 中启动 PiP 的有用信息。
注意 - 启用了正确的后台功能。另外,在我的 AppDelegate didFinishLaunchingWithOptions 方法中,我有以下代码似乎是 PiP 所需的:
do {
try audioSession.setCategory(AVAudioSession.Category.playback)
} catch {
print("Audio session failed")
}
Run Code Online (Sandbox Code Playgroud)
你的代码实际上大部分工作 - 至少在我的 SwiftUI 代码中我几乎有与你描述的相同的步骤。
然而,我在playerLayer上做了更多的事情,也许这会导致pipController真正工作。
这是我在视图定义中对playerLayer 所做的操作,我将其添加为单独的控制层:
player = AVPlayer(url: url)
playerLayer = AVPlayerLayer()
playerLayer.player = player
layer.addSublayer(playerLayer)
playerLayer.videoGravity = .resizeAspect
playerLayer.frame = self.bounds
if let playerLayer = playerLayer {
if AVPictureInPictureController.isPictureInPictureSupported() {
pipController = AVPictureInPictureController(playerLayer: playerLayer)!
}
}
Run Code Online (Sandbox Code Playgroud)
我不能 100% 确定这个额外的子层是否真的导致 pipController 得到改进。
另外,我没有使用KHKVideoPlayer而是使用普通的AVPlayer(url: url).
AVPlayerViewController自从在 SwiftUI 中完成所有操作以来,我根本没有使用过。
当然,我还添加了后台模式以使 pip 成为可能......
| 归档时间: |
|
| 查看次数: |
2930 次 |
| 最近记录: |