标题有点长, 因为一直没想好怎样简洁的表述这个问题
问题现象: iPhone12拍摄的视频上传到服务器后, 在chrome, ie等浏览器播放会泛白
问题原因: 因为iPhone12默认拍摄杜比视界HDR高动态范围视频, chrome, ie的色彩管理有点问题, 在非HDR显示器显示时候, 还是按照HDR范围显示, 导致色彩出现"过曝"现象
解决方案: 对视频进行转码. 指定色彩管理配置
核心代码:
inline static NSDictionary *lf_assetExportVideoConfig(CGSize size, LFAssetExportSessionPreset preset)
{
float ratio = 1;
CGSize presetSize = lf_assetExportSessionPresetSize(preset);
CGSize videoSize = size;
if (videoSize.width > videoSize.height) {
ratio = videoSize.width / presetSize.height;
} else {
ratio = videoSize.width / presetSize.width;
}
if (ratio > 1) {
videoSize = CGSizeMake(videoSize.width / ratio, videoSize.height / ratio);
}
if (@available(iOS 10.0, *)) {
return @{
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey:[NSNumber numberWithInteger:videoSize.width],
AVVideoHeightKey:[NSNumber numberWithInteger:videoSize.height],
AVVideoScalingModeKey:AVVideoScalingModeResizeAspectFill,
AVVideoCompressionPropertiesKey: @
{
///选择视频颜色编码格式(默认格式会支持HDR, 导致视频在chrome, ie泛白)
///默认为: AVVideoYCbCrMatrix_ITU_R_2020, 为支持HDR的格式, 应当指定为ITU_R_709_2通用配置
AVVideoColorPrimariesKey : AVVideoColorPrimaries_ITU_R_709_2,
AVVideoAverageBitRateKey: [NSNumber numberWithUnsignedLong:lf_assetExportSessionPresetBitrate()],
AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel,
AVVideoAllowFrameReorderingKey:@NO,
AVVideoExpectedSourceFrameRateKey:@24
},
};
} else {
return @{
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey:[NSNumber numberWithInteger:videoSize.width],
AVVideoHeightKey:[NSNumber numberWithInteger:videoSize.height],
AVVideoScalingModeKey:AVVideoScalingModeResizeAspectFill,
AVVideoCompressionPropertiesKey: @
{
AVVideoAverageBitRateKey: [NSNumber numberWithUnsignedLong:lf_assetExportSessionPresetBitrate()],
AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel,
AVVideoAllowFrameReorderingKey:@NO,
AVVideoExpectedSourceFrameRateKey:@24
},
};
}
}
简单总结下:
因为我们这边业务需求是用户上传的视频需要在本地做一次压缩, 我这边采用的方案就是AVAssetExportSession逐帧压缩. 在输出配置里面指定色彩配置即可(即强制把HDR视频转换成SDR视频).
效果如下: