Skip to main content

Player Configuration

Set peak bitrate

Configure the player's variant adaptation logic with the maximum bitrate constraint.

player.set(preferences: [.preferredPeakBitRate(bitrate: 842_742)])

Note: If you set preferences before the player enters the loaded state, these preferences are considered on-load preferences and override any preference set using the load(with preferences: Preference...) method. If you set preferences during playback, they're applied to the player immediately.

Set initial forward buffer duration

Set the preferred initial forward buffer duration to optimize playback startup time. This setting applies only before playback starts. To reset, set the value to 0.0, which uses the system-preferred buffer. Set this preference before calling the play() or load() API.

 player.set(preferences: [.preferredInitialForwardBufferDuration(duration: 1.0)])

Set forward buffer duration after rebuffer

To change the playback preference, either reset it to the default value by setting the value to 0.0, or set a new value to use after playback starts. The new value applies only after the video has started playing. Setting this to 0.0 uses the system buffer duration, which is based on different factors.

  player.set(preferences: [.preferredForwardBufferDurationAfterRebuffer(duration: 8.0)])

Set initial playback time

Set the initial time from which the player should start playback.

player.set(preferences: [.initialPlaybackTime(time: 10.0)])

Set maximum resolution

Set the preferred maximum resolution for playback video by passing the size (height and width).

player.set(preferences: [.preferredMaximumResolution(size: CGSize(width: 1080, height: 720))])

Set network resources for live streaming

The canUseNetworkResourcesForLiveStreamingWhilePaused property indicates whether the player item can use network resources to keep the playback state up to date while paused. When you set this property to true, the seekableTimeRanges property is periodically updated to reflect the current state of the live stream.

 player.set(preferences: [.canUseNetworkResourcesForLiveStreamingWhilePaused(paused: true)])

Setting MaximumResolution For Expensive Networks

By setting this preference, player may adjust the video resolution based on network condition to improve the user’s experience.

 player.set(preferences: [.preferredMaximumResolutionForExpensiveNetworks(size: CGSize(width: 1080, height: 720))])
note

Available from, iOS 15.0+, tvOS 15.0+

Setting starts On First Eligible Variant

Setting startsOnFirstEligibleVariant indicates whether playback starts with the first eligible variant that appears in the stream’s main playlist. The default value of this property is false.

player.set(preferences: [.startsOnFirstEligibleVariant(eligibleVariant: true)])

Note: Available from iOS 14.0+ and tvOS 14.0+.

Set peak bit rate for expensive networks

Set preferredPeakBitRateForExpensiveNetworks to set the maximum bit rate for streaming content when the player is connected to an expensive network.

 player.set(preferences: [.preferredPeakBitRateForExpensiveNetworks(preferredPeakBitRate: 5397000.0)])

Note: The value of the preferredPeakBitRate property applies unconditionally. This property value has no effect if it's less restrictive than the preferredPeakBitRate value. Available from iOS 15.0+ and tvOS 15.0+.

Protect playback from insecure devices

You can allow or disallow playback on insecure devices, that is, jailbroken devices. By default, FLPlayer allows playback on insecure devices.

player.set(preferences: [.allowPlaybackOnInsecureDevice(allow: false)])

You can enable additional security checks on top of detecting jailbreak:

// Opt in to additional checks
let additionalChecks = [.emulatorCheck, .debuggerCheck, .proxyCheck, .integrityCheck(bundleID: "com.organisation.appname")]
player.set(preferences: [.enableSecurityChecks(additionalChecks: additionalChecks)])

You can enable the following opt-in checks:

NameDescription
Debugger detectionDetermines if the application is being debugged
Emulator detectionDetermines if the application runs in an emulator
Proxy detectionDetermines if an HTTP proxy is set in the iOS settings
Device tampering detectionDetermines if the application has been tampered

Note: We recommend you integrate these checks with a remote configuration to enable or disable each detection and select the security level based on your requirements.

Determine device security status

You can access device security status through PlatformClient:

let device = FLPlatformCoreFactory.createDevice()
let result = device.securityStatus(bundleID: "com.org.app")
if !result.status {
// print(result.failureReason)
}

Trick play

Set the factor by which to speed up playback.

// Standard playback rate is 1 and paused is 0.
// You can use rates other than 0.0 and 1.0
// if the stream supports trick play.
player.rate = 1.25;

Picture in picture

FLPlayer library supports picture in picture (PiP). Your application must include the Audio, AirPlay & Picture in Picture capability. Picture in picture is possible only on iPad and on selected models. This is a platform limitation.

AirPlay

FLPlayer library supports AirPlay 2. Your application must include the Audio, AirPlay & Picture in Picture capability. Note that AirPlaying FairPlay-protected content requires an on-demand license key, so you can't AirPlay offline content.

Now playing info

iOS displays now-playing information on the device lock screen and in the multimedia controls in the multitasking UI. If you direct playback of your media to Apple TV through AirPlay, the now-playing information appears on the television screen. If you connect a device to an iPod accessory, such as in a car, the accessory may display now-playing information. Pass nil to clear the existing now-playing info.

// Setting NowPlayingInfo
var nowPlayingInfo = [String: Any]()
if #available(iOS 10.3, *) {
nowPlayingInfo[MPNowPlayingInfoPropertyAssetURL] = <url>
} else {
// Fallback on earlier versions
}

// Sample inputs
nowPlayingInfo[MPMediaItemPropertyTitle] = "Content Title"
nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.duration
nowPlayingInfo[MPMediaItemPropertyMediaType] = MPMediaType.anyVideo.rawValue
nowPlayingInfo[MPNowPlayingInfoPropertyDefaultPlaybackRate] = 1.0
nowPlayingInfo[MPMediaItemPropertyArtist] = "Artist"
nowPlayingInfo[MPMediaItemPropertyAlbumArtist] = "Album Artist"
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = "Album Title"

