WWDC Quick Look 💓 By SwiftGGTeam
What's new in AVFoundation

What's new in AVFoundation

元の動画を見る

ハイライト

AVFoundation は、iOS 15 / macOS 12 で Swift async/await に基づく非同期属性読み込み API を導入し、これまでの 3 ステップのコールバック プロセスを 1 行のコードに置き換えます。また、カスタム ビデオ構成への時間指定メタデータの挿入もサポートし、.itt および .scc 字幕ファイルを作成する機能を追加します。

主な内容

ビデオ ファイルがあり、その長さとトラック情報を知りたいと考えています。 AVFoundation の古いバージョンでは、これには、非同期読み込みメソッドの呼び出し、コールバックでのステータスの確認、同期されたプロパティの読み取りという面倒な 3 段階のプロセスが必要でした。コードは冗長でエラーが発生しやすいため、読み込み手順をスキップしてプロパティを直接読み取る人が多く、メイン スレッドがブロックされてしまいます。

iOS 15 と macOS 12 では、このエクスペリエンスが完全に変わります。

##詳細

非同期属性の読み込み: 3 ステップから 1 行に

02:16

古い API は次のように記述する必要があります。

// 旧方式:三步流程
asset.loadValuesAsynchronously(forKeys: ["duration", "tracks"]) {
    var error: NSError?
    guard asset.statusOfValue(forKey: "duration", error: &error) == .loaded else { return }
    guard asset.statusOfValue(forKey: "tracks", error: &error) == .loaded else { return }
    let duration = asset.duration
    let audioTracks = asset.tracks(withMediaType: .audio)
}

07:16

新しい API は、Swift async/await を使用すると 1 行に減ります。

func inspectAsset() async throws {
    let asset = AVAsset(url: movieURL)
    let duration = try await asset.load(.duration)
    myFunction(thatUses: duration)
}

02:16

キーポイント:

  • asset.load(.duration)これは非同期であり、メインスレッドをブロックしません。
  • .durationはコンパイル時のタイプセーフな属性識別子であり、戻り値の型は次のとおりです。CMTime
  • try await成功と失敗の両方の状況を統合して処理する
  • ロードに失敗するとエラーがスローされます

複数のプロパティを同時にロードすることもできます。

func inspectAsset() async throws {
    let asset = AVAsset(url: movieURL)
    let (duration, tracks) = try await asset.load(.duration, .tracks)
    myFunction(thatUses: duration, and: tracks)
}

04:02

キーポイント:

  • 複数のプロパティを同時にロードする方が効率的です。AVAsset は I/O をバッチ処理できます。
  • 返される結果は、渡された属性識別子と同じ順序のタプルです。
  • durationはいCMTimetracksはい[AVAssetTrack]

属性の読み込みステータスを確認する

04:52

新しい API が提供するのは、status(of:)待たずに物件状況を確認する方法:

switch asset.status(of: .duration) {
case .notYetLoaded:
    // 初始状态,尚未请求加载
    break
case .loading:
    // 正在加载中
    break
case .loaded(let duration):
    // 加载成功,直接使用值
    print(duration)
case .failed(let error):
    // 加载失败
    print(error)
}

04:52

キーポイント:

  • .notYetLoaded初期状態では、AVAsset はオンデマンドでロードされます
  • .loading非同期で処理されていることを示します
  • .loaded関連する値を保持し、直接使用可能
  • .failedエラーメッセージを伝える

非同期フィルタリング方式

06:32

プロパティの読み込みに加えて、AVAsset と AVAssetTrack には新しい非同期フィルタリング メソッドも追加されています。

let asset: AVAsset
let track = try await asset.loadTrack(withTrackID: 1)
let audioTracks = try await asset.loadTracks(withMediaType: .audio)
let legibleTracks = try await asset.loadTracks(withMediaCharacteristic: .legible)
let metadata = try await asset.loadMetadata(for: .quickTimeMetadata)
let chapterGroups = try await asset.loadChapterMetadataGroups(bestMatchingPreferredLanguages: ["en-US"])
let audibleGroup = try await asset.loadMediaSelectionGroup(for: .audible)

let track: AVAssetTrack
let segment = try await track.loadSegment(forTrackTime: .zero)
let sampleTime = try await track.loadSamplePresentationTime(forTrackTime: .zero)
let associatedTracks = try await track.loadAssociatedTracks(ofType: .audioFallback)

06:32

キーポイント:

  • loadTrack(withTrackID:)ID で特定のトラックを取得する
  • loadTracks(withMediaType:)メディアタイプ(オーディオ/ビデオ/字幕)でフィルタリングします
  • loadTracks(withMediaCharacteristic:)特性によるフィルタリング (可聴/視覚/読み取り可能)
  • loadMetadata(for:)メタデータを特定の形式でロードする
  • loadMediaSelectionGroup(for:)メディア選択グループ (多言語オーディオ トラックなど) をロードします。

レガシー API 移行ガイド

08:09

Apple は、将来のリリースで古い同期 API を廃止する予定です。移行パスは明確です。

古い API新しい API
loadValuesAsynchronously + statusOfValue+ 同期プロパティtry await asset.load(.property)
loadValuesAsynchronously + statusOfValue+ 同期フィルタリング方法try await asset.loadTracks(...)
statusOfValue(forKey:)+ 同期プロパティswitch asset.status(of: .property)

同期コンテキストでロードされた値を取得する必要がある場合は、ステータスを確認した後にアサートできます。

guard case .loaded(let tracks) = asset.status(of: .tracks) else { return }
// tracks 已加载,可以同步使用

09:49

キーポイント:

  • もう一度電話しますload(.tracks)作業の重複はなく、キャッシュされた値が返されます
  • しかしload非同期コンテキストでのみ呼び出すことができます
  • 同期コンテキストで使用されますstatus(of:)確認して開梱する
  • 属性が読み込まれた後、次の状態になることもあります。.failed

カスタムビデオコンポジションのタイムメタデータ

11:49

新しい API により、カスタム ビデオ コンポジションで時間指定されたメタデータを渡すことができます。たとえば、GPS データがあり、各フレームを合成するときに位置情報に基づいて画像を調整したいとします。

セットアップ手順:

// 告诉 video composition 哪些 metadata track 相关
videoComposition.sourceSampleDataTrackIDs = [4, 5]

// 每个 instruction 指定需要哪些 track
instruction1.requiredSourceSampleDataTrackIDs = [4]
instruction2.requiredSourceSampleDataTrackIDs = [4, 5]

11:49

合成コールバックでメタデータを読み取ります。

func startRequest(_ request: AVAsynchronousVideoCompositionRequest) {
    for trackID in request.sourceSampleDataTrackIDs {
        let metadata: AVTimedMetadataGroup? = request.sourceTimedMetadata(byTrackID: trackID)
        // 或者用 sourceSampleBuffer(byTrackID:) 获取原始 CMSampleBuffer
    }
    // 用 metadata 合成视频帧
    request.finish(withComposedVideoFrame: composedFrame)
}

12:44

キーポイント:

  • sourceSampleDataTrackIDs作曲レベルと指導レベルの両方で設定する必要があります
  • sourceTimedMetadata(byTrackID:)解析されたものを返すAVTimedMetadataGroup
  • sourceSampleBuffer(byTrackID:)原本を返却するCMSampleBuffer
  • 両方のセットアップ手順が必須です。そうしないとメタデータが受信されません。

字幕ファイルの作成

13:57

macOS 12 では、2 つの字幕ファイル形式に対する新しいオーサリング サポートが追加されています。

  • iTunes タイムドテキスト (.itt): 字幕ファイル
  • シナリオ クローズド キャプション (.scc): クローズド サブタイトル ファイル

コア API:

// AVCaption 表示单条字幕
let caption = AVCaption(text: "Hello", timeRange: timeRange)

// 用 AVCaptionConversionValidator 验证兼容性
let validator = AVCaptionConversionValidator()

// AVCaptionRenderer 预览字幕效果
let renderer = AVCaptionRenderer()
renderer.render(caption, to: cgContext)

14:30

キーポイント:

  • AVCaptionテキスト、位置、スタイルなどの属性が含まれます。
  • AVAssetWriterInputCaptionAdaptor字幕をファイルに書き込む
  • AVAssetReaderOutputCaptionAdaptorファイルから字幕を読み取る
  • AVCaptionConversionValidatorターゲット形式との字幕の互換性を確認する
  • .scc 形式には厳しい文字予算制限があり、バリデーターは調整を推奨します。

重要なポイント

  1. 既存の AVAsset プロパティ読み取りコードを async/await に移行します。古い 3 ステップのコールバック コードは冗長でエラーが発生しやすかったですが、新しい API はそれを 1 行で実行します。入口API:try await asset.load(.duration)

  2. GPS 駆動のダイナミック合成をビデオ編集アプリケーションに組み込みます。 GPS データを時間指定メタデータ トラックとして書き込み、カスタム コンポジターで読み取って画面を調整します。入口API:videoComposition.sourceSampleDataTrackIDs + request.sourceTimedMetadata(byTrackID:)

  3. ビデオ プラットフォームに字幕ファイル生成機能を追加します。 AVCaption と AVAssetWriterInputCaptionAdaptor を使用して、.itt または .scc ファイルをバッチ生成します。入口API:AVCaption + AVCaptionConversionValidator

  4. 同期コードでロードされたプロパティを安全に取得します。使用status(of:)同期コンテキストでの非同期メソッドの呼び出しを避けるために、ステータスを確認した後にラップを解除します。入口API:asset.status(of: .property)

  5. 複数の属性をバッチでロードしてパフォーマンスを向上させます。 1回の電話load(.duration, .tracks, .metadata)3 回の個別の呼び出しよりも効率的です。入口API:try await asset.load(.duration, .tracks)

関連セッション

コメント

GitHub Issues · utterances