1

J'essaie de lire la vidéo en UITableViewCell lorsqu'un utilisateur clique sur le bouton de lecture dans la cellule.Quel est le meilleur endroit pour ajouter AVPlayer ou MPMoviePlayerController dans UITableViewCell?

  1. Ajouter AVPlayer ou MPMoviePlayerController à cellForRowAtIndexPath (ajoutera joueur à chaque fois quand tableview défile)
  2. Ajouter AVPlayer ou MPMoviePlayerController sur le bouton clic (clic jeu vidéo dans une autre cellule pendant le défilement)

Je suis confus où ajouter le joueur dans UITableViewCell de sorte que lorsque je clique pour lire une vidéo, d'autres sont en pause ou arrêtés.

- (void)awakeFromNib { 
    [super awakeFromNib]; 
    // Initialization code 

    self.player = [[AVPlayer alloc] init]; 
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; 
    self.playerLayer.frame = self.playerView.bounds; 
    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    self.playerViewController = [AVPlayerViewController new]; 
    self.playerViewController.player = self.player; 

    [self.playerView.layer addSublayer:self.playerLayer]; 
    [self.playerView bringSubviewToFront:self.btnPlayPause]; 
} 

Ici, je télécharge mon lien de code de projet. https://www.dropbox.com/s/ljoeyc575epimtz/PrymeDemo.zip?dl=0

Je souhaite lire uniquement la vidéo sur laquelle l'utilisateur clique et met en pause la lecture d'une vidéo.

S'il vous plaît aidez-moi à ce sujet.

Merci d'avance.

+0

option de pâte est que pour lire la vidéo ouvrir un nouveau contrôleur sur le bouton cliquez sur cellrowatIndexpath –

+0

Juste pour votre information et en ajoutant commentaire ci-dessus: MPMoviePlayerController a été obsolète dans iOS 9. Regardez également cet exemple https://github.com/ Gagan5278/TableCellStreaming –

+0

@HimanshuMoradiya, je veux lire la vidéo dans la cellule. – Pankil

Répondre

1

Scène 1:

Si vous êtes prêt à video de lecture automatique comme Facebook ou Instagram dans chaque cellule, puis envisager d'ajouter AVPlayer dans cellForRowAtIndexPath.

AVPlayer ne vous permettra pas de changer l'URL en cours de lecture (AVURLAsset url) une fois créée. Donc, si vous utilisez AVPlayer et en fournissant votre propre vue au joueur, j'ai peur de créer AVPlayer instance à chaque fois dans CellForRowAtIndexPath est la seule solution.

D'autre part, si vous prévoyez d'utiliser AVPlayerViewController, vous pouvez créer AvPlayer exemple viewController dans la cellule de awakeFromNib de sorte que vous aurez une seule instance de joueur par cellule et cellForRowAtIndexPath vous pouvez passer URL différente à chaque fois. Vous pouvez utiliser la méthode prepareForReuse de la cellule pour mettre le lecteur en pause et réinitialiser toutes les propriétés de votre lecteur.

Scène 2:

Si vous prévoyez de jouer une fois l'utilisateur tape sur le bouton dans la cellule, envisagez de créer AVPlayer/AVPlayerViewController sur le bouton tap et lire la vidéo. Utilisez prepareForReuse pour réinitialiser les propriétés de votre lecteur afin de vous assurer de ne pas lire une mauvaise vidéo lorsque vous faites défiler et que la cellule est réutilisée.

EDIT:

OP a demandé Comme pour un extrait de code, en fournissant le code squelette. Ce n'est pas un code de copier-coller, l'idée est juste de donner une idée de la façon d'utiliser AVPlayerViewController à l'intérieur de la cellule, le code pourrait avoir des problèmes de compilateur.

// créer une coutume tableViewCell sous-classe

class ImageTableViewCell: UITableViewCell { 
    @IBOutlet weak var carsImageView: UIImageView! 
    var playerController : AVPlayerViewController? = nil 
    var passedURL : URL! = nil 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     playerController = AVPlayerViewController() 
     // Initialization code 
    } 

    func configCell(with url : URL) { 
     //something like this 
     self.passedURL = url 
     //show video thumbnail with play button on it. 
    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 
     // Configure the view for the selected state 
    } 

    @IBAction func playOrPauseVideo(_ sender: UIButton) { 
     let player = AVPlayer(url: url) 
     playerController.player = player 
     playerController?.showsPlaybackControls = true 
     playerController.player.play() 
     //add playerController view as subview to cell 
    } 

    override func prepareForReuse() { 
     //this way once user scrolls player will pause 
     self.playerController.player?.pause() 
     self.playerController.player = nil 
    } 
} 