#if os(iOS)
player.nowPlayingInfo = nowPlayingInfo
#endif

Thumbnail preview

Thumbnail preview lets users see a preview image of the video while seeking. The player uses a series of images woven into a sprite from a given URL to retrieve the corresponding image for a playhead position.

Set up thumbnail preview

This section describes how to create and configure thumbnail preview.

Create thumbnail configuration

ContentThumbnailPreviewConfiguration describes the URL, dimensions, and duration of each image in each sprite.

NameTypeDescription
endPointStringThe fully formed sprite image URL that combines the endpoint URL and generic URL suffix, which includes the flag ~index~. The player calculates the sprite index based on the given position and replaces ~index~ with the required index to construct the URL.
noOfcolumnsIntThe number of columns in each sprite image.
noOfRowsIntThe number of rows in each sprite image.
keyFrameDurationIntThe time (in seconds) that each thumbnail in each sprite image corresponds to.
thumbnailWidthIntThe width (in pixels) of each thumbnail in each sprite image.
thumbnailHeightIntThe height (in pixels) of each thumbnail in each sprite image.
let thumbnailConfiguration: ContentThumbnailPreviewConfiguration = FLPlayerFactory.thumbnailConfiguration(
endPoint: spriteURL,
noOfColumns: columns,
noOfRows: rows,
keyFrameDuration: frequency,
thumbnailHeight: height,
thumbnailWidth: width
)

Pass information to the player

Thumbnail preview is an optional feature. You can opt in by passing a ContentThumbnailPreviewConfiguration object to the corresponding player instance. For more information, see Player creation.

// If using AVURLAsset to create player
let player = FLPlayer.player(
asset: avURLAsset,
thumbnailConfiguration: thumbnailConfiguration
)

// If using content URL to create player
let player = FLPlayer.player(
contentURL: contentURL,
thumbnailConfiguration: thumbnailConfiguration
)

Implement thumbnail preview

This section describes how to call the API to get the thumbnail image.

Call the getThumbnail API

You can get the preview image for a particular position by calling the getThumbnail extension API on the player instance. The API returns the preview image for the given position as a UIImage.

ParameterTypeDescription
progressTimeIntervalThe position of the playhead for which to retrieve the thumbnail, in seconds.
completionHandler@escaping (UIImage) -> VoidThe callback function that returns a UIImage of the thumbnail.
player.getThumbnail(for: progress, completionHandler: { [weak self] thumbnail in
// Display preview image as required
})

You typically call this function with a scrub bar listener attached to the player that listens to all seeking activity from the user.

SMPTE-TT subtitles

SMPTE-TT is a bitmap or image-based subtitle format in which subtitle information is embedded within the stream and delivered to the client as XML through ID3 timed metadata. Because AVPlayer doesn't support this format, we added custom support for SMPTE-TT subtitle rendering in the Quickplay Player.

Alternatively, you can deliver SMPTE-TT subtitles using a sidecar approach, where the entire subtitle content is provided upfront in an XML file covering the full duration of the media.

Enable SMPTE-TT subtitle rendering

Enable this player preference to instruct the player to render SMPTE-TT subtitles.

Note: This is a resource-intensive operation, so enable it only for channels that support SMPTE-TT subtitles.

XML through ID3 event

let player = FLPlatformPlayerFactory.player(asset: urlAsset, thumbnailConfiguration: nil)
player.setPreference(.enableAdditionalSubtitle([.SMPTE_ID3]))

XML through sidecar load

let language = SubtitleLanguage(endpoint: "Configure EndPoint", languageCode: "Language code (en)")
let subtitleConfiguration = SubtitleConfiguration(languages: [language])
player.set(preferences: [.enableAdditionalSubtitle([.SMPTE_SIDECAR(subtitleConfiguration)])])
let player = FLPlatformPlayerFactory.player(asset: urlAsset, thumbnailConfiguration: nil)
player.setPreference(.enableAdditionalSubtitle([.SMPTE_SideLoad(subtitleConfiguration)]))

Limitations for SMPTE_ID3

The following limitations apply to SMPTE_ID3:

  • Not supported on tvOS.
  • Not supported during AirPlay playback.
  • Not supported in picture-in-picture mode.
  • SMPTE-TT subtitle tracks become available only after playback starts, whereas natively supported subtitles are available before playback begins.
  • Multi-language SMPTE-TT subtitles aren't supported on iOS 16 and below because ID3 timed metadata isn't reported to the client.
  • Subtitle selection depends on the enableAdditionalSubtitle preference and the available tracks in the stream.

Limitations for SMPTE_SideLoad

The following limitations apply to SMPTE_SideLoad:

  • Not supported on tvOS.
  • Not supported during AirPlay playback.
  • Not supported in picture-in-picture mode.
  • SMPTE-TT subtitle tracks become available only after playback starts, whereas natively supported subtitles are available before playback begins.
  • Subtitle selection depends on the enableAdditionalSubtitle preference and the available tracks in the stream.

Subtitle selection behavior

The following table shows subtitle selection behavior based on preferences:

PreferenceAvailable subtitle tracksDisplayed subtitle
'SMPTE_ID3''SMPTE_ID3''SMPTE_ID3'
'SMPTE_SideLoad''SMPTE_SideLoad''SMPTE_SideLoad'
'SMPTE_SideLoad, SMPTE_ID3''SMPTE_SideLoad, SMPTE_ID3''SMPTE_ID3'
undefined or no preference'Native supported''Native supported'
undefined or no preference'SMPTE_ID3''No tracks display'