swift – 在tableview单元格中嵌入视频

前端之家收集整理的这篇文章主要介绍了swift – 在tableview单元格中嵌入视频前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
将视频嵌入UITableViewCell的最佳方法是什么?我正在尝试构建类似Vine / Instagram的东西.

我能够很好地处理异步图像加载SD_WebImage ..但不幸的是它们不支持视频.我也尝试使用MPMoviePlayer进行嵌入,但它只是显示为黑屏.这是我试过的:

  1. override func viewDidLoad() {
  2. super.viewDidLoad()
  3.  
  4. tableView.frame = CGRectMake(0,view.bounds.width,view.bounds.height);
  5. tableView.delegate = self
  6. tableView.dataSource = self
  7.  
  8. tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier: "cell")
  9.  
  10. self.view.addSubview(tableView)
  11. }
  12.  
  13. func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  14.  
  15. var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
  16. var moviePlayer : MPMoviePlayerController?
  17.  
  18. let url = NSURL (string: "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v")
  19. moviePlayer = MPMoviePlayerController(contentURL: url)
  20. if let player = moviePlayer {
  21. player.view.frame = CGRectMake(0,100,view.bounds.size.width,180)
  22. player.prepareToPlay()
  23. player.controlStyle = .None
  24. player.repeatMode = .One
  25. player.scalingMode = .AspectFit
  26. cell.addSubview(player.view)
  27. }
  28.  
  29. return cell
  30.  
  31. }
我只测试了一个视频演示,

以下是如何实现它 –
创建一个自定义Cell类来保存视频播放器视图,并在这里处理avplayer的播放和暂停方法.

这是我的自定义单元类 –

  1. import UIKit
  2. import AVFoundation
  3.  
  4. class VideoCellTableViewCell: UITableViewCell {
  5.  
  6. // I have put the avplayer layer on this view
  7. @IBOutlet weak var videoPlayerSuperView: UIView!
  8. var avPlayer: AVPlayer?
  9. var avPlayerLayer: AVPlayerLayer?
  10. var paused: Bool = false
  11.  
  12. //This will be called everytime a new value is set on the videoplayer item
  13. var videoPlayerItem: AVPlayerItem? = nil {
  14. didSet {
  15. /*
  16. If needed,configure player item here before associating it with a player.
  17. (example: adding outputs,setting text style rules,selecting media options)
  18. */
  19. avPlayer?.replaceCurrentItem(with: self.videoPlayerItem)
  20. }
  21. }
  22.  
  23. override func awakeFromNib() {
  24. super.awakeFromNib()
  25. //Setup you avplayer while the cell is created
  26. self.setupMoviePlayer()
  27. }
  28.  
  29. func setupMoviePlayer(){
  30. self.avPlayer = AVPlayer.init(playerItem: self.videoPlayerItem)
  31. avPlayerLayer = AVPlayerLayer(player: avPlayer)
  32. avPlayerLayer?.videoGravity = AVLayerVideoGravityResizeAspect
  33. avPlayer?.volume = 3
  34. avPlayer?.actionAtItemEnd = .none
  35.  
  36. // You need to have different variations
  37. // according to the device so as the avplayer fits well
  38. if UIScreen.main.bounds.width == 375 {
  39. let widthrequired = self.frame.size.width - 20
  40. avPlayerLayer?.frame = CGRect.init(x: 0,y: 0,width: widthrequired,height: widthrequired/1.78)
  41. }else if UIScreen.main.bounds.width == 320 {
  42. avPlayerLayer?.frame = CGRect.init(x: 0,width: (self.frame.size.height - 120) * 1.78,height: self.frame.size.height - 120)
  43. }else{
  44. let widthrequired = self.frame.size.width
  45. avPlayerLayer?.frame = CGRect.init(x: 0,height: widthrequired/1.78)
  46. }
  47. self.backgroundColor = .clear
  48. self.videoPlayerSuperView.layer.insertSublayer(avPlayerLayer!,at: 0)
  49.  
  50. // This notification is fired when the video ends,you can handle it in the method.
  51. NotificationCenter.default.addObserver(self,selector: #selector(self.playerItemDidReachEnd(notification:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: avPlayer?.currentItem)
  52. }
  53.  
  54. func stopPlayback(){
  55. self.avPlayer?.pause()
  56. }
  57.  
  58. func startPlayback(){
  59. self.avPlayer?.play()
  60. }
  61.  
  62. // A notification is fired and seeker is sent to the beginning to loop the video again
  63. func playerItemDidReachEnd(notification: Notification) {
  64. let p: AVPlayerItem = notification.object as! AVPlayerItem
  65. p.seek(to: kCMTimeZero)
  66. }
  67.  
  68. }

然后是你的控制器 –
别忘了导入AVFoundation Framework

  1. import UIKit
  2. import AVFoundation
  3.  
  4. class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
  5.  
  6. // The current VisibleIndexPath,//it can be an array,but for now,//i am targetting one cell only
  7. //var visibleIP : IndexPath?
  8.  
  9. var aboutToBecomeInvisibleCell = -1
  10. var avPlayerLayer: AVPlayerLayer!
  11. var videoURLs = Array<URL>()
  12. var firstLoad = true
  13.  
  14. @IBOutlet weak var FeedTableView: UITableView!
  15.  
  16. override func viewDidLoad() {
  17. super.viewDidLoad()
  18. FeedTableView.delegate = self
  19. FeedTableView.dataSource = self
  20. //Your model to hold the videos in the video URL
  21. for i in 0..<2{
  22. let url = Bundle.main.url(forResource:"\(i+1)",withExtension: "mp4")
  23. videoURLs.append(url!)
  24. }
  25. // initialized to first indexpath
  26. visibleIP = IndexPath.init(row: 0,section: 0)
  27. }
  28.  
  29. func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
  30. return 5
  31. }
  32.  
  33. func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
  34. return 290
  35. }
  36.  
  37. func tableView(_ tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat {
  38. return 0
  39. }

然后在cellForRow委托中提供您的URL

  1. func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  2. //Thats it,just provide the URL from here,it will change with didSet Method in your custom cell class
  3. let cell = self.FeedTableView.dequeueReusableCell(withIdentifier: "videoCell") as! VideoCellTableViewCell
  4. cell.videoPlayerItem = AVPlayerItem.init(url: videoURLs[indexPath.row % 2])
  5. return cell
  6. }

