Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timer is running without sync with video duration and image #3

Open
Durga-Veerendra opened this issue Sep 28, 2018 · 6 comments
Open

Comments

@Durga-Veerendra
Copy link

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.

@defyreborn
Copy link

I have the same issue. Please provide a solution if available.
Thank you

@praveen4D2
Copy link

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

@praveen4D2
Copy link

praveen4D2 commented Nov 27, 2018

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.

@praveen4D2
Copy link

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.

@jainamOx
Copy link

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 ??

@mehdin13
Copy link

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
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants