当用户选择播放新视频时关闭画中画视频



我正在使用AVKit向用户显示视频。

当用户选择视频时,将使用AVKit的标准播放器呈现该视频。这使它全屏显示。

如果用户选择将其设置为"画中画",则用户可以继续使用应用程序的其余部分。

这意味着用户可以选择另一个视频进行播放,该视频确实与上一个视频同时播放(全屏(,该视频在画中画中仍然可见。

当选择第二个视频时,我想关闭第一个(PiP(视频,但是,在启动第二个视频之前,我尝试"关闭"前一个视频,但它不起作用。

我认为这是因为它显示为画中画,所以 AVPlayerViewController 不再代表它......

有没有办法简单地做到这一点?

播放视频时(不起作用(尝试终止第一个视频,如果第二个视频正在尝试播放:

func play(FileName filename: String, FileType type: String)
{
if self.isVideoPlaying == YES
{
self.playerController!.dismiss(animated: YES, completion: { self.isVideoPlaying = NO ; self.play(FileName: filename, FileType: type) })
return
}
self.isVideoPlaying = YES
let path = Bundle.main.path(forResource: filename, ofType: type)
let url = NSURL(fileURLWithPath: path!)
let player = AVPlayer(url: url as URL)
...

好的,这是我解决它的方法:

  1. 具有在播放视频时设置的类属性"isAlreadyPlaying: Bool"...然而

  2. 在"播放"视频并向AVPlayerViewController呈现(新(视频的方法中,请在开头进行以下检查:


if self.isAlreadyPlaying == YES
{
killVideoPlayer()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5, execute: { self.play(FileName: filename, FileType: type) })
return
}
... Here you put the normal play / present code

在"killVideoPlayer(("方法中,将属性"isAlreadyPlaying"设置为NO/false。

(仅供那些还不知道的人(,这是 kill 函数:

private func killVideoPlayer()
{
self.isAlreadyPlaying          = NO
self.playerController?.player?.pause()
self.playerController?.player  = nil
let audioSession = AVAudioSession.sharedInstance()
do
{
try audioSession.setActive(false, options: .notifyOthersOnDeactivation)
try audioSession.setCategory(.soloAmbient)
}
catch
{
print("Audio session failed")
}
self.playerController?.dismiss(animated: YES, completion: 
{ 
self.playerController = nil 
})
}

SwiftUI 和 UIViewControllerRepresentable

我的问题是,我想在播放新视频时关闭播放的最后一个画中画视频。 我使用 Combine 和AVPlayerViewControllerDelegate的函数解决了它。

协调器跟踪当前播放的视频的 PIP 状态,并将该 AVPlayerViewController 存储在管理器单例中,以防视频处于 PIP 中。播放新视频后,已存储的AVPlayerViewController将被关闭。

struct PlayerView: UIViewControllerRepresentable {
private let playerViewController: AVPlayerViewController = {
AVPlayerViewController()
}()
public func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIViewController(context: Context) -> AVPlayerViewController {
playerViewController.delegate = context.coordinator
context.coordinator.playerController = playerViewController
return playerViewController
}
func updateUIViewController(_ playerController: AVPlayerViewController, context: Context) { }
class Coordinator: NSObject, AVPlayerViewControllerDelegate {
weak var playerController: AVPlayerViewController? {
didSet {
playerController?.delegate = self
}
}

private var cancellables: Set<AnyCancellable> = Set<AnyCancellable>()

private var videoisPlayedInPip = PassthroughSubject<Bool, Never>()
private var pictureInPictureManager: VideoPlayerPictureInPictureManager = .shared

init() {
super.init()
handlePictureInPictureChanges()
}

private func handlePictureInPictureChanges() {
//Dismiss video played in PIP when a new video is played 
self.pictureInPictureManager.closeLastPipPlayer()
// Update new video played in PIP 
videoisPlayedInPip.sink { [weak self] isInPip in
guard let self else { return }
if isInPip {
self.pictureInPictureManager.updateLastPiPAVPlayerVC(self.playerController)
} else {
self.pictureInPictureManager.updateLastPiPAVPlayerVC(nil)
}
}
.store(in: &cancellables)
}

func playerViewControllerWillStartPictureInPicture(_ playerViewController: AVPlayerViewController) {
videoisPlayedInPip.send(true)
}

func playerViewControllerWillStopPictureInPicture(_ playerViewController: AVPlayerViewController) {
videoisPlayedInPip.send(false)
}
} 
}
class VideoPlayerPictureInPictureManager {
public static let shared = VideoPlayerPictureInPictureManager()
private(set) var lastPiPAVPlayerVC: AVPlayerViewController?
//Dismiss video played in PIP
public func closeLastPipPlayer() {
lastPiPAVPlayerVC?.dismiss(animated: false)
lastPiPAVPlayerVC?.player?.pause()
lastPiPAVPlayerVC?.player = nil

DispatchQueue.main.async { [weak self] in
self?.lastPiPAVPlayerVC?.dismiss(animated: true, completion: {
self?.updateLastPiPAVPlayerVC(nil)
})
}
}
//Update new video played in PIP 
public func updateLastPiPAVPlayerVC(_ vc: AVPlayerViewController?) {
self.lastPiPAVPlayerVC = vc
}
}

相关内容

  • 没有找到相关文章

最新更新