Dibujar el button en la parte superior de AVPlayer

Debo dibujar una label o button en la parte superior del video relay next previous , leave comment . La list de videos la tiene, una vez que el usuario selecciona un elemento de la tabla, debe jugar. Una vez que el jugador haya terminado, esos botones o tags deben aparecer encima del video.

Aquí está mi código:

  comPlayerControl = AVPlayerViewController() if let player = comPlayerControl { let videoURL: String = "http://cdnapi.kaltura.com/p/11/sp/11/playManifest/entryId/"+selectedSubmission.transcodeRefId+"/format/applehttp/protocol/http/a.m3u8" let playerItem = AVPlayerItem(URL: NSURL(string: videoURL)! ) commmentPlayer = AVPlayer(playerItem: playerItem) player.player = commmentPlayer player.view.frame = videoCell.frame player.view.sizeToFit() player.showsPlaybackControls = true NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(CommentsTableViewController.playerDidFinishPlaying(_:)), name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem) comPlayerControl.delegate = self videoCell.addSubview(player.view) } func playerDidFinishPlaying(note: NSNotification) { print("Video Finished") let DynamicView=UIView(frame: CGRectMake(100, 200, 100, 100)) DynamicView.backgroundColor=UIColor.greenColor() DynamicView.layer.cornerRadius=25 DynamicView.layer.borderWidth=2 DynamicView.layer.zPosition = 1; comPlayerControl.view.addSubview(DynamicView) } 

requisito como este

imagen del requerimiento

Está utilizando un AVPlayerViewController , por lo que no hay razón para acceder a la window de su aplicación como en la respuesta de Alessandro Ornano. ¿Por qué redevise la rueda? Cada AVPlayerViewController tiene una propiedad contentOverlayView que le permite colocar vistas entre el reproductor y los controles.

Primero, cree un nuevo AVPlayerItem y escuche la notificación AVPlayerItemDidPlayToEndTimeNotification en ese elemento. Cargue el elemento en su reproductor y comience la reproducción.

Una vez que se completa el elemento, se llamará al selector especificado para escuchar la notificación AVPlayerItemDidPlayToEndTimeNotification . En ese selector, acceda directamente a contentOverlayView y añada sus botones:

En algún controller de vista u otro object:

 let playerVC = AVPlayerViewController() // ... func setupPlayer { let playerItem = AVPlayerItem(...) playerVC.player?.replaceCurrentItemWithPlayerItem(playerItem) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(VC.itemFinished), name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem) self.presentViewController(playerVC, animated: true) { self.playerVC.player?.play() } } func itemFinished() { let btn = UIButton(type: .System) btn.addTarget(self, action: #selector(VC.buttonTapped), forControlEvents: .TouchUpInside) self.playerVC.contentOverlayView?.addSubview(btn) } func buttonTapped() { print("button was tapped") // replay/comment logic here } 

Como se indica en los comentarios (y una edición rechazada ), los botones pueden no funcionar en el contenido contentOverlayView . Para get una solución alternativa, consulte la respuesta de Pyro .

También podría subclass AVPlayerViewController y hacer todo dentro de una instancia de su subclass, pero Apple advierte contra eso :

No subclasss AVPlayerViewController . La anulación de los methods de esta class no es compatible y da como resultado un comportamiento no definido.

Creo que la mejor manera de hacer los botones de avplayer se explica aquí: IOS 8 Video Playback usando AVPlayer y AVPlayerViewController .

Por lo tanto, prefiero y estoy de acuerdo con estas instrucciones, pero si aún deseas agregar estos botones, puedes intentar agregarlos a la window self.

 if let app = UIApplication.shanetworkingApplication().delegate as? AppDelegate, let window = app.window { let myFirstButton = UIButton() myFirstButton.setTitle("test", forState: .Normal) window.addSubview(myFirstButton) ... } 

En function de su pregunta y del comentario / código de Ramis, he creado un código de ejemplo que puede probar

Como lo menciona JAL, the contentOverlayView debería ser la mejor opción para mostrar el control sobre el video en el AVPlayerController, pero según mi demostración mi muestra, la vista de contenido no tiene interacción del usuario con los botones u otros controles, como si se registrara la vista 3D del AVPlayerController tiene AVTouchIgnoringView / UIView por delante del contenidoOverlayView que puede ser un problema en la interacción del usuario de contentOverlayView

