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.
Related
I have an issue where when user is playing a video , while video is being player, he uses siri to search for a different movie, which will load its corresponding movie details page and then select to play that movie, which deeplinks to your app which is playing a movie, when i play a new selected movie and dismiss avplayer and avplayercontroller, audio from previous video still continues to play. somehow avplayer is not cleared although i clear all subviews from window and initialize its super view controller class again. I am cluless what can i do erase older instance of avplayer. Let me know if anyone has any suggestions or faced similar issue.
A few suggestions:
Are you subclassing AVPlayerViewController? If so, that's a bad idea. The API docs specifically say not to do that.
Add a deinit function. If it's not being called when the old AVPlayer is dismissed, you know you have a retention problem. This is often caused by registering for notifications or boundary time observers.
If you view controller has a reference to the AVPlayer object, you might try overriding the viewDidDisappear function to call player.pause() and then setting the player reference first to a new instance of AVPlayer() then to nil. Not sure why this helps, but sometimes it does.
Definitely implement #2 above. If deinit is not getting called, you most certainly have an issue.
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 am implementing a video app, that lists video and able to stream or watch local videos. If I try to watch videos with my player that inherits from AVPlayer, a lot of threads initated, after 15-20 times, the system does not alloc the AVPlayer well and, even if I do not get any error, the player view is blank and nothing happening...I need to kill app to restore.
How to deal with it?
Thanks in advance
I had the same issue, in my case the AVPlayerLayer didn’t get DE allocated successfully because somehow a custom label grabbed the strong reference of controller and the controller did not get DE allocated.
Implement
deinit {
}
in your controller and check this called or not. If not you have the solution.
I hope this helps.
I have used AVQueuePlayer several times and the default behaviour is to continue playing when you change view, but in my case when I navigate to the previous view where I came from by segue, the player stops. I put a breakpoint after dealloc to see if the AVQueuePlayer is released and from what I can see it's not deallocated (I have a strong reference to it using property). Please help!!!
I am streaming audio using several links from a server, not playing local files. I created the url, used the url to make AVPlayerItems, and added the player items into array, I used this array to initiate the AVQueuePlayer. I used GCD to make sure my array is completely ready before I play the AVQueuePlayer.
As soon I click on back button it stops. I am pulling out my hair
Create a singleton class that provides an interface to the AVQueuePlayer. That way you will be sure that it's alive even when you pop your view controllers.
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.