Reputation: 168
I tried this one : How do you loop AVPlayer in Swift? but when video endst crashes
my code :
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)
my loop code
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: myPlayer.currentItem)
func playerItemDidReachEnd(notification: NSNotification) {
myPlayer.seekToTime(kCMTimeZero)
myPlayer.play()
}
error log: http://pastebin.com/bN2fc29G
for some reason code glitches in stackoverflow so I putted it into pastebin
Upvotes: 1
Views: 1964
Reputation: 201
I've made myself a custom Looping AVPlayer a while ago, feel free to use / comment!
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)
}
}
}
It has been a while I made it thus it might be a bit dusty. Sorry about that!
It also works with HLS files ;)
Hope this'll help!
Upvotes: 2