简体   繁体   中英

AVPlayer in UITableViewCell is black and can't view

I've gone through every post and article but have yet to solve my problem and I'm not sure why. I have a table view which if the piece of content is an image, it will show an image in the TableViewCell, otherwise it will show a video in it. For the video, I have the link printed so it's there and the link works, but for some reason in the TableViewCell the video doesn't play and it's just black.

Here is the code for the TableViewCell:

import UIKit
import AVFoundation

class ViewImageCell: UITableViewCell {

var avQueuePlayer   : AVQueuePlayer?
var avPlayerLayer   : AVPlayerLayer?



let postContentView: UIView = {
    let view = UIView()

    return view
}()

   let contentImageView: UIImageView = {
       let imageView = UIImageView()
       imageView.translatesAutoresizingMaskIntoConstraints = false
       imageView.layer.masksToBounds = true
       imageView.autoresizesSubviews = true
       imageView.contentMode = .scaleAspectFit
       imageView.image = UIImage(named: "ProfileIcon")

      return imageView
   }()


override func awakeFromNib() {
    super.awakeFromNib()


    // Initialization code


}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}


override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: .default, reuseIdentifier: reuseIdentifier)

    addSubview(postContentView)
    addSubview(contentImageView)
    postContentView.anchor(top: self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
    contentImageView.anchor(top: self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
}


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

func addPlayer(for url: URL) {
    self.avQueuePlayer = AVQueuePlayer(url: url)
    self.avPlayerLayer = AVPlayerLayer(player: self.avQueuePlayer!)
    self.avPlayerLayer?.frame = self.postContentView.bounds
    self.avPlayerLayer?.fillMode = .both
    self.postContentView.layer.addSublayer(self.avPlayerLayer!)
    self.avQueuePlayer?.play()
}

   func bindData(content: NSDictionary) {

    if content[kPICTURE] != nil {

        let data = content[kPICTURE] as! String
        let picData = NSData(base64Encoded: data, options: [])

        if let image = UIImage(data: picData! as Data) {
            contentImageView.image = image
        } else {
            print("There was an error loading the pic")
        }

    } else {

    }

    if content[kVIDEO] != nil {
        contentImageView.isHidden = true
        let videoData = content[kVIDEO] as! String
           let url = NSURL(fileURLWithPath: videoData)
        addPlayer(for: url as URL)
           print("Here is a video")

    } else {
        //
    }

}
}

Here is a piece of the code for the TableView:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: imageCellID, for: indexPath) as! ViewImageCell

        if singleContent != nil {

            cell.bindData(content: singleContent)

        } else {
            print("Can't find singleContent")
        }

        return cell
    }




    return UITableViewCell()
}

Let me know if you have any questions and need more clarification. All help is greatly appreciated.

EDIT: Here is an example of the type of video path I'm using. I'm taking this from my Firebase Database, not a local file in my project.

file:///private/var/mobile/Containers/Data/PluginKitPlugin/49C0EAA4-9825-4D06-8CFB-6136FF5BCC3C/tmp/trim.AA010490-81F0-43C8-AE8A-1029D5AF55E1.MOV

I also get the error code below. I looked and think it means that the file doesn't exist, but I can still view that file else where in a different view it plays the video.

NSURLConnection finished with error - code -1100

Here is where the video path is stored in the database, not using Firebase Storage at all. 在此处输入图片说明

If you want to play video URL in webview use below code: (manage code as per your requirement)

func bindData(content: NSDictionary)
{

    if content[kPICTURE] != nil {

        let data = content[kPICTURE] as! String
        let picData = NSData(base64Encoded: data, options: [])

        if let image = UIImage(data: picData! as Data) {
            contentImageView.image = image
        } else {
            print("There was an error loading the pic")
        }

    } else {

    }

    if content[kVIDEO] != nil {
        contentImageView.isHidden = true
        let videoData = content[kVIDEO] as! String

        //let url = NSURL(fileURLWithPath: videoData)


        let storageRef = Storage.storage().reference(forURL: <YourFilePathURL>)
storageRef.getData(maxSize: INT64_MAX) { (data, error) in
    if let error = error {
        print("Error downloading image data: \(error)")
        return
    }
    storageRef.getMetadata(completion: { (metadata, metadataErr) in

        if let error = metadataErr {
            print("Error downloading metadata: \(error)")
            return
        }
        if (metadata?.contentType == "image/gif") {
            print("It is Gif")
        } else {
            let downloadUrl = metadata?.downloadURL()
            if downloadUrl != nil{
 print(downloadUrl)
       //You will get your Video Url Here
        self.PlayVideoInWEbView(downloadUrl)
        print("Here is a video")

    }

        }
    })
}
    } else {
        //
    }

}

func PlayVideoInWEbView(_ videoURL : String)
{
    let myWebView:UIWebView = UIWebView(frame: CGRect(x: 20, y: 20, width: self.viewCell.frame.width, height: 200))



    myWebView.delegate = self

    let myURL = URL(string: videoURL)
    let myURLRequest:URLRequest = URLRequest(url: myURL!)
    myWebView.loadRequest(myURLRequest)

    self.viewCell.addSubview(myWebView)

}

@Jaqueline Try like below If you have or stored a recorded video into the local document directory.

func bindData(content: NSDictionary) {

    if content[kPICTURE] != nil {

        let data = content[kPICTURE] as! String
        let picData = NSData(base64Encoded: data, options: [])

        if let image = UIImage(data: picData! as Data) {
            contentImageView.image = image
        } else {
            print("There was an error loading the pic")
        }

    } else {
    }

    if content[kVIDEO] != nil {
        contentImageView.isHidden = true
        //let videoData = content[kVIDEO] as! String

        //let url = NSURL(fileURLWithPath: videoData)

        let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
        let url = NSURL(fileURLWithPath: path)
        let filePath = url.appendingPathComponent("/video.mp4")!.path

        let videoData = URL(fileURLWithPath: filePath)

        //addPlayer(for: url as URL) //remove this line and add below line

        self.PlayVideoInWEbView(videoData)
        print("Here is a video")

    } else {
        //
    }
}

func PlayVideoInWEbView(_ videoURL : String) {
    let myWebView:WKWebView = WKWebView(frame: CGRect(x: 20, y: 20, width: self.viewCell.frame.width, height: 200))

    //myWebView.delegate = self

    myWebView.uiDelegate = self
    myWebView.navigationDelegate = self

    let myURL = URL(string: videoURL)
    let myURLRequest:URLRequest = URLRequest(url: myURL!)
    //myWebView.loadRequest(myURLRequest)

    myWebView.load(myURLRequest)

    self.viewCell.addSubview(myWebView)
}

//MARK: - WKNavigationDelegate
extension YourViewControllerClass: WKNavigationDelegate {

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        //Here hide your loading indicator
    }

    func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {

        DDLogDebug("webViewWebContentProcessDidTerminate ==> \(webView)")
    }

    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        //Here hide your loading indicator
    }
}

Hope it will help your required output!!!.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM