WWDC Quick Look 💓 By SwiftGGTeam
AVFoundation で HLS バリアントを探索する

AVFoundation で HLS バリアントを探索する

元の動画を見る

AVFoundation で HLS バリアントを探索する

ハイライト

iOS15AVAssetVariantAPI を使用すると、アプリケーションはさまざまなプロパティ (ビットレート、解像度、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]

注: 直接指定されたバリアントは、ダウンロードするデバイスで再生可能である必要があります。

重要なポイント

  1. プレイリストを手動で解析する代わりに AVAssetVariant を使用します: 構造化 API はテキスト解析よりも信頼性が高く、Apple の新しい属性フィールドに自動的に適応します。

  2. NSPredicate を使用して任意のフィルタ条件を組み合わせる: ビットレートの上限、HDR の種類、解像度、音声フォーマット、チャンネル数などの属性を述語条件として使用でき、組み合わせ方法が柔軟です。

  3. プライマリ + 補助構成によりダウンロード サイズが最適化: プライマリ構成には完全なビデオ + オーディオ + 字幕が含まれ、補助には追加のオーディオまたは字幕トラックのみが追加されます。オンにするoptimizesAuxiliaryContentConfigurations動画を繰り返しダウンロードすることは避けてください。

  4. NSProgress を使用してダウンロードの進行状況を表示: iOS 15 以降AVAssetDownloadTask.progressこれは KVO で監視可能であり、UIProgressView に直接バインドできます。

  5. ダウンロード前にデバイスの互換性を確認してください: バリアントを直接指定する場合は、ターゲット バリアントのコーデックと解像度がダウンロードするデバイスでサポートされていることを確認してください。 HDR コンテンツは SDR デバイスでは再生できません。

関連セッション

コメント

GitHub Issues · utterances