循环迅速的视频avplayer swift

时间:2015-07-20 14:56:38

标签: ios swift

我试过这个:How do you loop AVPlayer in Swift?但是当视频最终崩溃时

我的代码:

resolve.loader

我的循环代码

 super.viewDidLoad()
    var moviePlayer : MPMoviePlayerController?
    let myPlayerView = UIView(frame: self.view.bounds)
    myPlayerView.backgroundColor = UIColor.blackColor()
    view.addSubview(myPlayerView)

    var urlpath = NSBundle.mainBundle().pathForResource("bgivd", ofType: "mp4")
    let url:NSURL = NSURL.fileURLWithPath(urlpath!)!

    // Make a player
    let myPlayer = AVPlayer(URL: url)
    myPlayer.play()


    let avLayer = AVPlayerLayer(player: myPlayer)
    avLayer.frame = myPlayerView.bounds
    myPlayerView.layer.addSublayer(avLayer)
    myPlayerView.superview?.sendSubviewToBack(myPlayerView)

错误日志: http://pastebin.com/bN2fc29G

由于某种原因,stackoverflow中的代码故障因此我把它推入了pastebin

1 个答案:

答案 0 :(得分:2)

前一段时间我自己定制了一个循环播放AVPlayer,随时使用/评论!

protocol LoopingPlayerProgressDelegate: class {
    func loopingPlayer(loopingPlayer: LoopingPlayer, didLoad percentage: Float)
    func loopingPlayer(loopingPlayer: LoopingPlayer, didFinishLoading succeeded: Bool)
}

class LoopingPlayer: AVPlayer {

    weak var progressDelegate: LoopingPlayerProgressDelegate?

    var loopCount: Double = 0
    var timer: NSTimer?

    override init() {
        super.init()
        self.commonInit()
    }

    override init(URL url: NSURL!) {
        super.init(URL: url)
        self.commonInit()
    }

    override init(playerItem item: AVPlayerItem!) {
        super.init(playerItem: item)
        self.commonInit()
    }

    func commonInit() {
        self.addObserver(self, forKeyPath: "currentItem", options: .New, context: nil)
        self.actionAtItemEnd = .None
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"playerDidPlayToEndTimeNotification:", name:AVPlayerItemDidPlayToEndTimeNotification, object:nil)
        if mutePlayers == true {
            self.volume = 0.0
        }
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"mute", name:"MutePlayers", object:nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"unmute", name:"UnmutePlayers", object:nil)
    }

    deinit {
        self.timer?.invalidate()
        self.removeObserver(self, forKeyPath: "currentItem")
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

    func mute() {
        self.volume = 0.0
    }

    func unmute() {
        self.volume = 1.0
    }

    var playableDuration: CMTime {
        get {
            if let item: AnyObject = self.currentItem?.loadedTimeRanges?.first {
                if let timeRange = item.CMTimeRangeValue {
                    let playableDuration = CMTimeAdd(timeRange.start, timeRange.duration)
                    return playableDuration
                }
            }
            return kCMTimeZero
        }
    }

    var loadingProgress: Float {
        get {
            if (self.currentItem == nil) {
                self.timer?.invalidate()
                self.progressDelegate?.loopingPlayer(self, didFinishLoading: false)
                return 0
            }
            let playableDurationInSeconds = CMTimeGetSeconds(self.playableDuration)
            let totalDurationInSeconds = CMTimeGetSeconds(self.currentItem.duration)
            if (totalDurationInSeconds.isNormal) {
                var progress = Float(playableDurationInSeconds / totalDurationInSeconds)
                self.progressDelegate?.loopingPlayer(self, didLoad: progress)
                if (progress > 0.90) {
                    self.progressDelegate?.loopingPlayer(self, didFinishLoading: true)
                    self.timer?.invalidate()
                }
                return progress
            }
            return 0
        }
    }

    func playerDidPlayToEndTimeNotification(notification: NSNotification) {
        let playerItem: AVPlayerItem = notification.object as! AVPlayerItem
        if (playerItem != self.currentItem) {
            return
        }
        self.seekToTime(kCMTimeZero)
        self.play()
        loopCount += 1
    }

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
        if keyPath == "currentItem" {
            self.timer?.invalidate()
            self.timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "loadingProgress", userInfo: nil, repeats: true)
        }
    }
}

我已经做了一段时间,因此它可能有点尘土飞扬。对不起!

它也适用于HLS文件;)

希望这会有所帮助!