In my app the user can play a video and leave the screen and it will continue to play in the background (just the audio). They can then return to continue to watch the video. This means that the view the video is in is destroyed and then recreated at a later point. Whenever the view is recreated and the player is set on it's AVPlayerLayer there is a noticeable lag in the video and more importantly the audio.
Does anyone know how to eliminate this lag?
The key to making this work without any lag / delay in the audio or video is to store the view with the AVPlayerLayer outside of the view. When reloading the controller, instead of creating a new view and assigning its player to the same player, simply attach the old view to the new view controller's view.
The view stays in memory as long as the video is still playing, that way a new AVPlayerLayer is not created and assigned to. It is the reassigning that causes the lag.
Related
After several (depends on device - 2-3 transitions on first SE, more than 20 transitions on 11) transitions between two vc in navigation stack (from custom camera vc to custom video player vc) I get blank player layer without any playing video or sound. I checked up memory graph and don't found any leaks. play(), seek() and other methods don't works. I tried to change player layer frame directly in this case but it has right values. Unfortunately there is unpredictable trouble inside custom player. Any ideas?
I am currently displaying a video embedded in a view. On tap of this video I need to present it in full screen just like how App Store does it.
Right now I am using AVPlayer to embed in the view with a AVPlayerLayer. When I detect a tap on this embedded player, I am creating a AVPlayerViewController and setting its player object with the player currently embedded, but still I can notice a delay of 3~4 seconds until the player in fullscreen starts playing. How can I make this transition smooth ?
I have a table view controller that has a video view in each cell.
Each cell has a play button, slider and a full screen button.
I have implemented logic for playing , pausing and seeking the video using AVPlayerLayer.
When I click on the full screen button I am moving to another view controller where I will play the video in full screen in portrait and landscape mode
When I move to the full screen controller I want the video to play from where it was playing in the previous view controller.
And when I move back to the previous view controller the video should play from where it played in the full screen controller.
How can I achieve this? Any help will be appreciated. Thank you
I have implemented same for an audio player which has a mini player and tapping on it will open in full screen.
I have detached audio player from UI. Created singleton class of player which will update UI. So there will be only one instance of player which will update multiple UI in sync.
You can implement same logic for your player.
while playing remote HLS videos,
I am re-initializing AVQueue player which is already initialized with items by using
(AVQueuePlayer *)initWithItems:(NSArray<AVPlayerItem *> *)items
However, by doing this sound plays in background but the AVPlayerLayer is stuck at the last frame of the previous video, the video does not update. In order to make sure that video gets updated, I need to remove the previous layer for UIView of video player, re-create the new AVPlayerLayer and assign it to the UIView for player using following :
[oldAVPlayerLayer removeFromSuperLayer]
[newAVPlayerLayer playerLayerWithPlayer: myAVQueuePlayer]
[myViewForPlayerLayer addSublayer : newAVPlayerLayer]
This causes a flicker on the screen, which is okay if the device was just an iPhone/iPad, but problem is with abrupt Airplay behaviour, causing the UISlider for sound to show in the remote controls.
Is there a way to re-initialize the AVQueuePlayer without recreating or reassigning the AVPlayerLayer?
Ended up using AVPlayer instead of AVQueuePlayer, and using method
replaceCurrentItemWithPlayerItem
Does not cause the glitch in airplay, and saves the memory as well since the items are instantiated as and when required.
I know there have been a few hints on Stackoverflow about this issue but I haven't found a very satisfying answer to my problem.
I want to completely remove a video playing with AVPlayer in an AVPlayerLayer class from memory. I have read your are actually not allowed to call dealloc of the class containing the AVPlayerLayer. But even when I do so, the video remains in memory (cfr the sound does not stop playing).
Some people hint that you should pause the player, or just load in a new video, but I want it gone...
I need this because when rotating the device, I want the video kicked out of memory and a new video loaded in for the new orientation. I need to destroy the video completely because the parent view it is in also needs to be destroyed.
This is the structure I have
UIView
-> UIScrollView
-> UIviewWithPlayer
->AVPlayerLayer
In UIscrollView I call release and removefromsuperview on UIViewWithPlayer. In UIviewWithPlayer I call release and removefromsuperview on AVPlayerLayer. But that does not seem to work.
Thank you very much in advance for your help.