这里管理了可见细胞的所有部分,我在这里使用了所有可见细胞的交集计算,

找到可见的IndexPath,使用它来获取自定义表格单元格类型的单元格.
这也可以通过visibleCells实现,但我已经避免了,因为你可以有多种类型的单元格有图像,文本或其他东西.

  1. func scrollViewDidScroll(_ scrollView: UIScrollView) {
  2. let indexPaths = self.FeedTableView.indexPathsForVisibleRows
  3. var cells = [Any]()
  4. for ip in indexPaths!{
  5. if let videoCell = self.FeedTableView.cellForRow(at: ip) as? VideoCellTableViewCell{
  6. cells.append(videoCell)
  7. }
  8. }
  9. let cellCount = cells.count
  10. if cellCount == 0 {return}
  11. if cellCount == 1{
  12. if visibleIP != indexPaths?[0]{
  13. visibleIP = indexPaths?[0]
  14. }
  15. if let videoCell = cells.last! as? VideoCellTableViewCell{
  16. self.playVideoOnTheCell(cell: videoCell,indexPath: (indexPaths?.last)!)
  17. }
  18. }
  19. if cellCount >= 2 {
  20. for i in 0..<cellCount{
  21. let cellRect = self.FeedTableView.rectForRow(at: (indexPaths?[i])!)
  22. let intersect = cellRect.intersection(self.FeedTableView.bounds)
  23. // curerntHeight is the height of the cell that
  24. // is visible
  25. let currentHeight = intersect.height
  26. print("\n \(currentHeight)")
  27. let cellHeight = (cells[i] as AnyObject).frame.size.height
  28. // 0.95 here denotes how much you want the cell to display
  29. // for it to mark itself as visible,// .95 denotes 95 percent,// you can change the values accordingly
  30. if currentHeight > (cellHeight * 0.95){
  31. if visibleIP != indexPaths?[i]{
  32. visibleIP = indexPaths?[i]
  33. print ("visible = \(indexPaths?[i])")
  34. if let videoCell = cells[i] as? VideoCellTableViewCell{
  35. self.playVideoOnTheCell(cell: videoCell,indexPath: (indexPaths?[i])!)
  36. }
  37. }
  38. }
  39. else{
  40. if aboutToBecomeInvisibleCell != indexPaths?[i].row{
  41. aboutToBecomeInvisibleCell = (indexPaths?[i].row)!
  42. if let videoCell = cells[i] as? VideoCellTableViewCell{
  43. self.stopPlayBack(cell: videoCell,indexPath: (indexPaths?[i])!)
  44. }
  45.  
  46. }
  47. }
  48. }
  49. }
  50. }

使用这些方法来处理播放.

  1. func playVideoOnTheCell(cell : VideoCellTableViewCell,indexPath : IndexPath){
  2. cell.startPlayback()
  3. }
  4.  
  5. func stopPlayBack(cell : VideoCellTableViewCell,indexPath : IndexPath){
  6. cell.stopPlayback()
  7. }
  8.  
  9. func tableView(_ tableView: UITableView,didEndDisplaying cell: UITableViewCell,forRowAt indexPath: IndexPath) {
  10. print("end = \(indexPath)")
  11. if let videoCell = cell as? VideoCellTableViewCell {
  12. videoCell.stopPlayback()
  13. }
  14. }
  15. }

如果有兴趣,you can check the demo here

猜你在找的Swift相关文章