Le code définit au-dessus du PlayerController à zéro en prepareForReuse() alors quand l'utilisateur fait défiler la tableView et la cellule va de tableView cadre et obtient réutilisés, lecteur se met en pause et la volonté pas conserver le statut. Si vous voulez simplement faire une pause et rejouer lorsque l'utilisateur revient à la même cellule, vous devrez sauvegarder le lecteur quelque part en dehors de la cellule et trouver un moyen de mapper l'instance de joueur à la cellule.

Enfin, dans cellForRowAtIndexPath appel,

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell : ImageTableViewCell = tableView.dequeueReusableCell(withIdentifier: "imageCell") as! ImageTableViewCell 
    cell.configCell(with: URL(string: "https://google.com")!) 
    .... 
} 

EDIT 2:

Comme OP a complètement FILPED la question de jouer une seule vidéo à tout moment et faire une pause d'autres vidéos qui jouent sur les écoutes jeu bouton ma réponse précédente ne sera plus vraie.

Une réponse plus tôt permet à l'utilisateur de lire plusieurs vidéos.

Voici une réponse modifiée pour le faire fonctionner.

Modifiez votre classe de cellule personnalisée comme ci-dessous.

protocol VideoPlayingCellProtocol : NSObjectProtocol { 
    func playVideoForCell(with indexPath : IndexPath) 
} 

class ImageTableViewCell: UITableViewCell { 
    @IBOutlet weak var carsImageView: UIImageView! 
    var playerController : AVPlayerViewController? = nil 
    var passedURL : URL! = nil 
    var indexPath : IndexPath! = nil 
    var delegate : VideoPlayingCellProtocol = nil 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     playerController = AVPlayerViewController() 
     // Initialization code 
    } 

    func configCell(with url : URL,shouldPlay : Bool) { 
     //something like this 
     self.passedURL = url 
     if shouldPlay == true { 
      let player = AVPlayer(url: url) 
      if self.playerController == nil { 
       playerController = AVPlayerViewController() 
      } 
      playerController.player = player 
      playerController?.showsPlaybackControls = true 
      playerController.player.play() 
     } 
     else { 
      if self.playerController != nil { 
       self.playerController.player?.pause() 
       self.playerController.player = nil 
      } 
      //show video thumbnail with play button on it. 
     } 
    } 

    override func setSelected(_ selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

    @IBAction func playOrPauseVideo(_ sender: UIButton) { 
     self.delegate.playVideoForCell(self.indexPath) 
     //add playerController view as subview to cell 
    } 

    override func prepareForReuse() { 
     //this way once user scrolls player will pause 
     self.playerController.player?.pause() 
     self.playerController.player = nil 
    } 
} 

Dans votre TableView VC créer une propriété appelée

var currentlyPlayingIndexPath : IndexPath? = nil 

Faites votre TableView VC pour confirmer VideoPlayingCellProtocol

extension ViewController : VideoPlayingCellProtocol { 
    func playVideoForCell(with indexPath: IndexPath) { 
    self.currentlyPlayingIndexPath = indexPath 
    //reload tableView 
    self.tableView.reloadRows(at: self.tableView.indexPathsForVisibleRows!, with: .none) 
    } 
} 

modifier Enfin votre cellForRowAtIndexPath comme

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell : ImageTableViewCell = tableView.dequeueReusableCell(withIdentifier: "imageCell") as! ImageTableViewCell 
     //delegate setting here which u missed 
     cell.delegate = self 
     //let the cell know its indexPath 
     cell.indexPath = indexPath 

      cell.configCell(with: URL(string: "https://google.com")!, shouldPlay: self.currentlyPlayingIndexPath == indexPath) 
     .... 
} 

Tout ce dont vous avez besoin.

+0

ya que cette solution est la meilleure pour son problème. –

+0

@ himanshu-moradiya: Merci mon pote :) –

+0

J'ai préféré la scène 2 et j'ai mis à jour ma question avec le code d'événement de clic de bouton. comme vous suggérez d'utiliser 'prepareForReuse' comment l'utiliser? – Pankil