在你的 App 中支持 HDR 视频回放,编辑与导出

支持高动态范围(HDR)的 App 可以帮助用户创建更加生动逼真的视频。如果你的 App 支持杜比视界规格的 HDR,使用 iPhone 12 或 iPhone 12 Pro 的用户可以更进一步,直接在他们的设备上拍摄、编辑与播放电影级画质的视频。杜比视界调校将动态应用到每一帧画面,以保留原始镜头的本真面貌。

下面就来看一看如何提供最佳的 HDR 视频回放、编辑和导出体验。

初步了解 HDR 视频

你的 App 需要支持 iOS 14.1 或者更新版本的系统,才能利用 HDR 视频的优势。首先,我们建议你重温一些 WWDC 会议,概览整个流程。

使用AVFoundation在APP上输出HDR影像

Watch now

使用 AVFoundation 编辑和回放 HDR 视频

Watch now

注意:iPhone 12 和 iPhone 12 Pro 使用 HEVC(10-bit)编解码器录制 HDR 视频,Dolby Vision Profile(杜比视界描述文件)为 8.4,BL Signal Cross-Compatibility ID(基础层信号交叉兼容 ID)为 4(HLG,混合对数伽码)。这一格式旨在向后兼容 HLG,允许现有的 HEVC 解码器将视频解码为 HLG 格式。《相机》App 将视频录制为 QuickTime File Format(QTFF)影片(.mov 扩展)。在 QTFF 影片中传输杜比视界信号,类似于在 ISO 基础媒体文件格式中传输杜比视界流媒体信号。


Learn more about Dolby Vision Profiles

Learn more about Dolby Vision Levels

Learn more about Dolby Vision Streams

在你的 App 中支持 HDR 视频回放

iOS 和 macOS 都支持在适合设备上进行 HDR 视频回放。在 AVPlayer 上使用 eligibleForHDRPlayback,检查当前设备是否支持 HDR 回放。通常,AVPlayerAVPlayerlayer 或者 AVSampleBufferDisplayLayer 类都可以用于播放杜比视界视频。如果你的 App 使用 AVPlayer,你无需在代码中添加任何额外内容:如果 AVFoundation 框架探测到杜比视界素材,且设备支持 HDR 回放,它会自动搭建 HDR 回放通道,处理 Dolby Vision Profile 8.4。

如果你的 App 使用 AVSampleBufferDisplayLayer 渲染视频,要确保通过样本缓冲器显示层的样本缓冲器格式适合 HDR,并带有 Dolby Vision Profile 8.4 每一帧的元数据。这些样本缓冲器需要具有 10-bit 或更高的比特位深。通常使用的 10-bit 格式是 4:2:0 Y’CbCr 视频范围,用 kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange 表示。该像素格式关联的 OSType'x420'

如果你的样本缓冲器使用 VTDecompressionSession 解码,你可以使用 kVTDecompressionPropertyKey_PropagatePerFrameHDRDisplayMetadata 在缓冲器中携带 Dolby Vision Profile 8.4 每一帧的元数据。这个值默认为真。

素材检查 AVMediaCharacteristic 提供了指定媒体类型特性的选项,包括一段视频是否包含 HDR 元数据。你可以使用 Swift 媒体特性 containsHDRVideo 来识别一条轨道的任意部分是否包含 HDR,以使你的 App 能正确渲染它。在 Objective-C 里,你可以使用在 AVMediaFormat.h 里定义的 AVMediaCharacteristicContainsHDRVideo

使用 Swift 方法 loadValuesAsynchronously(forKeys:completionHandler:) 读取轨道属性后,你可以使用 tracks(withMediaCharacteristic:) 获取 HDR 轨道。下面来看看如何获取所有想要的 HDR 轨道:

let hdrTracks = asset.tracks(withMediaCharacteristic: .containsHDRVideo)

使用类似的方法,你可以使用 Objective-C 方法 loadValuesAsynchronouslyForKeys:completionHandler: 来读取轨道属性,并使用 tracksWithMediaCharacteristic: 方法获取 HDR 轨道,方法如下:

NSArray<AVAssetTrack *> *hdrTracks 
= [asset tracksWithMediaCharacteristic:AVMediaCharacteristicContainsHDRVideo];

hasMediaCharacteristic(_:) 方法可以用来追踪媒体特性,比如 HDR 媒体类型,格式说明,或者显式标记。例如:

if track.hasMediaCharacteristic(.containsHDRVideo){
// Process HDR track
}

在 Objective-C 中,你可以使用同样的 hasMediaCharacteristic: 方法进行显式标记,如下所示:

if track.hasMediaCharacteristic(.containsHDRVideo){
// Process HDR track
}

在你的 App 中支持 HDR 视频编辑与预览

使用AVVideoComposition在你的应用里添加 HDR 内容编辑。如果你在使用内置排序工具,你也可以使用 Swift 初始值 init(asset:applyingCIFiltersWithHandler:) 或者 Objective-C 初始值 videoCompositionWithAsset:applyingCIFiltersWithHandler: 配合内置的 CIFilters ,轻松在 App 中添加 HDR 编辑通道。

自定义排序工具也可以支持 HDR 内容:你可以使用 supportsHDRSourceFrames 属性表明 HDR 能力。对于 Objective-C,supportsHDRSourceFrames 属性是在 AVVideoCompositing.h 中被定义的 AVVideoCompositing 协议的一部分。

如果你的自定义排序工具需要在 10-bit HDR 像素格式下运行,你需要使用 sourcePixelBufferAttributes 属性选择排序工具能接受为输入的像素缓冲器特性。对于 Objective-C,可以在 AVVideoCompositing.h 中找到该属性。该属性的值是一个包含在 CoreVideo 标题文件 CVPixelBuffer.h 中定义的像素缓冲器属性键的字典类型。