Entonces, otra solución es agregar la vista de superposition en AVPlayerViewController

 func addContentOverlayView() { OverlayView.frame = CGRectMake(0,30,AVPlayerVC.view.bounds.width, 100) OverlayView.hidden = true OverlayView.backgroundColor = UIColor ( networking: 0.5, green: 0.5, blue: 0.5, alpha: 0.379 ) let btnNext = UIButton(frame:CGRectMake(AVPlayerVC.view.bounds.width - 60,0,60,44)) btnNext.setTitle(">>", forState:.Normal) btnNext.addTarget(self, action:"playNext", forControlEvents:.TouchUpInside) // btnNext.layer.borderColor = UIColor ( networking: 0.0, green: 0.0, blue: 1.0, alpha: 0.670476140202703 ).CGColor // btnNext.layer.borderWidth = 1.0 OverlayView.addSubview(btnNext) let btnReplay = UIButton(frame:CGRectMake((AVPlayerVC.view.bounds.width/2)-40,0,80,44)) btnReplay.setTitle("Replay", forState:.Normal) btnReplay.addTarget(self, action:"replayVideo", forControlEvents:.TouchUpInside) OverlayView.addSubview(btnReplay) let btnPrevious = UIButton(frame:CGRectMake(0,0,80,44)) btnPrevious.setTitle("<<", forState:.Normal) btnPrevious.addTarget(self, action:"previousVideo", forControlEvents:.TouchUpInside) OverlayView.addSubview(btnPrevious) let btnComment = UIButton(frame:CGRectMake((AVPlayerVC.view.bounds.width/2)-70,40,140,44)) btnComment.setTitle("Comments", forState:.Normal) btnComment.addTarget(self, action:"openComments", forControlEvents:.TouchUpInside) OverlayView.addSubview(btnComment) AVPlayerVC.view.addSubview(OverlayView); } func playNext() { prevItem = AVPlayerVC.player?.currentItem OverlayView.hidden = true commmentQueuePlayer.advanceToNextItem() } func replayVideo() { OverlayView.hidden = true AVPlayerVC.player?.currentItem?.seekToTime(kCMTimeZero) AVPlayerVC.player?.play() } func previousVideo() { OverlayView.hidden = true if prevItem != AVPlayerVC.player?.currentItem { if (commmentQueuePlayer.canInsertItem(prevItem!, afterItem:AVPlayerVC.player?.currentItem)) { //commmentQueuePlayer.insertItem(prevItem!, afterItem:AVPlayerVC.player?.currentItem) commmentQueuePlayer.replaceCurrentItemWithPlayerItem(prevItem) prevItem = AVPlayerVC.player?.currentItem replayVideo() } } else { replayVideo() //Else display alert no prev video found } } func stopedPlaying() { if prevItem == nil { prevItem = AVPlayerVC.player?.currentItem } OverlayView.hidden = false } 

En la configuration inicial, configuramos AVPlayerController, AVQueuePlayer, etc … en ese momento podemos agregar la superposition en AVPlayerController

Para el artículo anterior, no hay disponible directamente y, según la documentation, el elemento se eliminará una vez que se reproduzca el siguiente elemento, por lo que tenemos dos opciones como replaceCurrentItemWithPlayerItem o insertItem(item: AVPlayerItem, afterItem: AVPlayerItem?)

Si necesita verificar el código completo, puede verificarlo desde: https://gist.github.com/Pyrolr/debb4fca8f608b1300e099a5b3547031

Nota: Esto es como un prototipo, no funciona a la perfección en todos los casos, pero puede ayudarlo a comprender la funcionalidad básica que necesita y puede mejorar / optimizar de acuerdo con sus requisitos

Recomiendo search AVPlayerLayer como una forma de mostrar botones y otro contenido en la parte superior de tu video.

Consulte los avances en la presentación de WWDC de reproducción de AVFoundation .

Además, echa un vistazo al proyecto de ejemplo AVFoundationSimplePlayer-iOS .

Esencialmente, creas una vista para alojar tu reproductor, y creas la capa detrás de la vista en un AVPlayerLayer.

 class PlayerView: UIView { var player: AVPlayer? { get { return playerLayer.player } set { playerLayer.player = newValue } } var playerLayer: AVPlayerLayer { return layer as! AVPlayerLayer } override class var layerClass: AnyClass { return AVPlayerLayer.self } }