Skip to main content

5. Offline Playback

Describes how to play back content that has been fully downloaded to local disk. In offline mode, instead of using a remote URL as in online streaming playback, you pass the downloaded KollusContent instance directly to the player to start playback.

All example code in this document is based on the official sample app, kollus_player_ios.


Offline playback

Obtain the downloaded content object safely through the storage manager, then inject it as the data source for the player view to start offline playback.

1. Find downloaded content

let downloaded = StorageManager.shared.contents()
.first { $0.mediaContentKey == targetMck && $0.downloaded }

2. Attach to the player

// Method 1: Inject directly into the KollusPlayerView instance property
playerView.kollusContent = downloaded

// Method 2: Pass as a constructor parameter when initializing PlayerViewController
let vc = PlayerViewController(content: downloaded)
present(vc, animated: true)

Full integration flow

  1. Obtain an object from StorageManager.shared.contents() that matches the desired media content key and satisfies the download completion condition.
  2. Connect the obtained KollusContent instance to the KollusPlayerView object as shown in the example code above.
  3. During playback preparation, the SDK automatically performs local DRM verification. If the license has expired or permissions are insufficient, the player stops and notifies the state via a delegate callback or player error. (See Also: 8. Download Events/Callbacks)

Offline DRM verification conditions

To pass DRM verification in an offline environment without a network connection, all four of the following DRM security restriction conditions embedded in the downloaded file must be satisfied.

PropertyNormal condition
DRMExpiredMust remain false.
DRMExpireDateThe device's current time must be before the expiration date specified in the license.
drmTotalExpirePlayTime / DRMExpirePlayTimeNo limit (== 0) or remaining allowed playback time must be > 0.
drmExpireCountMax / drmExpireCountNo limit (== 0) or remaining allowed playback count must be > 0.

If any one of the above four conditions is violated, local playback will fail, and you must reconnect to the network and renew the license for normal operation. (See Also: 6. DRM License Renewal)


Handle DRM-expired content

This is the business utility logic implementation pattern adopted by the sample application to determine whether content has expired in advance.

func isExpired(_ content: KollusContent) -> Bool {
// 1. Verify forced expiration flag status
if content.DRMExpired { return true }
// 2. Verify expiration date and time
if let expire = content.DRMExpireDate, expire < Date() { return true }
// 3. Verify only when cumulative playback time limit is set (drmTotalExpirePlayTime == 0 means no limit)
if content.drmTotalExpirePlayTime > 0 && content.DRMExpirePlayTime <= 0 { return true }
// 4. Verify only when playback count limit is set (drmExpireCountMax == 0 means no limit)
if content.drmExpireCountMax > 0 && content.drmExpireCount <= 0 { return true }
return false
}
Recommended UX for expired content

If the content is determined to be expired by the verification logic above, design the UX by choosing one of the following flows.

  • Run dynamic renewal process: Immediately attempt a background renewal API call and start playback upon success.
  • Notify on renewal failure: If the renewal process ultimately fails, display a license expiration popup to the user and prompt them to re-download.

Display DRM expiration renewal notification

The DRMExpireRefreshPopup property is a control flag that the SDK dynamically sets by determining whether to show the renewal popup during response communication with the console server. If this value is received as true, it is recommended to display an explicit notification according to the guide.

if content.DRMExpireRefreshPopup {
// It is recommended to display a "Would you like to renew your license?" dialog on the user's screen.
}

Handle deleted and corrupted file exceptions

This is a safe defensive code implementation pattern for when a user arbitrarily modifies or forcibly deletes local media files.

SituationSDK behavior and recommended handling
File exists in the list but the actual file is missingThe SDK automatically cleans it up, so no additional handling is needed by the caller (app layer).
File is corruptedA player error occurs during playback preparation and the event is notified. Display a message to the user indicating the file is defective and prompting them to re-download.
A KollusContent object with a nil mediaContentKey is foundIt may be a virtual folder (directory) node rather than an actual file. If fileType == 1, handle it as a folder view branch in the UI.