If some error happens on the server side (playlist) of HLS, the AVPlayer client will eventually stop and we will get this notification: AVPlayerItemFailedToPlayToEndTime.
How can we resume play after this, taking for granted that all errors serverside are fixed?
I cause 500 errors on the playlist side. The AVPlayer stops after a while.
Even after AVPlayerItemFailedToPlayToEndTime has happened, the status of the AVPlayer is NOT failed, and the currentItem.status is also NOT failed. Specifically both of these are still readyToPlay which looks like we SHOULD be able to continue playing without recreating the whole AVPlayer instance etc.
The way I try to cause a "play" again is self.play() (subclass of AVPlayer). This does not work.
I've been able to resume play (from a failed state) by recreating the AVPlayerItem and assigning it again using replaceCurrentItem(). However since I need this to happen without any user interaction (like pressing play button etc), it seems like there is no good way to find out WHEN to apply this method, and if it really worked or not.
I think you need to save your pause time. Whenever you have yo play video again, say 'Play Button Click' OR 'Resume Video' , seek to that time
avPlayer.seek(to: playerPauseTime)
if self.avPlayer.status == .readyToPlay && self.avPlayer.currentItem?.status == .readyToPlay {
self.avPlayer.seek(to: atTime,
toleranceBefore: kCMTimeZero,
toleranceAfter: kCMTimeZero,
completionHandler: { (finished) in
self.avPlayer.play()
})
}
And you will be playing your video from time lapse where it was paused.
Related
I'm trying to implement a play/pause button for positional audio attached to a node in an ARKit scene. I want the user to be able to pause the audio, then resume it from the paused point at a later time. So removeAudioPlayer() is no good, as this resets the audio back to the start when it is reattached.
The only pause method associated with SCNAudioPlayers that I can find is buried deep down in:
myAudioPlayer.audioNode?.engine?.pause()
But this doesn't seem to have any effect. Strangely
myAudioPlayer.audioNode?.engine?.stop()
Does stop the audio from playing, but then you can't start it again afterwards!
My code for creating the audioPlayer is as follows:
audioSource = SCNAudioSource(fileNamed: "audio.caf")!
audioSource.loops = false
audioSource.isPositional = true
audioSource.shouldStream = false
audioSource.load()
// then a bit later...
audioPlayer = SCNAudioPlayer(source: audioSource)
myARNode.addAudioPlayer(audioPlayer)
Notice that no 'play' method is needed. The audio just starts playing as soon as you attach it to the node. And the lack of straight play() and pause() methods as top-level properties of SCNAudioPlayer makes me wonder if it's possible at all. This seems slightly crazy however, as it's a pretty rudimentary aspect of working with audio.
Does anyone know if this can be done?
Thanks in advance.
To stop audio engine use 2 sec delay. Pause doesn't work here (I'm using Xcode 12.2).
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
player.audioNode?.engine?.stop()
}
So I have an app built with a player that plays a video, I have a [player pause] and [player play] in the didBecomeActive and willResignActive methods. Most of the time works fine, but when I open the app, and press the home button and repeat again that process, around the 8th time the video will not play even though I see the play method getting called.
Does anyone have any idea what might be going on?
The app can be in several states that are not foreground. Before playing, check to see if you still have a player, that it still has a player.currentItem, and if it's status is AVPlayerStatusReadyToPlay.
If any of those conditions are not met, then the player and the item must be reinitialized using the code that you used to create it in the first place.
This is a good candidate for a lazy initializer for your player property.
I'm playing live video with AVPlayer and AVPlayerItem. I'm observing AVPlayerItem's status, isPlaybackLikelyToKeepUp, and AVPlayerItemPlaybackStalled. I'm also observing AVPlayer's rate.
While I'm testing I found really weird thing happened.
While AVPlayer plays video normally(AVPlayerItem.status == readyToPlay and AVPlayerItem.isPlaybackLikelyToKeepUp == true), if I press home button, the AVPlayer.rate becomes 0.0. It means player stopped playing.
When app got back to foreground and I press play button, it is still AVPlayerItem.status == readyToPlay and AVPlayerItem.isPlaybackLikelyToKeepUp == true but paused and after a while it starts to play.
What I want is to know the player is paused or playing. In this case, even player is not playing video, the status indicates it is playing. (AVPlayerItem.status == readyToPlay, AVPlayerItem.isPlaybackLikelyToKeepUp == true, AVPlayer.rate == 1.0)
I checked AVPlayerItem's loadedTimeRanges and item.loadedTimeRanges.first is not nil(loadedTimeRanges has only one item) and its start and duration are not 0.
What should I check?
I'm adding little more.
This symptom only happens with streaming(m3u8) not with vod(mp4).
So I guess it is a problem of buffered data. While player is playing, buffer has data to play and the data is still valid. After app goes background and back to foreground, player's buffer still has data so isPlaybackLikelyToKeepUp == true, AVPlayerItem.status == readyToPlay. However when I try to play, AVPlayer flushes buffer because it is old.
It looks like the only way so far is create new AVPlayerItem and set when app is back to foreground.
What is the exact problem I'm encountering and want to know how to avoid it.
This is the repo I'm working on.
https://github.com/trick14/SLPlayer
The upper one is live and bottom one is VOD. After loading is done, play and go background and foreground couple times. And if you try to play, all status looks normal but player is stalled.
I have a similar experience long time ago.
At that time, I've stored the status of playing and the playback location when user press home button.
When return to the foreground, I used the stored information to restore or play the location.
I hope you were helpful.
I have an AVQueuePlayer which loads URLs to play audio files and it works well for the most part. However, I have run into a problem where after the player finishes playing a file (with another file in the queue), it will simply stop playing. Normally, the app would be able to use the player's rate, status, and items. In this case, I have gone through with the debugger and everything looks normal.
Everything appears to be playing, except for the player itself. After forcing the player to play, the player will skip to the next track, indicating that the AVPlayerItem it had was not loaded (I can confirm the audio urls are valid).
Does anyone have any ideas how I catch this programatically?
You need to have the delegate method:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
Once this method is finished, start the new audio.
I have a problem with AVAudioPlayer Interruption.
And I'm not talking about the interruption during the incoming call. I can handle this situation very well. Call -> Interruption start -> End of call -> Interruption finish.
The problem is with the camera on the device. The situation is:
My player app is playing on background. I want to make a photo. I open the camera and make a photo. No interruption at all! But if I want to capture some video the interruption starts and the player becomes silent. At the same moment interruption finishes! (I have checked it on two devices with the help of NSLog - and I find it very weird) But the player doesn't continue playing the song because video camera is still ON. I close camera and NOW I expect the interruption to finish, but it was finished earlier and the player remain silent.
The question is: How to handle this situation?