HDR(High Dynamic Range,高动态范围 ) 视频,相比普通 SDR(Standard Dynamic Range)视频拥有更高的色深、更广的动态范围和更强的色彩表现力,使得画面更真实、更有层次,很直观的提升视频画质,从而有效提升人们的观影感受。本文为您介绍使用播放器 SDK 时如何播放 HDR 视频。
使用 HDR 视频播放功能前,请确保满足以下条件:
TTVideoEngineUrlSource 时,若视频为 HDR 源,需将 isHDRSource 属性设置为 YES。HDRDefinition 参数以请求 HDR 格式的视频流。客户端获取视频源后,按常规方式设置播放即可。播放前,先通过 isSupportHDR 判断设备是否支持 HDR 播放,示例代码如下:
BOOL support = [self.videoEngine isSupportHDR];
注意
虽然 SDK 提供以上接口判断设备是否支持 HDR,但是我们更建议您自行维护一个支持 HDR 的机型白名单,以便在新机型发布时能更灵活、及时地更新支持列表。
若设备支持 HDR 视频且已知源为 HDR,则可直接设置播放视频。
若您以 DirectUrl 模式播放 HDR 视频,参考设置播放源将 HDR 视频资源的 URL 设置给播放器即可。在创建 TTVideoEngineUrlSource 时,如果视频是 HDR 源,需将其 isHDRSource 属性设置为 YES 。
/** * DirectUrl 模式播放视频 * @param url 播放地址 * @param key 视频的缓存 key,推荐使用可以标记视频的唯一标识,例如 url 的md5值 * @param isHDRUrl YES:HDR 视频 */ - (void)playWithUrl:(NSString *)url key:(NSString *)key isHDRUrl:(BOOL)isHDRUrl { TTVideoEngineUrlSource *source = [[TTVideoEngineUrlSource alloc] initWithUrl:url cacheKey:key]; if (isHDRUrl && [self.videoEngine isSupportHDR]) { source.isHDRSource = YES; } // 设置播放源 [self.videoEngine setVideoEngineVideoSource:source]; // TTSDK 版本 > 1.44.1.6-premium, 在 play 之前开启 VEKKeyIsEnableMetalRenderHDR 配置 [self.videoEngine setOptionForKey:VEKKeyIsEnableMetalRenderHDR value:@(YES)]; // 开始播放 [self.videoEngine play]; }
若您以 Vid 模式播放 HDR 视频,您需要参考以下步骤:
HDRDefinition 参数,从视频点播服务获取对应清晰度的 HDR 源。参数 HDRDefinition 支持的取值为 all、4k、2k、1080p、720p、480p、360p。当 HDRDefinition 为 all 时,请求全部 HDR 和 SDR 档位清晰度视频。当 HDRDefinition 为具体某一清晰度,例如 1080p, 请求 1080p HDR 和 SDR 档位清晰度。如果 1080p 档位清晰度不存在,则返回全部 HDR 档位清晰度,您可根据返回的全部 HDR 档位自行处理。通过 allSupportedResolutions 获取到所有视频点播服务下发的 HDR 和 SDR 档位:
// 当 AppServer 增加 hdrDefinition 参数,通过获取支持的清晰度包括 HDR+SDR, // 您根据自己的业务以及 UI 样式进行处理 NSArray<NSNumber *> *allSupportedResolutions = [engine supportedResolutionTypes];
获取所有档位后,通过 isHDRResolution 方法筛选出 HDR 档位,您可以根据自己业务需求进行页面布局使用。
/** 判断是否是 HDR 档位清晰度 @param resolutionType 清晰度 */ - (BOOL)isHDRResolution:(TTVideoEngineResolutionType)resolutionType { NSDictionary<NSString *, NSNumber *> *resolutionMapDic = [self.videoEngine resolutionMap]; for (NSString *key in resolutionMapDic.allKeys) { NSNumber *resolutionObj = [resolutionMapDic objectForKey:key]; if ([resolutionObj integerValue] == resolutionType && [[key lowercaseString] containsString:@"hdr"]) { return YES; } } return NO; }
若不确定播放源是否为 HDR,可在 videoEngineReadyToDisPlay 回调中对播放源是否为 HDR 进行判断。若为 HDR 则采用 HDR 播放模式,若不是则采用 SDR 播放模式。
// 在首帧回调判断视频源是否为 HDR - (void)videoEngineReadyToDisPlay:(TTVideoEngine *)videoEngine { BOOL isHDRSource = ([[self.videoEngine getOptionBykey:VEKKEY(VEKKeyIsVideoProcessorIsHDRSource_NSInterger)] integerValue] == 1); }
注意
播放 HDR 源前,必须先判断设备是否支持 HDR,如不支持请播放非 HDR 源。
/** * @brief 播放视频 * @param urlSource URL 播放源 * @param isHDRPlay 是否使用默认开启 HDR 播放,播放器 SDK 内部会自动识别 HDR,如果 isHDRPlay:YES,默认使用HDR效果播放,反之正常播放 */ - (void)playWithVideoSource:(TTVideoEngineUrlSource *)urlSource isHDRPlay:(BOOL)isHDRPlay { // 设置播放源 [self.videoEngine setVideoEngineVideoSource:urlSource]; // 开启获取 HDR 播放状态开关 [self.videoEngine setOptionForKey:VEKKeyIsEnableGetHDRStatus value:@(1)]; // 配置 HDR 相关开关,iOS16 以上和 iOS16 以下实现方案有差异,可以按照如下代码配置 // 请在 play/prepare 前调用 if (@available(iOS 16.0, *)) { [self.videoEngine setOptionForKey:VEKKeyIsHDRAutomaticIdentification value:@(1)]; [self.videoEngine setOptionForKey:VEKKeyKeyIsEnableSoftDecodeHDR value:@(1)]; [self.videoEngine setOptionForKey:VEKKeyIsEnableMetalRenderHDR value:@(1)]; [self.videoEngine setOptionForKey:VEKKeyIsDecodeMalFunctionErrorIgnore value:@(1)]; NSMutableDictionary* processorOptions = [NSMutableDictionary dictionaryWithObjectsAndKeys:@(VEKProcessorInitEffect),VEKProcessorActionStr, @(VEKFilterTypeHDR2SDR),VEKProcessorEffectTypeStr, @(1),VEKProcessorHDR2SDRUseHLGStr, @(0),VEKProcessorHDR2SDRUsePQStr, @(0),VEKProcessorHDR2SDREnableCMSmatrixStr, nil]; if (!isHDRPlay) { [processorOptions setObject:@(1) forKey:VEKProcessorUseEffectStr]; } [self.videoEngine setEffectParams:processorOptions]; } else { [self.videoEngine setOptionForKey:VEKKeyPlayerPreferSpdlForHDR_BOOL value:@(YES)]; [self.videoEngine setOptionForKey:VEKKeyPlayerSetSpdlForHDRUrl_BOOL value:@(YES)]; [self.videoEngine setOptionForKey:VEKKeyIsVideoProcessorEnableHDR2SDR_BOOL value:@(!isHDRPlay)]; } // 开始播放 [self.videoEngine play]; }
// 播放过程 hdr 和 sdr 相互切换 - (void)__hdr2sdrSwitch:(BOOL)isSDR { [self.videoEngine setOptionForKey:VEKKeyIsVideoProcessorEnableHDR2SDR_BOOL value:@(isSDR)]; }