San*_*ari 5

场景1:

如果你愿意自动播放视频的像Facebook或Instagram的每个单元格,然后考虑增加AVPlayercellForRowAtIndexPath

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

另一方面,如果您打算使用AVPlayerViewController,则可以AVPlayer viewController在单元格中创建实例,awakeFromNib这样每个单元格中只有一个播放器实例,并且每次cellForRowAtIndexPath都可以传递不同的url。您可以使用单元格的prepareForReuse方法暂停播放器并重置所有播放器属性。

场景2:

如果您打算在用户点按单元格中的按钮后播放一次,请考虑创建AVPlayer/ AVPlayerViewController单击按钮并播放视频。使用prepareForReuse重置乌尔玩家的属性,以确保当u滚动和细胞得到重用你不玩错了视频。

编辑:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将PlayerControllerin 设置为nil,prepareForReuse()因此当用户滚动tableView和并使单元格脱离tableViewFrame并被重用时,播放器将暂停并且不会保留状态。如果您只是想在用户回滚到同一单元格时暂停并重播,则必须将播放器保存在该单元格之外的某个位置,并找到一种将播放器实例映射到该单元格的方法。

终于在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")!)
    ....
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

由于OP已完全解决问题,因此在任何时间点只能播放一个视频,而在点击“播放”按钮时暂停其他播放视频,我以前的答案将不再成立。

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

这是一个修改后的答案,以使其起作用。

修改您的自定义单元格类,如下所示。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

在您的TableView VC中创建一个名为

var currentlyPlayingIndexPath : IndexPath? = nil
Run Code Online (Sandbox Code Playgroud)

使您的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)
   }
}
Run Code Online (Sandbox Code Playgroud)

最后修改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)
        ....
}
Run Code Online (Sandbox Code Playgroud)

那就是您所需要的。