1

当用户点击单元格中的播放按钮时,我尝试播放UITableViewCell中的视频。什么是在UITableViewCell中添加AVPlayer或MPMoviePlayerController的最佳地点?

  1. 添加AVPlayercellForRowAtIndexPathMPMoviePlayerController(将增加玩家每次当tableview中的滚动)
  2. 添加按钮点击AVPlayerMPMoviePlayerController(点击视频播放在其他细胞而滚动)

我困惑在UITableViewCell添加播放器的位置,以便当我点击播放一个视频时,其他播放器暂停或停止。

- (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]; 
} 

这里我上传我的项目代码链接。 https://www.dropbox.com/s/ljoeyc575epimtz/PrymeDemo.zip?dl=0

我只想播放那个用户点击并暂停以前播放视频的视频。

请帮我解决这个问题。

在此先感谢。

+0

面糊选项是播放视频打开新的控制器上按钮单击cellrowatIndexpath –

+0

只是为您的信息和添加上面的评论:MPMoviePlayerController已被弃用在iOS 9。也看看这个例子https://github.com/ Gagan5278/TableCellStreaming –

+0

@HimanshuMoradiya,我想在单元格中播放视频。 – Pankil

回答

1

场景1:

如果你愿意自动播放视频的像Facebook或Instagram的在每个单元格,然后考虑的cellForRowAtIndexPath加入AVPlayer。

AVPlayer将不允许您在创建后更改正在播放的网址(AVURLAsset网址)。因此,如果您使用AVPlayer并向玩家提供您自己的视图,那么恐怕在CellForRowAtIndexPath中每次创建AVPlayer实例都是唯一的解决方案。

。如果您打算使用AVPlayerViewController另一方面,可以在细胞的awakeFromNib创建avplayer的viewController实例,所以你将有只有一个每个细胞的球员实例,并在你的cellForRowAtIndexPath可每次都通过不同的URL。您可以使用单元格的prepareForReuse方法暂停播放器并重置所有播放器属性。

场景2:

如果您正计划打一次用户在细胞上的按钮水龙头,考虑按钮自来水创建AVPlayer/AVPlayerViewController和播放视频。使用prepareForReuse来重置您播放器的属性,以确保当您滚动并重新使用单元格时不会播放错误的视频。

编辑:

由于OP已要求一些代码片段,提供框架代码。这不是一个复制粘贴代码,想法只是想知道如何在单元内使用AVPlayerViewController,代码可能有编译器问题。

//创建一个自定义tableViewCell子

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 
    } 
} 

上面的代码设置的PlayerController为零的prepareForReuse()所以当用户滚动的tableView和细胞熄灭的tableView框架和得到重用,玩家将暂停和意志不保留状态。如果你只是想在用户滚动回到同一单元格时暂停并重放,你将不得不将单元保存到单元格外的某处,并找到一种方法将单元映射到单元格。

终于在cellForRowAtIndexPath通话,

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")!) 
    .... 
} 

编辑2:

欧普已经完全filped问题在任何时间点上敲击玩只玩一个视频和暂停等播放视频按钮我以前的答案将不再成立。

较早的答案允许用户播放多个视频。

这是修改后的答案,使其工作。

修改您的自定义单元类如下。

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 
    } 
} 

在你的TableView VC创建一个名为

var currentlyPlayingIndexPath : IndexPath? = nil 

让您的TableView VC确认VideoPlayingCellProtocol

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

财产最后修改cellForRowAtIndexPath作为

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) 
     .... 
} 

那就是你需要的全部。

+0

ya这个解决方案最适合他的问题。 –

+0

@ himanshu-moradiya:谢谢哥们:) –

+0

我喜欢场景2,我用按钮点击事件代码更新了我的问题。因为你建议使用'prepareForReuse'如何使用它? – Pankil

相关问题