为啥我的视频没有显示在我使用 AVPlayer 的滚动视图的单元格中

Posted

技术标签:

【中文标题】为啥我的视频没有显示在我使用 AVPlayer 的滚动视图的单元格中【英文标题】:Why aren't my videos showing in cells in my scroll view with AVPlayer为什么我的视频没有显示在我使用 AVPlayer 的滚动视图的单元格中 【发布时间】:2020-01-07 10:30:53 【问题描述】:

我知道我的代码目前还没有效率,我只是希望它在优化之前真正工作。

基本上我有一个函数 FeaturedPostsManager.shared.getFeaturedPosts 从我的服务器获取视频并将其存储在应用程序的缓存中并将本地 url 存储到视频。在我的代码中,我为两个不同的视频做了两次,所以我有两个指向两个不同视频的网址。然后我将它们添加到我的自定义数据数组中,以便我的滚动视图为每个单元格展开,并将其各自的视频添加到它的单元格(例如,视频一到单元格一,视频二到单元格二)到 AVPlayer。没有抛出任何错误,只是什么都没有显示,这条消息给了我:

The behavior of the UICollectionViewFlowLayout is not defined because:
2020-01-07 09:48:05.095012+0000 Clipify[9131:368986] the item height must be less than the 
height of the UICollectionView minus the section insets top and bottom values, minus the 
content insets top and bottom values.
2020-01-07 09:48:05.095574+0000 Clipify[9131:368986] The relevant UICollectionViewFlowLayout 
instance is <UICollectionViewFlowLayout: 0x7f8be8525c20>, and it is attached to 
<UICollectionView: 0x7f8be9063a00; frame = (16 150; 343 171.667); clipsToBounds = YES; 
gestureRecognizers = <NSArray: 0x600003f4c1e0>; layer = <CALayer: 0x60000319b100>; 
contentOffset: 0, 0; contentSize: 0, 0; adjustedContentInset: 0, 0, 0, 0; layout: 
<UICollectionViewFlowLayout: 0x7f8be8525c20>; dataSource: <Clipify.HomeViewController: 
0x7f8be850c240>>.

我不知道这是否意味着什么,但这是我的完整代码:

import UIKit
import AVKit
import Firebase

struct CustomData 
    var title: String
    var image: UIImage
    var url: String


var videoURL = ""

class HomeViewController: UIViewController 

    var itemOne: String?
    var itemTwo: String?

override func viewDidLoad() 
    super.viewDidLoad()

    view.addSubview(collectionView)
    collectionView.backgroundColor = .white
    collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: 150).isActive = true
    collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16).isActive = true
    collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16).isActive = true
    collectionView.heightAnchor.constraint(equalTo: collectionView.widthAnchor, multiplier: 0.5).isActive = true 

    collectionView.delegate = self
    collectionView.dataSource = self

    getPosts()


func getPosts()
    FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion:   url in
        if url != nil
            self.itemOne = url!
            print(self.itemOne)
        else
            print("error")
        
    )
    FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion:   url in
        if url != nil
            self.itemTwo = url!
            print(self.itemTwo)
        else
            print("error")
        
    )


var data: [CustomData] 
    return [
        CustomData(title: "Test", image: #imageLiteral(resourceName: "ss-1"), url: itemOne!),
        CustomData(title: "Test2", image: #imageLiteral(resourceName: "done-button"), url: itemTwo!)
    ]


fileprivate let collectionView: UICollectionView = 
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.register(CustomCell.self, forCellWithReuseIdentifier: "cell")
    return cv
()


extension HomeViewController: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource

public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    return CGSize(width: collectionView.frame.width, height: collectionView.frame.width)

public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return data.count


public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
    cell.data = self.data[indexPath.row]
    return cell



class CustomCell: UICollectionViewCell

    var data: CustomData?
        didSet
            guard let data = data else  return 
            bg.image = data.image
        
    

override init(frame: CGRect) 
    super.init(frame: frame)

    if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) 
        let player = AVPlayer(url: url)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = contentView.bounds
        contentView.layer.addSublayer(playerLayer)
        player.play()
    


required init?(coder: NSCoder) 
    fatalError("init(coder:) has not been implemented")


【问题讨论】:

您确定单元格可见吗?尝试用一些图像而不是AVPlayerLayer 显示UIImageView 当我使用图像而不是视频时,它工作得非常好。所以滚动视图和单元格/数据都运行良好,只是当我尝试涉及视频时。我可以显示我用来显示图像的代码吗? 【参考方案1】:

你需要在这里重新加载

FeaturedPostsManager.shared.getFeaturedPosts(index: 0, completion:   url in
    if url != nil
        self.itemOne = url!
        print(self.itemOne)
        DispatchQueue.main.async  self.collectionView.reloadData() 
    else
        print("error")
    
)
FeaturedPostsManager.shared.getFeaturedPosts(index: 1, completion:   url in
    if url != nil
        self.itemTwo = url!
        print(self.itemTwo)
        DispatchQueue.main.async  self.collectionView.reloadData() 
    else
        print("error")
    
)

override init(frame: CGRect) 被调用一次。所以添加

func reload() 
 if let unwrappedURLString = data?.url, let url = URL(string: unwrappedURLString) 
    let player = AVPlayer(url: url)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = contentView.bounds
    contentView.layer.addSublayer(playerLayer)
    player.play()
 

然后

var data: CustomData?
    didSet
        guard let data = data else  return 
        bg.image = data.image
        self.reload()
    

【讨论】:

这可能是我应该遇到的另一个问题,所以谢谢你,但仍然没有解决问题,我认为这与滚动视图中的数据有关. 不,它成功获取了 url 并打印出了带有本地 url 的 itemOne,因此 itemOne 中存储了一个 url 字符串。除非它在滚动视图更新后存储 url?我什至不确定该代码是否会在滚动视图单元格中显示视频。 这将替换滚动视图所需的override init(frame: CGRect) 是否有任何其他方法可以重新加载它而不用reload() 替换它? 没关系!只要有两个功能,就可以了,非常感谢!

以上是关于为啥我的视频没有显示在我使用 AVPlayer 的滚动视图的单元格中的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer 层不显示视频内容

无法使用带有 Swift 的 AVPlayer 播放视频

AVFoundation - 视频没有在 AVplayer 的 AVMutablecomposition 中播放

防止 AVPlayer 取消背景音频

带有流式视频或 NSFileHandle 的 AVPlayer

为啥使用 AVCaptureSession、AVAssetWriter 和 AVPlayer 录制和回放视频会卡顿?