Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

AVPlayer: Significant Delays and Asset Loss When Playing Partially Downloaded HLS Content Offline

We're experiencing significant issues with AVPlayer when attempting to play partially downloaded HLS content in offline mode. Our app downloads HLS video content for offline viewing, but users encounter the following problems:

Excessive Loading Delay: When offline, AVPlayer attempts to load resources for up to 60 seconds before playing the locally available segments Asset Loss: Sometimes AVPlayer completely loses the asset reference and fails to play the video on subsequent attempts Inconsistent Behavior: The same partially downloaded asset might play immediately in one session but take 30+ seconds in another Network Activity Despite Offline Settings: Despite configuring options to prevent network usage, AVPlayer still appears to be attempting network connections

These issues severely impact our offline user experience, especially for users with intermittent connectivity. Technical Details Implementation Context Our app downloads HLS videos for offline viewing using AVAssetDownloadTask. We store the downloaded content locally and maintain a dictionary mapping of file identifiers to local paths. When attempting to play these videos offline, we experience the described issues. Current Implementation Here's our current implementation for playing the videos:

- (void)presentNativeAvplayerForVideo:(Video *)video navContext:(NavContext *)context {
    NSString *localPath = video.localHlsPath;

    if (localPath) {
        NSURL *videoURL = [NSURL URLWithString:localPath];

        NSDictionary *options = @{
            AVURLAssetPreferPreciseDurationAndTimingKey: @YES,
            AVURLAssetAllowsCellularAccessKey: @NO,
            AVURLAssetAllowsExpensiveNetworkAccessKey: @NO,
            AVURLAssetAllowsConstrainedNetworkAccessKey: @NO
        };

        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:options];

        AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
        NSArray *keys = @[@"duration", @"tracks"];

        [asset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
                AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
                playerViewController.player = player;
                [player play];
            });
        }];
        playerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
        [context presentViewController:playerViewController animated:YES completion:nil];
    }
}

Attempted Solutions We've tried several approaches to mitigate these issues:

Modified Asset Options:

NSDictionary *options = @{
    AVURLAssetPreferPreciseDurationAndTimingKey: @NO,  // Changed to NO
    AVURLAssetAllowsCellularAccessKey: @NO,
    AVURLAssetAllowsExpensiveNetworkAccessKey: @NO,
    AVURLAssetAllowsConstrainedNetworkAccessKey: @NO,
    AVAssetReferenceRestrictionsKey: @(AVAssetReferenceRestrictionForbidRemoteReferenceToLocal)
};

Skipped Asynchronous Key Loading:

AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset automaticallyLoadedAssetKeys:nil];

Modified Player Settings:

player.automaticallyWaitsToMinimizeStalling = NO;
[playerItem setPreferredForwardBufferDuration:2.0];

Added Network Resource Restrictions:

playerItem.canUseNetworkResourcesForLiveStreamingWhilePaused = NO;

Used File URLs Instead of HTTP URLs where possible

Despite these attempts, the issues persist.

Expected vs. Actual Behavior

Expected Behavior:

AVPlayer should immediately begin playback of locally available HLS segments When offline, it should not attempt to load from network for more than a few seconds Once an asset is successfully played, it should be reliably available for future playback

Actual Behavior:

AVPlayer waits 10-60 seconds before playing locally available segments Network activity is observed despite all network-restricting options Sometimes the player fails completely to play a previously available asset Behavior is inconsistent between playback attempts with the same asset

Questions:

  • What is the recommended approach for playing partially downloaded HLS content offline with minimal delay?
  • Is there a way to force AVPlayer to immediately use available local segments without attempting to load from the network?
  • Are there any known issues with AVPlayer losing references to locally stored HLS assets?
  • What diagnostic steps would you recommend to track down the specific cause of these delays?
  • Does AVFoundation have specific timeouts for offline HLS playback that could be configured?

Any guidance would be greatly appreciated as this issue is significantly impacting our user experience. Device Information

iOS Versions Tested: 14.5 - 18.1 Device Models: iPhone 12, iPhone 13, iPhone 14, iPhone 15 Xcode Version: 15.3-16.2.1

Hello @nlaptenok, thank you for your post. Are you able to observe the same issue when you test persisting one of your streams using the Using AVFoundation to play and persist HTTP Live Streams?

AVPlayer: Significant Delays and Asset Loss When Playing Partially Downloaded HLS Content Offline
 
 
Q