Reputation: 6394
I am working on an app that supports video playback similar to what snapchat is doing (you can tap through a bunch of remote videos). After tapping through a handful of videos, buffering seems to become slower, and comes to a complete stop at some point of you keep going. Sounds a lot like a memory leak to me.
After diving into it in Instruments, I found that all AVPlayers, AVPlayerItems, and AVPlayerLayers get deallocated correctly. The only leaks I find are these:
However, by studying the Connections graph and the Memory Usage, I can clearly see that even after dismissing the video player and sitting in the camera view of the app, some buffering is still occurring. The network activity stays fairly high and the memory slowly grows.
To get a better understanding of how I do video playback, here's a short explanation. I have a VideoPlayer object that I only initiate one of, then I give it new assets to play. Before giving it a new asset, I call stopBuffering
, just to make sure nothing gets left behind (we all see how successful that was).
- (void)stopBuffering
{
[self removeObservers];
[self.player pause];
[self.avPlayer replaceCurrentItemWithPlayerItem:nil];
self.avPlayer = nil;
self.player = nil;
self.playerItem = nil;
}
I have verified that this method gets called every time a new asset is loaded. This is the All Heap & Anonymous VM graph, in which the first generation is before any video playback, and the third generation is after leaving the video player. In between, I quickly jumped through about 20 videos.
Upvotes: 1
Views: 433
Reputation: 6394
The reason for this was that I began loading values with loadValuesAsynchronouslyForKeys
whenever I loaded an asset, but if I moved on the next asset before this method completed, I never canceled it. After storing the AVURLAsset
as a property and then calling
[self.asset cancelLoading];
at appropriate times, the problem disappeared.
Upvotes: 1