Streaming is available in most browsers,
and in the WWDC app.
-
Explore HLS variants in AVFoundation
Discover how you can use AVFoundation APIs to highlight different variants of your content within your app. We'll show you how you can inspect HLS content using these APIs for different video characteristics, including attributes like SDR/HDR, FPS, and the like. And we'll explore the AVAssetVariant, which represents streaming and offline content.
Resources
- Have a question? Ask with tag wwdc21-10143
- HTTP Live Streaming - Overview
- Search the forums for tag wwdc21-10143
Related Videos
WWDC21
WWDC 2020
-
DownloadArray
-
-
0:40 - HLS Master Playlist
#EXTM3U #EXT-X-VERSION:7 #EXT-X-INDEPENDENT-SEGMENTS #EXT-X-MEDIA:TYPE=AUDIO,NAME="English",GROUP-ID="stereo",LANGUAGE="en",DEFAULT=YES, AUTOSELECT=YES,CHANNELS="2",URI="en_stereo.m3u8" #EXT-X-MEDIA:TYPE=AUDIO,NAME="French",GROUP-ID="stereo",LANGUAGE="fr",DEFAULT=NO, AUTOSELECT=YES,CHANNELS="2",URI="fr_stereo.m3u8" #EXT-X-MEDIA:TYPE=AUDIO,NAME="English",GROUP-ID="atmos",LANGUAGE="en",DEFAULT=YES, AUTOSELECT=YES,CHANNELS="16/JOC",URI="en_atmos.m3u8" #EXT-X-MEDIA:TYPE=AUDIO,NAME="French",GROUP-ID="atmos",LANGUAGE="fr",DEFAULT=NO, AUTOSELECT=YES,CHANNELS="16/JOC",URI="fr_atmos.m3u8" #EXT-X-STREAM-INF:BANDWIDTH=14516883,VIDEO-RANGE=SDR,CODECS="avc1.64001f,mp4a.40.5", AUDIO="stereo",FRAME-RATE=23.976,RESOLUTION=1920x1080 sdr_variant.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=34516883,VIDEO-RANGE=PQ,CODECS="dvh1.05.06,ec-3", AUDIO="atmos",FRAME-RATE=23.976,RESOLUTION=3840x1920 dovi_variant.m3u8
-
3:38 - Peak bitrate cap predicate
let peakBitRateCap = NSPredicate(format: "peakBitRate < 5000000") let peakBitRateCapQualifier = AVAssetVariantQualifier(predicate: peakBitRateCap)
-
3:55 - HDR predicate
let hdrOnlyPredicate = NSPredicate(format: "videoAttributes.videoRange == %@", argumentArray: [AVVideoRange.pq]) let hdrOnlyQualifier = AVAssetVariantQualifier(predicate: hdrOnlyPredicate)
-
4:46 - Content configuration
let variantPref = AVAssetVariantQualifier(predicate: NSPredicate(format: "videoAttributes.videoRange == %@ && peakBitRate < 5000000", argumentArray: [AVVideoRange.pq])) let myMediaSelections : [AVMediaSelection] = [enAudioMS, frAudioMS, enLegibleMS] //English, French audio and English subtitle renditions let contentConfig = AVAssetDownloadContentConfiguration() contentConfig.variantQualifiers = [variantPref] contentConfig.mediaSelections = myMediaSelections
-
6:29 - Download configuration
let asset = AVURLAsset(url: URL(string: "http://example.com/master.m3u8")!) let dwConfig = AVAssetDownloadConfiguration(asset: asset, title: "my-title") /* Primary content config */ let varPref = NSPredicate(format: "videoAttributes.videoRange == %@ && peakBitRate < 5000000", argumentArray: [AVVideoRange.pq]) let varQf = AVAssetVariantQualifier(predicate: varPref) dwConfig.primaryContentConfiguration.variantQualifiers = [varQf] dwConfig.primaryContentConfiguration.mediaSelections = [enAudioMS, frAudioMS, enLegibleMS] //English, French audio and English subtitle renditions /* Aux content config */ let auxVarPref = NSPredicate(format: "%d IN audioAttributes.formatIDs", argumentArray: [kAudioFormatAppleLossless]) let auxVarQf = AVAssetVariantQualifier(predicate: auxVarPref) let auxContentConfig = AVAssetDownloadContentConfiguration() auxContentConfig.variantQualifiers = [auxVarQf] auxContentConfig.mediaSelections = [enAudioMS] //english audio dwConfig.auxiliaryContentConfigurations = [auxContentConfig] dwConfig.optimizesAuxiliaryContentConfigurations = true
-
7:42 - Download task
let myAssetDownloadDelegate = MyDownloadDelegate() let avurlsession = AVAssetDownloadURLSession(configuration: URLSessionConfiguration.background(withIdentifier: "my-background-session"), assetDownloadDelegate: myAssetDownloadDelegate, delegateQueue: OperationQueue.main) let asset = AVURLAsset(url: URL(string: "http://example.com/master.m3u8")!) let dwConfig = AVAssetDownloadConfiguration(asset: asset, title: “my-title”) ... let downloadTask = avurlsession.makeAssetDownloadTask(downloadConfiguration: dwConfig) downloadTask.resume() let progress = downloadTask.progress
-
8:10 - Direct variant selection
/* Example for direct variant selection */ let asset = AVURLAsset(url: URL(string: "http://example.com/master.m3u8")!) let dwConfig = AVAssetDownloadConfiguration(asset: asset, title: "my-title") /* Primary content config */ let myVariant : AVAssetVariant = ... let myMediaSelections : [AVMediaSelection] = ... let variantQf = AVAssetVariantQualifier(variant: myVariant) dwConfig.primaryContentConfiguration.variantQualifiers = [variantQf] dwConfig.primaryContentConfiguration.mediaSelections = myMediaSelections /* Aux content config */ let myAuxVariant : AVAssetVariant = ... let myAuxMediaSelections : [AVMediaSelection] = ... let auxVariantQf = AVAssetVariantQualifier(variant: myAuxVariant) let auxContentConfig = AVAssetDownloadContentConfiguration() auxContentConfig.variantQualifiers = [auxVariantQf] auxContentConfig.mediaSelections = myAuxMediaSelections dwConfig.auxiliaryContentConfigurations = [auxContentConfig]
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.