ARStories
ARStories copied to clipboard
Timer is running without sync with video duration and image
Timer is running without sync with video duration and image. If an image or video still under downloading from the network, the top status is running and moved to next image or video. please help me in this.
I have the same issue. Please provide a solution if available. Thank you
Hi, i also have the same issue. I tried like below for images.
self.SPB.duration = 5
self.SPB.isPaused = true
self.imagePreview.setShowActivityIndicator(true)
self.imagePreview.setIndicatorStyle(.whiteLarge)
self.imagePreview.sd_setImage(with: URL(string: storyDict.value(forKey: "storyUrl") as! String)) { (image, error, imageCacheType, imageUrl) in
if image != nil {
print("image found")
self.SPB.isPaused = false
}else
{
print("image not found")
}
}
Before downloading image i am pausing the SegmentedProgressBar and after getting image again i am changing isPaused value to false. this is working only for first story.
if we have multiple stories below code executing after changing self.SPB.isPaused = true. in that function self.isPaused = false. Because of that one again progress bar not Syncing with image .
private func animate(animationIndex: Int = 0) {
let nextSegment = segments[animationIndex]
currentAnimationIndex = animationIndex
self.isPaused = false
// no idea why we have to do this here, but it fixes everything :D
print("duration =* ",duration)
UIView.animate(withDuration: duration, delay: 0.0, options: .curveLinear, animations: {
nextSegment.topSegmentView.frame.size.width = nextSegment.bottomSegmentView.frame.width
}) { (finished) in
if !finished {
return
}
self.next()
}
}
Any useful reply will be appreciated. ^_^ Waiting for your good news! @@@👍 Thank you
Hi, I Found one solution it working fine but I don't know exactly it is an efficient way or not. in SegmentedProgressBar class I have placed if-else condition for checking ispaused value like below.
private func animate(animationIndex: Int = 0) {
let nextSegment = segments[animationIndex]
currentAnimationIndex = animationIndex
**if self.isPaused {
} else {
self.isPaused = false // no idea why we have to do this here, but it fixes everything :D
}**
UIView.animate(withDuration: duration, delay: 0.0, options: .curveLinear, animations: {
nextSegment.topSegmentView.frame.size.width = nextSegment.bottomSegmentView.frame.width
}) { (finished) in
if !finished {
return
}
self.next()
}
}
and for SegmentedProgressBar synchronization with video duration firstly i declared below three things globally.
var playerItem: AVPlayerItem! private var playerItemContext = 0 let requiredAssetKeys = [ "playable", "hasProtectedContent" ]
After that in play video or show image function i added some code like below.
func playVideoOrLoadImage(index: NSInteger) {
let moviePath = storyDict["storyUrl"]as? String ?? ""
self.imagePreview.isHidden = true
self.videoView.isHidden = false
self.resetPlayer()
let url = URL(string: moviePath)
let asset = AVAsset(url: url!)
playerItemContext = 0
self.SPB.isPaused = true
playerItem = AVPlayerItem(asset: asset,
automaticallyLoadedAssetKeys: requiredAssetKeys)
playerItem.addObserver(self,
forKeyPath: #keyPath(AVPlayerItem.status),
options: [.old, .new],
context: &playerItemContext)
player = AVPlayer(playerItem: playerItem)
let videoLayer = AVPlayerLayer(player: self.player)
videoLayer.frame = view.bounds
videoLayer.videoGravity = .resizeAspectFill
self.videoView.layer.addSublayer(videoLayer)
let duration = asset.duration
let durationTime = CMTimeGetSeconds(duration)
self.SPB.duration = durationTime
self.player.play()
}
When you associate a player item with AVPlayer, it immediately begins enqueuing the item’s media and preparing it for playback. The player item becomes ready for use when the status value changes to AVPlayerItem.Status.readyToPlay.
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &playerItemContext else {
super.observeValue(forKeyPath: keyPath,
of: object,
change: change,
context: context)
return
}
if keyPath == #keyPath(AVPlayerItem.status) {
let status: AVPlayerItemStatus
if let statusNumber = change?[.newKey] as? NSNumber {
status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!
} else {
status = .unknown
}
switch status {
case .readyToPlay:
self.SPB.isPaused = false
break
case .failed:
self.SPB.isPaused = true
break
case .unknown:
self.SPB.isPaused = true
break
}
}
}
The above method is invoked whenever the status value changes, giving you the chance to take some action: Now, everything works fine for me.
Hi, i have one issue regarding stories skipping. i need do exactly like whatsapp. For example if there are five stories, one user saw 3 stories out of five and close that screen. when the user reopen the same stories of that particular person i have to show image or play video from 4 th position of that stories. if Any body have idea kindly help me to fix this issue.
Hi, i have one issue regarding stories skipping. i need do exactly like whatsapp. For example if there are five stories, one user saw 3 stories out of five and close that screen. when the user reopen the same stories of that particular person i have to show image or play video from 4 th position of that stories. if Any body have idea kindly help me to fix this issue.
Hi, i have one issue regarding stories skipping. i need do exactly like whatsapp. For example if there are five stories, one user saw 3 stories out of five and close that screen. when the user reopen the same stories of that particular person i have to show image or play video from 4 th position of that stories. if Any body have idea kindly help me to fix this issue.
Did you found any solution on this @praveen4D2 ??
in playVideoOrLoadImage function stop SPB and resume after Load video or image: self.SPB.isPaused = true
//add this code
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReadyToPlay(notification:)), name: .AVPlayerItemNewAccessLogEntry, object: player?.currentItem) }
@objc func playerItemDidReadyToPlay(notification: Notification) { if let _ = notification.object as? AVPlayerItem { // player is ready to play now!! self.SPB.isPaused = false } }