此外,要创建新的处理缓冲器,你需要视频排序器所要求的、正确的像素缓冲器特性。为达到这个特定的目的,使用属性 requiredPixelBufferAttributesForRenderContext

如果你的 App 提供编辑中的视频预览功能,修改像素值可能会使像素现有的动态元数据及其使用失效。因为 Dolby Vision Profile 8.4 元数据是完全透明的,你可以在仅限预览的场景中使用 AVPlayerItem 放置任何无效数据,并在导出时更新动态元数据,以反映视频内容中的改动。

要对 HDR 设置进行配置,你可以使用 AVPlayerItem 中的 appliesPerFrameHDRDisplayMetadata 属性,该属性默认为真。在 Objective-C 里,该属性默认为 YES,可以在 AVPlayerItem.h 中找到。

AVFoundation 在显示视频时将默认尝试使用杜比视界元数据,但你可以让你的 App 忽视它:只要在 Swift 里把 AVPlayerItemappliesPerFrameHDRDisplayMetadata 属性设为假,或者在 Objective-C 里把该属性设为 NO。如果你的应用正在使用 VideoToolbox 里的 VTDecompressionSession API,你可以使用kVTDecompressionPropertyKey_PropagatePerFrameHDRDisplayMetadata 关闭杜比视界色调映射。要在 C 语言或 Objective-C 中使用该属性,要确保在框架标题 VTDecompressionProperties.h 中包含 VideoToolbox。

在你的 App 中支持 HDR 导出

你可以使用 AVAssetWriter 和 HEVC 预设,在 App 中支持 HDR 视频导出。

发现预设与 AVAssetExportSession 所有 HEVC 预设都已升级为支持 HDR。输出格式将匹配源格式,所以如果源文件是 Dolby Vision Profile 8.4,导出的影片也会是 Dolby Vision Profile 8.4。如果你需要更改输出格式,可以使用AVAssetWriter


注意:H.264 预设将把 HDR 转换为标准动态范围(SDR)。


为了在使用 AVAssetWriter 导出的过程中保留 Dolby Vision Profile 8.4,你必须选择合适的输出模式,支持杜比视界的色彩属性,以及 10-bit 的描述文件等级。

首先,要注意在 Swift 里查询 supportedOutputSettingsKeys(for:),或者在 Objective-C 里查询 supportedOutputSettingsKeysForConnection: 会提供支持当前设备的输出设置键的列表。

对于杜比视界导出,视频输出设置字典键 AVVideoCompressionPropertiesKey 允许你控制比特率,B-frame(双向预测帧)传送,I-frame(帧内编码帧)间隔与编解码器质量。与该键相关的值是 NSDictionary 的一个实例。在 Objective-C 里,可以在 AVVideoSettings.h 中找到该键。

举例来说,Swift 中的杜比视界视频输出设置字典将包含下列这些键/值对:

let videoOutputSettings: [String: Any] = [
    AVVideoCodecKey: AVVideoCodecType.hevc,
    AVVideoProfileLevelKey: kVTProfileLevel_HEVC_Main10_AutoLevel,
    AVVideoColorPropertiesKey: [
        AVVideoColorPrimariesKey: AVVideoColorPrimaries_ITU_R_2020,
        AVVideoTransferFunctionKey: AVVideoTransferFunction_ITU_R_2100_HLG,
        AVVideoYCbCrMatrixKey: AVVideoYCbCrMatrix_ITU_R_2020
    ],
    AVVideoCompressionPropertiesKey: [
        kVTCompressionPropertyKey_HDRMetadataInsertionMode: kVTHDRMetadataInsertionMode_Auto
    ]
]

在 Objective-C 中,你的视频输出设置字典会包含同样的键/值对:

NSDictionary<NSString*, id>* videoOutputSettings = @{
    AVVideoCodecKey: AVVideoCodecTypeHEVC,
    AVVideoProfileLevelKey: (__bridge NSString*)kVTProfileLevel_HEVC_Main10_AutoLevel,
    AVVideoColorPropertiesKey: @{
        AVVideoColorPrimariesKey: AVVideoColorPrimaries_ITU_R_2020,
        AVVideoTransferFunctionKey: AVVideoTransferFunction_ITU_R_2100_HLG,
        AVVideoYCbCrMatrixKey: AVVideoYCbCrMatrix_ITU_R_2020
    },
    AVVideoCompressionPropertiesKey: @{
        (__bridge NSString*)kVTCompressionPropertyKey_HDRMetadataInsertionMode: (__bridge NSString*)kVTHDRMetadataInsertionMode_Auto
    }
};

在 Objective-C 里,可以在 VTDecompressionProperties.h 里找到键 kVTCompressionPropertyKey_HDRMetadataInsertionMode 和值 kVTHDRMetadataInsertionMode_Auto

除了定义键/值对,要确保交给 AVAssetWriterInput 的像素缓冲器是 'x420' OSType 代表的 10-bit 4:2:0 Y’CbCr 视频范围。

你可以选择使用单独的 AVAssetReader 或者 AVAssetWriter 模型进行导出。在这种情况下,你可以使用 VideoToolbox 属性 kVTCompressionPropertyKey_PreserveDynamicHDRMetadata,并将其分别针对 C/Objective-C 或 Swift 设为 kCFBooleanFalse 或假。设置 VideoToolbox 属性时,AVAssetWriter 会自动重新计算 Dolby Vision Profile 8.4 元数据以导出文件。在你的 App 修改从 AVAssetReader 导出的帧时,这个步骤应该已经完成了。

Resources

Learn more about AVFoundation

AVFoundation

Video Toolbox

Learn more about Dolby Vision Profiles