Behavior (iOS v3)


DVR

DVR functionality allows viewers to pause, play, and rewind live events. If viewers begin watching an event past the initial broadcast time, and do not want to miss any important content, this allows them to start at an earlier position. If DVR is supported and enabled on the streaming server, add ?DVR to the video URL (eg. http://mydomain.com/video.m3u8?DVR) to indicate to the player that the HLS Playlist is a DVR stream. JWP will, in turn, adjust the visual elements on the control bar to support DVR and make it clear to the viewer that the live stream can be paused or rewound to a point in the past.



Background Audio

All iOS apps have a default audio session that comes preconfigured. Although the default audio session provides useful behavior, it doesn't provide the general audio behavior you need when building a media playback app. To change the default behavior, you configure your app’s audio session category.

Of the seven categories, the one most playback apps need is called AVAudioSessionCategoryPlayback / playback. This category indicates that audio playback is a central feature of your app. When you specify this category, your app’s audio continues with the Ring/Silent switch set to silent mode. With this category, your app can also play background audio if you're using the Audio, AirPlay, and Picture in Picture background mode (see the AVAudioSession docs for an overview).

πŸ“˜

If you have not enabled the "Audio, AirPlay and Picture in Picture" setting in the Background Modes of your project's capabilities list, add the UIBackgroundModes key in your app's info.plist and set its value to an array containing the string "audio".

Since updating the session is a blocking operation, the best practice is to perform this operation on a background concurrent thread (not shown).

The snippets below do not implement error handling for the sake of clarity.


To set the category, add the following code to your app, conventionally in the AppDelegate's didFinishLaunchingWithOptions method:

NSError *error;
[AVAudioSession.sharedInstance setCategory:AVAudioSessionCategoryPlayback error:&error];
[AVAudioSession.sharedInstance setActive:YES error:&error];
// Swift < 4.2
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try? AVAudioSession.sharedInstance().setActive(true)

// Swift 4.2
try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback, options: [])
try? AVAudioSession.sharedInstance().setActive(true, options: [])

For more on this topic, such as AVAudioSession options allowing AirPlay and Bluetooth, see the Apple docs AVAudioSession, and especially Audio Session Categories and Modes.

πŸ“˜

Per Apple's documentation, adding the audio string to the UIBackgroundModes array in your Info.plist will also enable streaming via AirPlay.

❗️

onPause can be called when the app is sent to the background in iOS 14.x. This is a bug in Apple's AVPlayer framework (openradar/FB8722590, dev.apple/forums/thread/660673) propagating downstream to the SDK, and can be partially worked around by calling pause(), perhaps with a slight delay, in applicationWillResignActive and/or applicationDidEnterBackground.



Lock screen controls

An application reproducing content with JWP will display controls on the device's lock screen by default as long as background audio is enabled.

  • Play/Pause will always be displayed and can be toggled with the Apple AirPod and EarPod headphones.
  • 'Previous' and 'Next' will appear grayed out when playing single items and ads.
  • 'Previous' will be grayed out for the first item of a playlist.
  • 'Next' will not be grayed out for the last item of a playlist; instead, tapping 'Next' will 'wrap-around' to load the first item of the playlist.

Additionally, information about the content being reproduced will be displayed:

  • Information set in a JWPlaylistItem (e.g., 'title' and 'image') will be displayed.
  • If absent from the JWPlaylistItem, the information set in the JWConfig will be displayed.
  • If a title is not specified in either place, the name of the application will be displayed in place of a title.
  • When Google IMA ads are playing, the title switches to "Advertisement".

If you wish to disable this feature and/or override it with your own settings, set the JWPlayerController's displayLockScreenControls property to NO.

πŸ“˜

In order for Lock Screen controls to appear, the audioSession's categoryOptions property must include AVAudioSessionCategoryOptionDefaultToSpeaker / defaultToSpeaker or AVAudioSessionCategoryOptionAllowBluetooth / allowBluetooth, or return 0.



Custom asset options

When initializing the player, an options dictionary for AVURLAsset customization can be specified, via the 'assetOptions' property in JWConfig, JWSources, or JWPlaylistItem.

The AVURLAsset customization options are described in AVURLAsset documentation.

For example:

JWConfig *config = [[JWConfig alloc] initWithContentUrl:@"your url"];
config.assetOptions = @{@"AVURLAssetHTTPHeaderFieldsKey":@{@"cookie": @"cookie data"}};
var config = JWConfig(contentUrl: "your url")
config.assetOptions = ["AVURLAssetHTTPHeaderFieldsKey": ["cookie": "cookie data"]]