Sener
Sener

Reputation: 129

same video in every five cells

I created a UICollectionView named UserProfileController. I created a UICollectionViewCell named UserProfilePhotoCell. I created avplayer in UserProfilePhotoCell. When you click on Avplayer the video starts.

When I click on the 1st AVPlayer on the cell, The first, fifth, ninth cells play AVplayer.

How can I fix?

Issue Video = https://ibb.co/bMwOAe

import UIKit
import Alamofire
import AVKit
import AVFoundation
class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    let screen = ScreenProp()
    var posts = [ProfileVideo]()

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = "Profil Detay"
        collectionView?.backgroundColor = .white

        collectionView?.register(UserProfileHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerID")
        collectionView?.delegate = self
        collectionView?.dataSource = self
        collectionView?.register(UserProfilePhotoCell.self, forCellWithReuseIdentifier: "cellId")

        veriCek()
    }

    var user: User?
    func veriCek(){

        //http post başlangıç

       // LoadingOverlay.shared.showOverlay(view: UIApplication.shared.keyWindow!)
//
//        guard let confirm = phoneInput.text else {return}
        let defaults = UserDefaults.standard
        let userID = defaults.integer(forKey: "userID")
        let acToken = defaults.string(forKey: "acToken")


        let parameters: Parameters = [
            "userID": userID,
            "acToken": acToken ?? ""
        ]

        Alamofire.request("********************************", method: .post, parameters: parameters).validate().responseJSON { response in
            switch response.result {
            case .success:
                print(response.data!)
                if let result = response.result.value {
                    let json = result as! NSDictionary
                    print(json)

                    let dataArray = json["sonuclar"] as! NSArray;

                    print("Data items count: \(dataArray.count)")
                    for item in dataArray { // loop through data items

                        let obj = item as! NSDictionary
//                        let profileVideo = ProfileVideo(dictionary: obj)
//                        print(profileVideo.artistName)

                        let artistName = obj.value(forKey: "artistName") as! String
                        let commentlikes = obj.value(forKey: "commentlikes") as! String
                        let likeStatus = obj.value(forKey: "likeStatus") as! String
                        let name = obj.value(forKey: "name") as! String
                        let profilePics = obj.value(forKey: "profilePics") as! String
                        let time = obj.value(forKey: "time") as! String
                        let userID = obj.value(forKey: "userID") as! String
                        let username = obj.value(forKey: "username") as! String
                        let videoContent = obj.value(forKey: "videoContent") as! String
                        let videoID = obj.value(forKey: "videoID") as! String
                        let videoLikes = obj.value(forKey: "videoLikes") as! String
                        let videoName = obj.value(forKey: "videoName") as! String
                        let videoPath = obj.value(forKey: "videoPath") as! String
                        let view = obj.value(forKey: "view") as! String

                        let post = ProfileVideo(artistName: artistName, commentlikes: commentlikes, likeStatus: likeStatus, name: name, profilePics: profilePics, time: time, userID: userID, username: username, videoContent: videoContent, videoID: videoID, videoLikes: videoLikes, videoName: videoName, videoPath: videoPath, view: view, status: 0)

                        self.posts.append(post)

                    }


                    self.user = User(dictionary: json as! [String : Any])
                    self.navigationItem.title = self.user?.username
                    self.collectionView?.reloadData()

                }



            case .failure(let error):
                print(error)
            }
        }

        // http post bitiş

    }




    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerID", for: indexPath) as! UserProfileHeader

        header.user = self.user

        return header
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return posts.count
    }


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! UserProfilePhotoCell
        var dizi = posts[indexPath.item]

        print("\(indexPath.item) = \(dizi.status)")

        cell.post = dizi
        return cell
    }

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        referenceSizeForHeaderInSection section: Int) -> CGSize{
        return CGSize(width: view.frame.width ,height: CGFloat(screen.heightHesap(x: 246)))
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let width = view.frame.width

        return CGSize(width: width, height: 500)
    }



}

struct User {
    let name: String
    let username: String
    let profileImageUrl: String
    let follow: String
    let follower: String
    let videoCount: String

    init(dictionary: [String: Any]) {
        self.username = dictionary["username"] as! String
        self.profileImageUrl = dictionary["profilePics"] as! String
        self.name = dictionary["name"] as! String
        self.follow = dictionary["follow"] as! String
        self.follower = dictionary["follower"] as! String
        self.videoCount = dictionary["videoCount"] as! String
    }

}

