0

I want to play multiple videos one by one in my app in swift 4 and xcode 9. I can do this with avqueue player. But once the player is finished playing all videos then can not replay the player. Just a blank screen appears.

Code:

var selectedVideos : NSMutableArray = []
var videoPlayer: AVQueuePlayer!
var playerLayer: AVPlayerLayer!
var videoQueue: [AVPlayerItem] = []
var currentVideoTime: Double = 0
var previousVideoTime: Double = 0
var total_video_duration: Double = 0.0;
var total_video: Int = 0

@IBOutlet weak var video_container: UIView!
@IBOutlet weak var video_duration: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    setup_video_player()
    setup_layer()

    NotificationCenter.default.addObserver(self, selector: #selector(self.finishVideo), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)

}

func setup_video_player() {

    try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [])

    currentVideoTime = 0
    previousVideoTime = 0
    total_video_duration = 0
    video_duration.text = "00:00"
    videoPlayer = nil
    videoQueue = []
    total_video = selectedVideos.count

    var playerItem: AVPlayerItem!

    for index in selectedVideos {

        print("selected url: \(index as! URL)")
        playerItem = AVPlayerItem(url: index as! URL)
        videoQueue.append(playerItem)
    }

    videoPlayer = AVQueuePlayer(items: videoQueue)

    for playerItem in self.videoPlayer.items() {

        let duration = playerItem.asset.duration
        let seconds = CMTimeGetSeconds(duration)
        total_video_duration = total_video_duration + seconds
    }

    let interval = CMTime(seconds: 1, preferredTimescale: 2)

    timeObserver = videoPlayer.addPeriodicTimeObserver(forInterval: interval, queue: DispatchQueue.main, using: { elapsedTime in

        self.currentVideoTime =  self.previousVideoTime + CMTimeGetSeconds(elapsedTime)
        self.video_duration.text = self.video_duration(value: self.currentVideoTime)
    })

    print("finish setup video palyer")

    play_video()
}

func setup_layer() {

    if(playerLayer != nil){

        playerLayer.removeFromSuperlayer()
    }

    playerLayer = AVPlayerLayer(player: videoPlayer)
    playerLayer.frame = video_container.bounds
    video_container.layer.addSublayer(playerLayer)

    print("finish setup layer ")
}

func play_video() {

    if videoPlayer == nil {

        return
    }

    videoPlayer.play()
    videoPlayer.volume = 1.0
    print("playing video")
}

@objc func finishVideo(_ notification: NSNotification) {

    previousVideoTime = currentVideoTime

    print("current video time: \(currentVideoTime)")
    print("total video duration: \(total_video_duration)")

    if Int(currentVideoTime) != Int(total_video_duration) {

        return
    }

    play_video()
}

No error. But can not understand why avqueue player is not re-playing after finished once playing.

Sarwar Jahan
  • 63
  • 10

1 Answers1

0

By looking at the documentation, I found that There is no direct way to loop through all the AVPlayerItem in AVQueuePlayer. You can use AVPlayerLooper to repeat one AVPlayerItem but can't repeat entire player list.

What you can do is:

Check for your own counter in the finished method and when it reaches to end, you can remove existing player Items, with function removeAllItems() and reassign the [AVPlayerItem] to your AVQueuePlayer instance.

Hope it helps.

Community
  • 1
  • 1
Bhavin Kansagara
  • 2,866
  • 1
  • 16
  • 20