Jan
Jan

Reputation: 2522

Video loop is freezing my iOS app at some point

I have an application that is running on a Kiosk, open all day looping videos. Eventually, after around 1 day, the application freezes.

Here is an Instruments session after 14 hours of running: enter image description here enter image description here enter image description here enter image description here

I'm not very familiar with Instruments yet, and although the Live Bytes stay consistent and are low, the other values do seem like very high. But again, I'm not sure if that's normal or not.

This is how I create the video player:

- (void)setupInitialContentWithBounds:(CGRect)externalScreenBounds
{   
    avPlayer = [[AVPlayer alloc] init];
    avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
    avPlayerLayer.frame = externalScreenBounds;
    [self.externalWindow.layer addSublayer:avPlayerLayer];
    avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playerItemDidReachEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[avPlayer currentItem]];

    [self playVideo:@"Idle"];
}

Here is the playVideo method:

- (void)playVideo:(NSString *)name
{
    currentVideo = name;
    NSString *filepath = [[NSBundle mainBundle] pathForResource:name ofType:@"mp4"];
    NSURL *fileURL = [NSURL fileURLWithPath:filepath];
    AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:fileURL];
    [avPlayer replaceCurrentItemWithPlayerItem:playerItem];
    [avPlayer play];
}

And here the notification listener for when the video finishes:

- (void)playerItemDidReachEnd:(NSNotification *)notification
{
    if([currentVideo isEqualToString:@"Idle"])
    {
        //Keeps looping the Idle video until another one is selected
        AVPlayerItem *p = [notification object];
        [p seekToTime:kCMTimeZero];
    }

    else
    {
        NSLog(@"Just finished a different video, so go back to idle");
        [self playVideo:@"Idle"];
    }
}

EDIT: At first my client told me it crashed, but it looks like it actually freezes, the video stops playing and the app is unresponsive. Any ideas?

Upvotes: 4

Views: 1480

Answers (2)

Michael Melanson
Michael Melanson

Reputation: 1335

I can't answer your question about the crash, except to confirm that we've seen a similar crash here that may be the same issue.

But I can help you interpret Instruments' display a bit better. I wouldn't worry about the Overall Bytes and # Overall values being very high. Those measure the total amounts of memory allocated since the app was launched (or since Instruments was attached). That is, allocating 1MB then freeing it would add 1MB to those totals.

I'd expect that the Overall Bytes amount is more or less proportional to size of video * play count.

Upvotes: 1

LONGI
LONGI

Reputation: 11443

I never used the AVPlayer class, but we had a similar scenario for an infinite video loop app for an exhibition

Overall, it looks like your app get some memory, if running for a long time. Maybe AVPlayer causes some memory leaks?!

  • on video end event: release your player (set to nil) and re-initialize it (like on startup) instead of looping it. If some "garbage" should fall behind, ARC might do the rest ...

    //release your player (taken from here: http://stackoverflow.com/questions/17831764/how-to-stop-a-video-in-avplayer)
    [self.videoPlayer Pause];
    [self.avPlayerLayer removefromsuperlayer];
    self.videoPlayer = nil;
    
    //re-init
    
  • ensure your setupInitialContentWithBounds is only called once, otherwise you might call addObserver several times which can lead to strange side-effects (or do you call removeObserver at some point)

Upvotes: 0

Related Questions