Je souhaite lire une vidéo locale dans AVPlayerViewController mais je n'ai pas trouvé l'événement de clic du bouton Terminé.
Ma vidéo peut être lue dans AVPlayerViewController, mais je n'ai pas trouvé le bouton suivant, le bouton précédent et l'événement de clic sur le bouton Terminé.
Officiellement, il n'y a pas d'événement de clic sur le bouton Terminé, a déclaré un ingénieur d'Apple à ce sujet ici .
En ce qui concerne mes recherches, j’ai découvert qu’il existait un moyen indirect, mais vraiment indirect, d’obtenir un événement si le bouton Terminé était cliqué.
J'ai découvert que la seule variable d'AVPlayerViewController, qui change lorsque l'on clique sur le bouton, est AVPlayerViewController.view.frame
. Tout d’abord, view.frame apparaît au centre du viewController.
Si vous le présentez avec animated : true
, il ira au bas de viewController et reviendra au centre. Lorsque vous avez terminé, vous revenez au bas de la page.
Si vous le présentez avec animated : false
, il n'y aura que 2 changements: l'image sera au centre de viewController lorsque vous commencerez à lire la vidéo et en bas, lorsque vous cliquerez sur Terminé.
Donc, si vous ajoutez l'observateur au AVPlayerViewController.view.frame
dans le rappel à present(PlayerViewController, animated : true)
, vous n'obtiendrez qu'un seul appel de l'observateur. Dès que vous avez terminé, le bouton est cliqué et l'affichage vidéo sort de l'écran.
Dans mon cas, AVPlayerViewController était présenté sous forme modale avec animation. Le code ci-dessous a fonctionné pour moi:
Swift 3.0
override func viewDidLoad()
{
super.viewDidLoad()
let videoURL = NSURL(fileURLWithPath:Bundle.main.path(forResource: "MyVideo", ofType:"mp4")!)
let player = AVPlayer(url: videoURL as URL)
present(playerViewController, animated: false) { () -> Void in
player.play()
self.playerViewController.player = player
self.playerViewController.addObserver(self, forKeyPath: #keyPath(UIViewController.view.frame), options: [.old, .new], context: nil)
}}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?)
{
print(self.playerViewController.view.frame)
//Player view is out of the screen and
//You can do your custom actions
}
En outre, j'ai découvert que lorsque vous cliquez sur Terminé, AVPlayerViewController n'est pas renvoyé et vous pouvez le voir dans ParentViewController.presentedViewController
, vous ne pouvez donc pas ajouter l'observateur à cette propriété.
Je l’ai fait pour obtenir un événement de clic sur le bouton Done
de AVPlayerViewController
.
Tout d’abord, créez une extension de Notification.Name
comme ci-dessous
extension Notification.Name {
static let kAVPlayerViewControllerDismissingNotification = Notification.Name.init("dismissing")
}
Maintenant, créez une extension de AVPlayerViewController
et remplacez viewWillDisappear
comme ci-dessous
// create an extension of AVPlayerViewController
extension AVPlayerViewController {
// override 'viewWillDisappear'
open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// now, check that this ViewController is dismissing
if self.isBeingDismissed == false {
return
}
// and then , post a simple notification and observe & handle it, where & when you need to.....
NotificationCenter.default.post(name: .kAVPlayerViewControllerDismissingNotification, object: nil)
}
}
CECI IS POUR UNE SEULE FONCTIONNALITÉ DE BASE QUI MANIPULE L'ÉVÉNEMENT DU BOUTON.
codage heureux ...
Ceci est une petite amélioration par rapport à la réponse de @vmchar:
Nous pouvons utiliser la méthode .isBeingDismissed pour nous assurer que le AVPlayerViewController est en train d'être fermé au lieu d'analyser le cadre.
...
let videoURL = NSURL(fileURLWithPath:"video.mp4")
let player = AVPlayer(url: videoURL as URL)
present(playerViewController!, animated: false) { () -> Void in
player.play()
self.playerViewController!.player = player
self.playerViewController!.addObserver(self, forKeyPath:#keyPath(UIViewController.view.frame), options: [.old, .new], context: nil)
...
Puis observer la valeur
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?)
{
if (playerViewController!.isBeingDismissed) {
// Video was dismissed -> apply logic here
}
}
Je suppose qu'il y a beaucoup de façons de peler un chat. J'avais besoin de gérer l'événement de clic 'Terminé'. Dans mon cas, je voulais être sûr de pouvoir m'inscrire à l'événement après avoir cliqué sur le "X" et AVLayerViewController était COMPLÈTEMENT fermé (rejeté).
Swift 4.0
protocol TableViewCellVideoPlayerViewControllerDelegate: class {
func viewControllerDismissed()
}
class MyPlayerViewController: AVPlayerViewController {
weak var navDelegate: TableViewCellVideoPlayerViewControllerDelegate?
open override func viewDidDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed {
self.navDelegate?.viewControllerDismissed()
}
}
}
class TodayCell: UITableViewCell, SFSafariViewControllerDelegate, TableViewCellVideoPlayerViewControllerDelegate {
func viewControllerDismissed() {
self.continueJourney()
}
}
J'ai eu le même problème et j'ai trouvé une autre astuce (fonctionne avec le framework YoutubePlayer Swift qui lit les vidéos dans une webview, mais vous pourrez peut-être l'adapter à d'autres utilisations).
Dans mon cas, appuyer sur le bouton Done
et sur le bouton Pause
du lecteur vidéo plein écran provoque un événement pause
sur YoutubePlayer. Cependant, lorsque la vidéo est lue dans une fenêtre différente, j'ai sous-classé la fenêtre principale de mon application et substitué les fonctions becomeKey
et resignKey
pour stocker si ma fenêtre est la fenêtre de clé ou non, comme ceci:
class MyWindow:UIWindow {
override func becomeKey() {
Services.appData.myWindowIsKey = true
}
override func resignKey() {
Services.appData.myWindowIsKey = false
}
}
Une fois que j'ai cela, je peux vérifier si ma fenêtre est la clé lorsque l'état de la vidéo passe en pause - lorsque vous appuyez sur le bouton Done
, ma fenêtre est la fenêtre de la clé et je peux fermer mon contrôleur de vue vidéo, et Pause
cas ma fenêtre n'est pas la fenêtre de clé, donc je ne fais rien.