struct ProfileVideo {
    let artistName: String
    let commentlikes: String
    var likeStatus: String
    let name: String
    let profilePics: String
    let time: String
    let userID: String
    let username: String
    let videoContent: String
    let videoID: String
    let videoLikes: String
    let videoName: String
    let videoPath: String
    let view: String
    var status: Int
}

UserProfilePhotoCell

import UIKit
import AVKit
import AVFoundation
import Alamofire

class UserProfilePhotoCell: UICollectionViewCell {
    var screen = ScreenProp()

    var playerLayer = AVPlayerLayer()
    var player = AVPlayer()
    var moviePlayerController = AVPlayerViewController()
    let defaults = UserDefaults.standard
    var status = 0

    let videoHeader: UIImageView = {
        let imageView = UIImageView(image: #imageLiteral(resourceName: "videoHeader1"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .red
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let videoFooter: UIImageView = {
        let imageView = UIImageView(image:#imageLiteral(resourceName: "videoFooter"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .none
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let clapsDeactive: UIImageView = {
        let imageView = UIImageView(image: #imageLiteral(resourceName: "applause"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .none
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let clapsActive: UIImageView = {
        let imageView = UIImageView(image: #imageLiteral(resourceName: "applause_on"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .none
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let comment: UIImageView = {
        let imageView = UIImageView(image: #imageLiteral(resourceName: "comments"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .none
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let videoName: UILabel = {
        let textView = UILabel()
        textView.text = "Video Adı";
        textView.textColor = CustomColor.white;
        textView.font = CustomFont.textStyle16;
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    let userName: UILabel = {
        let textView = UILabel()
        textView.text = "username";
        textView.textColor = CustomColor.bblack;
        textView.font = CustomFont.textStyle16;
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    let location: UILabel = {
        let textView = UILabel()
        textView.text = "location";
        textView.textColor = CustomColor.battleshipGreyTwo;
        textView.font = CustomFont.textStyle16;
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    let profilePhoto: UIImageView = {
        var screen1 = ScreenProp()

        let imageView = UIImageView(image: #imageLiteral(resourceName: "profile_photo"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .white
        imageView.contentMode = .scaleToFill
        imageView.layer.cornerRadius = CGFloat(screen1.heightHesap(x: 37)/2)
        imageView.clipsToBounds = true
        return imageView
    }()

    let videoCover: UIImageView = {
        var screen1 = ScreenProp()

        let imageView = UIImageView(image: #imageLiteral(resourceName: "video-sample"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.backgroundColor = .white
        imageView.contentMode = .scaleToFill
        imageView.clipsToBounds = true
        return imageView
    }()

    let clapsText: UILabel = {
        let textView = UILabel()
        textView.text = "0";
        textView.textColor = CustomColor.bblack;
        textView.font = CustomFont.textStyle3;
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    let commentsText: UILabel = {
        let textView = UILabel()
        textView.text = "0";
        textView.textColor = CustomColor.bblack;
        textView.font = CustomFont.textStyle3;
        textView.textAlignment = .center
        textView.translatesAutoresizingMaskIntoConstraints = false
        return textView
    }()

    let content: UITextView = {
        let textView = UITextView()
        textView.text = "Donec pretium est sit amet ipsum fringilla feugiat. Aliquam erat volutpat. Maecenas scelerisque,";
        textView.textColor = CustomColor.cloudyBlue;
        textView.font = CustomFont.textStyle3;
        textView.textAlignment = .left
        textView.isEditable = false
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.isScrollEnabled = false
        return textView
    }()

    var set = 0

    var ratePlayer = 0

    var post: ProfileVideo? {
        didSet{
            print(post?.status)
            if(set == 0){
               // kur(str: (post?.videoPath)!)
                }

            videoName.text = "\(post?.artistName ?? "") - \(post?.videoName ?? "")"
            userName.text = post?.username
            clapsText.text = post?.videoLikes as? String
            commentsText.text = post?.commentlikes
            content.text = post?.videoContent
            var url = URL(string: post?.profilePics ?? "")
            ImageLoader.image(for: url!) { image in
                self.profilePhoto.image = image
            }
            if(post?.likeStatus == "0"){
                status = 1
                self.clapsDeactive.image = UIImage(named: "applause")

            }else{
                status = 0
                self.clapsDeactive.image = UIImage(named: "applause_on")
            }
            set = set + 1
        }
    }

    func kur(str: String){
        print("asdjvhsagdvjsakd")
        let videoURL = URL(string: str)


               // var myUrl = post.image // post.image is image url

                let fileUrl = videoURL

               // aPlayer = AVPlayer(URL: fileUrl as! URL)
                player = AVPlayer(url: fileUrl!)
                moviePlayerController.player = player
                moviePlayerController.view.frame = CGRect(x:0, y:37, width:frame.size.width, height:300)
                moviePlayerController.videoGravity = AVLayerVideoGravity.resizeAspectFill.rawValue
                moviePlayerController.view.sizeToFit()
                moviePlayerController.showsPlaybackControls = true
                addSubview(moviePlayerController.view)
                //moviePlayerController.player?.play()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
            addSubview(videoHeader)
            addSubview(videoName)
            addSubview(profilePhoto)
            addSubview(userName)
            addSubview(location)
            addSubview(videoFooter)
            addSubview(clapsDeactive)
            addSubview(comment)
            addSubview(clapsText)
            addSubview(commentsText)
            addSubview(content)
            addSubview(videoCover)

            setup()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(like(tapGestureRecognizer:)))
        clapsDeactive.isUserInteractionEnabled = true
        clapsDeactive.addGestureRecognizer(tapGestureRecognizer)

        let tapGestureRecognizer2 = UITapGestureRecognizer(target: self, action: #selector(playVideo(tapGestureRecognizer:)))
        videoCover.isUserInteractionEnabled = true
        videoCover.addGestureRecognizer(tapGestureRecognizer2)

        }

    func setup(){
        videoHeader.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: frame.size.width, height: CGFloat(screen.heightHesap(x: 37)))
        videoName.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 9)), paddingLeft: CGFloat(screen.widthHesap(x: 40)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        profilePhoto.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 360)), paddingLeft: CGFloat(screen.widthHesap(x: 20)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 37)), height: CGFloat(screen.heightHesap(x: 37)))
        userName.anchor(top: profilePhoto.topAnchor, left: profilePhoto.rightAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: CGFloat(screen.widthHesap(x: 11)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        location.anchor(top: userName.bottomAnchor, left: profilePhoto.rightAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: CGFloat(screen.widthHesap(x: 11)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        videoFooter.anchor(top: topAnchor, left: nil, bottom: nil, right: rightAnchor, paddingTop: CGFloat(screen.heightHesap(x: 356)), paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 180)), height: CGFloat(screen.heightHesap(x: 50)))
        clapsDeactive.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 9)), paddingLeft: CGFloat(screen.widthHesap(x: 29)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 33)), height: CGFloat(screen.heightHesap(x: 28)))
        comment.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 15)), paddingLeft: CGFloat(screen.widthHesap(x: 110)), paddingBottom: 0, paddingRight: 0, width: CGFloat(screen.widthHesap(x: 23)), height: CGFloat(screen.heightHesap(x: 23)))
        clapsText.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 17)), paddingLeft: CGFloat(screen.widthHesap(x: 67)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        commentsText.anchor(top: videoFooter.topAnchor, left: videoFooter.leftAnchor, bottom: nil, right: nil, paddingTop: CGFloat(screen.heightHesap(x: 17)), paddingLeft: CGFloat(screen.widthHesap(x: 142)), paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        var hesap = frame.size.width - CGFloat(screen.widthHesap(x: 40))
        content.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: CGFloat(screen.heightHesap(x: 420)), paddingLeft: CGFloat(screen.widthHesap(x: 20)), paddingBottom: 0, paddingRight: CGFloat(screen.widthHesap(x: 20)), width: hesap, height: CGFloat(screen.heightHesap(x: 50)))

        videoCover.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 37, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: frame.size.width, height: 300)

    }

    @objc func playVideo(tapGestureRecognizer: UITapGestureRecognizer)
    {
        kur(str: (post?.videoPath)!)
    }



    @objc func like(tapGestureRecognizer: UITapGestureRecognizer)
    {
        let userID = defaults.string(forKey: "userID")
        let acToken = defaults.string(forKey: "acToken")


        let parameters: Parameters = [
            "userID": userID ?? "",
            "acToken": acToken ?? "",
            "videoID": post?.videoID ?? "",
            "status": status,
            "videoUserID": post?.userID ?? ""
        ]

        Alamofire.request("***********************************", method: .post, parameters: parameters).validate().responseJSON { response in
            switch response.result {
            case .success:
                print(response.data!)
                if let result = response.result.value {
                    let json = result as! NSDictionary
                    let statusCode = json["statusCode"]
                    let status = json["status"]
                    var like = json["likeCount"] as? String

                    if(statusCode as? Int == 10){
                        print("Beğendim.")
                        self.post?.likeStatus = "1"
                        print(self.post?.likeStatus)
                        self.clapsDeactive.image = UIImage(named: "applause_on")
                        self.clapsText.text = like
                    }else{
                        print("Beğenemedim.")
                        self.post?.likeStatus = "0"
                        self.clapsDeactive.image = UIImage(named: "applause")
                        self.clapsText.text = like
                    }


                }


            case .failure(let error):
                print(error)
            }
        }

    }

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

Upvotes: 0

Views: 49

Answers (1)

Alpesh Desai
Alpesh Desai

Reputation: 313

Just use this code for play video in the cell with expect index. It will help you a lot and for other also ,

class UserProfilePhotoCell: UICollectionViewCell {

@IBOutlet var viewForVideo: UIView!
@IBOutlet var btnPlayVideo: UIButton!
var blockVideoPlay : ((_ sender : UIButton)->())?

override func awakeFromNib() {
        super.awakeFromNib()
removeSubLayerFromVideo()
        self.setupMoviePlayer()
}


@IBAction func btnPlayVideoCLK(_ sender: UIButton) {
        if blockVideoPlay != nil {
            blockVideoPlay!(sender)
        }
    }

    func removeSubLayerFromVideo() {
        if let layerArray = viewForVideo.layer.sublayers, layerArray.isEmpty {
            for layer in layerArray {
                if layer.name == "\(viewForVideo.tag)" {
                layer.removeFromSuperlayer()
                }
            }
        }
    }

    func setupMoviePlayer(){
        self.avPlayer = AVPlayer.init(playerItem: self.videoPlayerItem)
        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer?.videoGravity = AVLayerVideoGravity.resizeAspect
        avPlayerLayer?.name = "\(viewForVideo.tag)"
        avPlayer?.volume = 3
        avPlayer?.actionAtItemEnd = .none
        avPlayerLayer?.frame = CGRect(x: 0, y: 0, width: UIScreen.width, height: UIScreen.height)
        self.viewForVideo.backgroundColor = .clear
        self.viewForVideo.layer.insertSublayer(avPlayerLayer!, at: 0)

        // This notification is fired when the video ends, you can handle it in the method.
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.playerItemDidReachEnd(notification:)),
                                               name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                               object: avPlayer?.currentItem)
    }

    func stopPlayback(){
        if let player = self.avPlayer {
            if player.isPlaying {
                player.pause()
            }
        }  
    }

    func startPlayback(){
        self.avPlayer?.play()

    }

    // A notification is fired and seeker is sent to the beginning to loop the video again
    @objc func playerItemDidReachEnd(notification: Notification) {
        //let p: AVPlayerItem = notification.object as! AVPlayerItem
        //p.seek(to: kCMTimeZero)
        btnPlayVideo.isSelected = false
        self.avPlayer?.currentItem?.seek(to: kCMTimeZero, completionHandler: { (success) in
            if success {
                self.avPlayer?.pause()
            }
        })

    }
}

For View Controller use this code also you can post via var all data in the cell and from the cell, you can set URL path it works fine make sure when view Will Disappear you have to stop the player

    class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

   override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)
        for cell in mediaListCollection.visibleCells {
            if let cell = cell as? UserProfilePhotoCell {
                cell.stopPlayback()
            }
        }
    }



    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    var cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! UserProfilePhotoCell

    let url = URL(fileURLWithPath: path, isDirectory: true)
                        cell.videoPlayerItem = AVPlayerItem(url: url)
    cell.viewForVideo.tag = indexPath.row+1
    cell.blockVideoPlay = { (sender) -> Void in
    sender.isSelected = !sender.isSelected
                       if sender.isSelected {
                                cell.startPlayback()
                            }
                            else {
                                cell.stopPlayback()
                            }
    }

    }


    func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
            if let cell = cell as? UserProfilePhotoCell {
                cell.stopPlayback()
                        if cell.btnPlayVideo.isSelected {
                            cell.btnPlayVideo.isSelected = false
                        }
            }
        }
    }

Also use this extension for check player is currently playing or not

extension AVPlayer {
    var isPlaying: Bool {
        return rate != 0 && error == nil
    }
}

Upvotes: 2

Related Questions