繁体   English   中英

AVPlayer 视频一直没有加载

[英]AVPlayer videos not loading all the time

我的应用程序使用 AVPlayer 播放我的视频,但它们并非每次都播放。 我只是在某些视频上看到黑屏。 然而,不播放的视频每次都不一样。 我不明白为什么一分钟它起作用,然后下一分钟它不起作用。 我正在使用HCVimeoVideoExtractor以便从 Vimeo 中提取视频。

import UIKit
import HCVimeoVideoExtractor
import Foundation
import AVKit
import AVFoundation

class Arms : UITableViewController{

    @IBOutlet var Tableview: UITableView!

    //video outlet
    let playerController = AVPlayerViewController()

    //@IBOutlet var mypic: UIImageView!

    let sectionName = ["Day 0","Day 1","Day 2","Day 3","Day 4","Day 5","Day 6","7"]

    let foodTitleArray = ["1 and a Half Cable Bicep Curl", "Barbell Bicep Curls", "Cable Bicep Curl","Dumbbell Bicep Curl","Bench Press Close Grip","Across The Body Tricep Extension","EZ Bar Curl", "Dumbbell Hammer Curl", "Low Pulley Cable Curl", "Preacher Curl Machine", "Skull Crusher", "Straight Bar Tricep Extension", "Rope Tricep Extension"]

    let foodImageArray = ["Bicep Curl 1 and half Cable", "Bicep Curl Barbell", "Bicep Curl Cable","Bicep Curl Dumbbell","Close Grip Bench Press","Cross body tricep extension","EZ Bar Curl", "Hammer Curl Dumbbell", "Low Cable Pulley Curl", "Preacher Curl Machine", "Skull Crusher", "Tricep extension Cable", "Tricep Extension rope"]


    var rowselected = Int()


    //-----vids-----
    //video links
    var calledVideo: String?

    let vids = ["https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345","https://vimeo.com/12345", "https://vimeo.com/12345", "https://vimeo.com/12345", "https://vimeo.com/12345"]
    //-----vids-----


    override func viewDidLoad() {
        super.viewDidLoad()
    }


    @IBAction func Back(_ sender: Any) {

        NotificationCenter.default.removeObserver(self)

        self.dismiss(animated: true, completion: nil)
    }


    //setting up tableview rows
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //return sectionName.count
        return foodTitleArray.count
    }


    //what cell is & how it looks
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = Tableview.dequeueReusableCell(withIdentifier: "cellarms") as! UITableViewCell1


        // cell.foodImage.image = UIImage(named: foodImageArray[indexPath.row] + ".jpg") //this is origionally how memory images are used added to cell. this way caches the images building memory.
        cell.foodTitle.text = foodTitleArray[indexPath.row] //this is how to the uitableviews titles are added to cells

        //shows the images in cells without storing image in cache
        let bundlePath = Bundle.main.path(forResource: foodImageArray[indexPath.row], ofType: "jpg")
        let image = UIImage(contentsOfFile: bundlePath!)
        cell.foodImage.image = image

        return (cell)
    }


    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        rowselected = indexPath.row

        //indexpath.row is the code to get a number of the row selected this number then is selected from vids array and sets calledvideo to this number.
        print(indexPath.row)
        let number = indexPath.row
        calledVideo = vids[number]
        print(calledVideo)
        geturl()


        //making desleected row not highlighted
        tableView.deselectRow(at: indexPath, animated: true)
    }

    //Getting url info for video by using exractor
    func geturl() {
        if let url = URL(string: calledVideo!) {
            HCVimeoVideoExtractor.fetchVideoURLFrom(url: url, completion: { ( video:HCVimeoVideo?, error:Error?) -> Void in
                if let err = error {
                    DispatchQueue.main.async() {
                        let alert = UIAlertController(title: "Error", message: err.localizedDescription, preferredStyle: .alert)
                        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                        self.present(alert, animated: true, completion: nil)
                    }
                    return
                }


                guard let vid = video else {
                    print("Invalid video object")
                    return
                }



                //play video
                let player = AVPlayer(url: vid.videoURL[.Quality360p]!)
                self.playerController.player = player
                self.present(self.playerController, animated: true) {
                    player.play()
                }
            })   
        }
    }
}

