I allow users to capture both images and videos and save them to my server. When a user taps on an icon they should be able to view all of the media stored in that particular location. Currently, I am having difficulty assessing when a video ends to move to the next piece of media or when a video is done processing and ready to be played
I am trying to use notification center to update when it is ready to play but it is still not working. I also included a timer which gives images an automatic 3 seconds to be viewed or if it is a video it gets the videos duration and moves after that video has concluded playing
//METHODS: func showFeed() {
//ensure there is media to present
if media.count > 0 {
//check if media is of type video or image
//show first piece of media initially
if media[mediaIndex].media_type! == "CAMERA" || media[mediaIndex].media_type! == "LIBRARY" {
videoDisplay.isHidden = true
timeInterval = 3.0
photoDisplay.kf.setImage(with: URL(string: Constants.Server.PHOTO_URL + media[mediaIndex].media_photo_url!))
} else if media[mediaIndex].media_type! == "VIDEO" {
//check if photoview is hidden & if not hide it
videoDisplay.isHidden = false
var url = URL(fileURLWithPath: Constants.Server.VIDEO_URL + media[mediaIndex].media_video_url!)
prepareToPlay(url)
}
//date formatter
//media time stamp
let timeStampStr = formatter.string(from: media[mediaIndex].media_created_at!)
media_time_stamp.text = GlobalService.sharedInstance().UTCToLocal(date: timeStampStr)
}
//begin timer
//make sure repeat is set to false so timer is fresh
/*
if timerCounter == nil {
timerCounter = Timer.scheduledTimer(withTimeInterval: TimeInterval(timeInterval), repeats: false, block: {(timer) in
self.scrollToNextCell()
})
}
*/
}
Here is the next call to prepareToPlay()
func prepareToPlay(_ url: URL) { //get time interval from player
let asset = AVAsset(url: url)
let assetKeys = [
"playable",
"hasProtectedContent"
]
playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: assetKeys)
playerItem!.addObserver(self,
forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
player = AVPlayer(playerItem: playerItem!)
}
//handle changes in state of playback item override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// Only handle observations for the playerItemContext
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItem.Status
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
// Switch over status value
switch status {
case .readyToPlay:
//hide loading screen
mediaLoadingView.isHidden = true
activityIndicator.stopAnimating()
//play video
let assetDuration = player?.currentItem?.asset.duration
let duration = CMTimeGetSeconds(assetDuration!)
let timeIntervalDuration = Float(duration)
timeInterval = timeIntervalDuration
//add player to player layer
playerLayer = AVPlayerLayer(player: player!)
//add player layer to UIView
//move resize aspect fill to where it will be loaded before frame of layer is calculated
playerLayer!.videoGravity = .resizeAspectFill
playerLayer!.frame = self.view.bounds
videoDisplay.layer.addSublayer(playerLayer!)
player?.play()
// Player item is ready to play.
case .failed:
let alert = SCLAlertView()
alert.showError("Failed", subTitle: "video was unable to properly load")
case .unknown:
// Player item is not yet ready.
mediaLoadingView.isHidden = false
activityIndicator.startAnimating()
print("player not yet ready")
}
}
}
I intend to have the media, if it is a video, to begin playing immediately however it does not