AVFoundation で HLS バリアントを探索する
ハイライト
iOS15
AVAssetVariantAPI を使用すると、アプリケーションはさまざまなプロパティ (ビットレート、解像度、HDR タイプ、オーディオ形式) をマスター プレイリストから直接読み取ることができるため、プレイリスト テキストを手動で解析する必要がなくなります。ダウンロードシナリオでは、NSPredicate駆動されるAVAssetVariantQualifierバリアント選択を「いくつかの固定オプション」から「条件の任意の組み合わせ」に進化させましょう。
主な内容
HLS マスター プレイリストには、それぞれ異なる解像度、ビットレート、コーデック、HDR 設定を持つ複数のバリアント ストリームが含まれています。これまで、アプリで「4K Dolby Vision」や「Dolby Atmos」などのバッジを表示するには、プレイリストのテキストを手動で解析する必要がありましたが、これはエラーが発生しやすく、保守が困難でした。
iOS 15で導入されましたAVAssetVariantバリアント情報を構造化 API として公開します。AVAssetVariant.VideoAttributesそしてAVAssetVariant.AudioAttributesビデオ属性とオーディオ属性は個別にカプセル化されており、アプリケーションはそれらを直接読み取ることができます。ダウンロードシナリオでは、AVAssetVariantQualifier協力するNSPredicate柔軟なバリアント フィルタリングを実装し、ビット レート制限、HDR 設定、ロスレス オーディオなどの条件の任意の組み合わせをサポートします。
詳細
バリアントチェック API
典型的なマスター プレイリストを例に挙げます (00:40):
#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
このプレイリストには、SDR + ステレオ (1080p) と Dolby Vision + Dolby Atmos (4K) の 2 つのバリエーションがあります。
iOS 15 以降では、API を使用してこれらのプロパティを直接読み取ることができます。
let asset = AVURLAsset(url: masterPlaylistURL)
// すべてのバリエーションを取得する
for variant in asset.variants {
let bitrate = variant.peakBitRate
if let videoAttrs = variant.videoAttributes {
let resolution = videoAttrs.presentationSize // CGSize
let frameRate = videoAttrs.frameRate
let videoRange = videoAttrs.videoRange // .sdr, .hdr, .pq, .hlg
}
if let audioAttrs = variant.audioAttributes {
let channelCount = audioAttrs.channelCount
let formatIDs = audioAttrs.formatIDs
}
}
アプリは、プレイリストを手動で解析することなく、これらのプロパティに基づいて UI にバッジ (「4K」、「Dolby Vision」、「Dolby Atmos」など) を表示できます。
ダウンロード シナリオでのバリアントの選択
HLS オフライン ダウンロードは、2016 年からサポートされています。iOS 15 より前では、バリアントの選択は、HDR スイッチ、ロスレス オーディオ スイッチ、およびいくつかの固定オプションなど、限られたダウンロードタスク オプションを通じて実装されていました。
iOS 15で導入されましたAVAssetVariantQualifier、使用NSPredicateバリアントの好みを表現する (03:38):
// ビットレートの上限: 5Mbps 未満のバリアントを優先します
let peakBitRateCap = NSPredicate(format: "peakBitRate < %d", 5_000_000)
let peakBitRateCapQualifier = AVAssetVariantQualifier(predicate: peakBitRateCap)
// HDR 設定: PQ (Dolby Vision) バリアントのみを選択します
let hdrOnlyPredicate = NSPredicate(
format: "videoAttributes.videoRange == %@",
argumentArray: [AVVideoRange.pq]
)
let hdrOnlyQualifier = AVAssetVariantQualifier(predicate: hdrOnlyPredicate)
複数の条件を組み合わせる (04:46):
let compoundPredicate = NSPredicate(
format: "videoAttributes.videoRange == %@ && peakBitRate < %d",
argumentArray: [AVVideoRange.pq, 5_000_000]
)
let variantPref = AVAssetVariantQualifier(predicate: compoundPredicate)
Content Configuration
AVAssetDownloadContentConfigurationバリエーション設定とメディア選択を結び付ける (04:46):
let myMediaSelections: [AVMediaSelection] = [
enAudioMS, // 英语音频
frAudioMS, // 法语音频
enLegibleMS // 英文字幕
]
let contentConfig = AVAssetDownloadContentConfiguration()
contentConfig.variantQualifiers = [variantPref]
contentConfig.mediaSelections = myMediaSelections
Download Configuration
AVAssetDownloadConfiguration設定をダウンロードするためのルート インターフェイスです (06:29):
let asset = AVURLAsset(url: masterPlaylistURL)
let dwConfig = AVAssetDownloadConfiguration(asset: asset, title: "my-title")
// Primary content config:HDR + 5Mbps 以下 + 英法音频 + 英文字幕
dwConfig.primaryContentConfiguration.variantQualifiers = [varQf]
dwConfig.primaryContentConfiguration.mediaSelections = [enAudioMS, frAudioMS, enLegibleMS]
// 補助コンテンツ構成: ロスレス英語音声
let auxVarPref = NSPredicate(
format: "%d IN audioAttributes.formatIDs",
argumentArray: [kAudioFormatAppleLossless]
)
let auxVarQf = AVAssetVariantQualifier(predicate: auxVarPref)
let auxContentConfig = AVAssetDownloadContentConfiguration()
auxContentConfig.variantQualifiers = [auxVarQf]
auxContentConfig.mediaSelections = [enAudioMS]
dwConfig.auxiliaryContentConfigurations = [auxContentConfig]
dwConfig.optimizesAuxiliaryContentConfigurations = true
optimizesAuxiliaryContentConfigurations(デフォルトは true) AVFoundation にロスレス バリアントを選択させる場合は、ビデオのダウンロードが繰り返されることを避けるために、そのビデオ レンディションがプライマリと同じであることを確認してください。
ダウンロードタスクの作成
let session = AVAssetDownloadURLSession(
configuration: .background(withIdentifier: "my-background-session"),
assetDownloadDelegate: myDelegate,
delegateQueue: .main
)
let downloadTask = session.makeAssetDownloadTask(downloadConfiguration: dwConfig)
downloadTask.resume()
// iOS 15 以降、ダウンロードの進行状況を確認できるようになりました
let progress = downloadTask.progress // KVO-observable
バリアントを直接指定する
述語を使用して表現するのが難しいビジネス ロジックの場合は、バリアントを直接指定できます (08:10)。
let myVariant: AVAssetVariant = ... // asset.variantsからフィルタリングする
let variantQf = AVAssetVariantQualifier(variant: myVariant)
dwConfig.primaryContentConfiguration.variantQualifiers = [variantQf]
注: 直接指定されたバリアントは、ダウンロードするデバイスで再生可能である必要があります。
重要なポイント
-
プレイリストを手動で解析する代わりに AVAssetVariant を使用します: 構造化 API はテキスト解析よりも信頼性が高く、Apple の新しい属性フィールドに自動的に適応します。
-
NSPredicate を使用して任意のフィルタ条件を組み合わせる: ビットレートの上限、HDR の種類、解像度、音声フォーマット、チャンネル数などの属性を述語条件として使用でき、組み合わせ方法が柔軟です。
-
プライマリ + 補助構成によりダウンロード サイズが最適化: プライマリ構成には完全なビデオ + オーディオ + 字幕が含まれ、補助には追加のオーディオまたは字幕トラックのみが追加されます。オンにする
optimizesAuxiliaryContentConfigurations動画を繰り返しダウンロードすることは避けてください。 -
NSProgress を使用してダウンロードの進行状況を表示: iOS 15 以降
AVAssetDownloadTask.progressこれは KVO で監視可能であり、UIProgressView に直接バインドできます。 -
ダウンロード前にデバイスの互換性を確認してください: バリアントを直接指定する場合は、ターゲット バリアントのコーデックと解像度がダウンロードするデバイスでサポートされていることを確認してください。 HDR コンテンツは SDR デバイスでは再生できません。
関連セッション
- WWDC2021 10140 - HLS Dynamic Ad Insertion Exploration — HLS インタースティシャルのバリアント処理
- WWDC2021 10142 - HLS シームレス メディア トランジション — 複数のリソースの連続再生のためのバリアント切り替え
- WWDC2020 10049 - HLS オフライン ダウンロード — HLS ダウンロードの基本
- WWDC2021 10159 - Core Image Kernel の改善 — HDR コンテンツ処理
コメント
GitHub Issues · utterances