这是一个不同的视频,每次在我身上都会被取消。 这似乎是完全随机的。 以下是取消视频时发生在我身上的错误示例:

Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://gcs-vimeo.akamaized.net/exp=1581445783~acl=%2Fvimeo-prod-skyfire-std-us%2F01%2F3120%2F14%2F365604762%2F1507711789.mp4~hmac=ac26b711525132b93ce5b4c33db5f04efc84feab53f3c07ec324d15962a9f5dd/vimeo-prod-skyfire-std-us/01/3120/14/365604762/1507711789.mp4?source=1, NSErrorFailingURLKey=https://gcs-vimeo.akamaized.net/exp=1581445783~acl=%2Fvimeo-prod-skyfire-std-us%2F01%2F3120%2F14%2F365604762%2F1507711789.mp4~hmac=ac26b711525132b93ce5b4c33db5f04efc84feab53f3c07ec324d15962a9f5dd/vimeo-prod-skyfire-std-us/01/3120/14/365604762/1507711789.mp4?source=1, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <A7D7517F-1F77-495B-80A1-2F61FE5B723D>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <A7D7517F-1F77-495B-80A1-2F61FE5B723D>.<1>, NSLocalizedDescription=cancelled} [-999]

首先,您应该在打印“无效视频对象”时显示警报,以便用户也获得此信息。

您尝试流式传输视频。 有时这可能会立即开始,但大多数情况下玩家需要一些时间来缓冲前几秒钟才能玩。

您需要观察玩家 currentItem 的status 这将显示您的播放器正在做什么,是否正在加载、加载失败或准备就绪。 当状态变为“readyToPlay”时,您可以调用playerController.play()

如何观察此属性如下所示: https : //stackoverflow.com/a/47787854

编辑:观察者实现
在你的 ViewController 类中声明这个变量:

var observer: NSKeyValueObservation? {
    willSet {
        guard let observer = observer else { return }
        observer.invalidate()
    }
}

替换此代码:

//play video
let player = AVPlayer(url: vid.videoURL[.Quality360p]!)
self.playerController.player = player
self.present(self.playerController, animated: true) {
    player.play()
}

具有以下内容:

let url = vid.videoURL[.Quality360p]!
// Create asset to be played
let asset = AVAsset(url: url)

let assetKeys = [
    "playable",
    "hasProtectedContent"
]
// Create a new AVPlayerItem with the asset and an
// array of asset keys to be automatically loaded
let playerItem = AVPlayerItem(asset: asset,
                          automaticallyLoadedAssetKeys: assetKeys)

// Associate the player item with the player
let player = AVPlayer(playerItem: playerItem)
self.playerController.player = player

// Register as an observer of the player item's status property
self.observer = playerItem.observe(\.status, options:  [.new, .old], changeHandler: { (playerItem, change) in
    if playerItem.status == .readyToPlay {
        self.present(self.playerController, animated: true) {
            player.play()
        }
    }
})

该代码无法按原样进行测试,因此仅通过心理分析...

修改后的代码部分是在您的//play video评论之后。 它需要明确地转发 UI 操作并运行到主线程:

//play video
DispatchQueue.main.async {
    let player = AVPlayer(url: vid.videoURL[.Quality360p]!)
    self.playerController.player = player
    self.present(self.playerController, animated: true) {
        player.play()
    }
}

当您滚动tableview时,您的链接已更改。 滚动后检查您的url 如果一切正常,请尝试下面的代码。

对于快速:

let url = URL(string: "https://vimeo.com/254597739")!
HCVimeoVideoExtractor.fetchVideoURLFrom(url: url, completion: { ( video:HCVimeoVideo?, error:Error?) -> Void in                
    if let err = error {                    
       print("Error = \(err.localizedDescription)")                    
       return
    }

    guard let vid = video else {
        print("Invalid video object")
        return
    }

    print("Title = \(vid.title), url = \(vid.videoURL), thumbnail = \(vid.thumbnailURL)")

    if let videoURL = vid.videoURL[.Quality540p] {
        let player = AVPlayer(url: videoURL)
        let playerController = AVPlayerViewController()
        playerController.player = player
        self.present(playerController, animated: true) {
            player.play()
        }
    }                            
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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