4

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?

Aluminum
  • 2,932
  • 5
  • 35
  • 63
Jan
  • 2,462
  • 3
  • 31
  • 56
  • Do you have a crash report that tells you that this is due to memory pressure? And apologies for the daft question, but this kiosk is definitely keeping the pad charged throughout the day? – davbryn Mar 06 '14 at 14:22
  • Unfortunately I don't, as it is happening on location. I can't reproduce it, because the videos are going through a secondary screen, and if I connect that, I can't connect the device to Xcode. Instruments ran on the simulator, and although it didn't crash, the app was quite unresponsive when I tried to use it after 14hs. – Jan Mar 06 '14 at 14:41
  • Does your app monitor free disk space? – bneely Mar 06 '14 at 20:47
  • You should be able to get a crash report from Organizer. Or use something like Hockeyapp/Airbrake for remote crash reports – j_mcnally Mar 06 '14 at 20:48
  • @bneely no it doesn't. But why should disk space be an issue? I'm not writing anything to disk. – Jan Mar 07 '14 at 15:02
  • @j_mcnally I don't have access to the devices as they are in another country, but I'll take a look at Hockeyapp/Airbrake. Thanks – Jan Mar 07 '14 at 15:02
  • @Jan If you're not consuming disk space, it is not a concern. My iPhone 5s recently filled up with music and I was getting a lot of unexpected lags throughout many apps. – bneely Mar 07 '14 at 17:02
  • Your real solution would be NewRelic they will give you live telemetry of remote apps. – j_mcnally Mar 14 '14 at 00:46
  • @Jan, I had a similar problem with AVPlayer and HTTP Live Straming. Every so often it would freeze. Similar to your situation, there was no crash report, and no visible cause. I had suspected the Streaming server, so put together an implementation using Core audio directly, and the problem disappeared. I subsequently implemented 3 lines of code to nil the AVPlayer and recreate it between songs, which fixed the problem. There seems to be an internal issue that is hard to trace. – MDB983 Mar 14 '14 at 21:47

2 Answers2

1

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.

Michael Melanson
  • 1,325
  • 10
  • 21
0

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)

longi
  • 11,104
  • 10
  • 55
  • 89