AVPlayerView播放HDR视频亮度偏高,如何禁用HDR或转SDR?
问题描述
我通过AVQueuePlayer、AVPlayerViewController和AVPlayerLooper加载本地缓存文件夹中的视频播放,代码如下。目前播放正常,但HDR视频亮度过高,在QuickTime中播放显示正常,请问如何禁用HDR或将HDR转换为SDR?
internal void LoadVideoUsingURL(string url) { // 在后台线程加载资源避免卡顿 DispatchQueue.GetGlobalQueue(DispatchQualityOfService.Background).DispatchAsync(() => { var avasset = AVAsset.FromUrl(NSUrl.FromFilename(url)); avasset.LoadValuesAsynchronously(new string[] { "duration", "playable" }, () => { DispatchQueue.MainQueue.DispatchAsync(() => { var item = new AVPlayerItem(avasset); if (this.queuePlayer.CurrentItem != item) { this.queuePlayer.ReplaceCurrentItemWithPlayerItem(item); this.looperPlayer = AVPlayerLooper.FromPlayer(this.queuePlayer, item); } }); }); }); } private void LoadView() { try { queuePlayer.Volume = SoundON ? 1.0f : 0; playerViewController.ShowsPlaybackControls = false; queuePlayer.ActionAtItemEnd = AVPlayerActionAtItemEnd.None; playerViewController.VideoGravity = AVLayerVideoGravity.Resize; playerViewController.View.Layer.MasksToBounds = true; ContentView.AddSubview(playerViewController.View); playerViewController.Player = queuePlayer; ContentView.AddSubview(BlackBackground); } catch (Exception ex) { Console.WriteLine(ex.Message); } } public virtual void StartPlaying() { if (queuePlayer.CurrentItem != null && !isPlaying) { if (queuePlayer.Status == AVPlayerStatus.ReadyToPlay) { queuePlayer.Play(); queuePlayer.Volume = Volume; isPlaying = true; } else { this.queuePlayer.CurrentItem.AddObserver(this, new NSString("status"), NSKeyValueObservingOptions.New | NSKeyValueObservingOptions.Initial, StatusObservationContext.Handle); } } }
解决方案
针对HDR视频播放过亮的问题,有两种可行的处理方式:
1. 播放时强制使用SDR渲染(无需转码)
通过设置AVPlayerItem的preferredDisplayCriteria,指定使用SDR显示标准,让AVFoundation自动将HDR内容转换为SDR输出。修改LoadVideoUsingURL方法中创建AVPlayerItem的部分:
var item = new AVPlayerItem(avasset); // 添加SDR显示偏好设置 if (AVDisplayCriteria.SDRDisplayCriteria != null) { item.PreferredDisplayCriteria = AVDisplayCriteria.SDRDisplayCriteria; } if (this.queuePlayer.CurrentItem != item) { this.queuePlayer.ReplaceCurrentItemWithPlayerItem(item); this.looperPlayer = AVPlayerLooper.FromPlayer(this.queuePlayer, item); }
这种方式无需修改原视频文件,直接在播放阶段处理,适合临时播放场景。
2. 将HDR视频转码为SDR(永久修改)
如果需要长期使用SDR版本的视频,可通过AVAssetExportSession将HDR视频转码为SDR格式,示例代码如下:
void ConvertHDRToSDR(AVAsset asset, string outputPath) { var exportSession = AVAssetExportSession.FromAsset(asset, AVAssetExportPresetHighestQuality); exportSession.OutputUrl = NSUrl.FromFilename(outputPath); exportSession.OutputFileType = AVFileType.Mpeg4; // 设置输出为SDR参数 var outputSettings = new AVVideoSettingsCompressed(); outputSettings.ColorProperties = new AVVideoColorProperties() { TransferFunction = AVVideoTransferFunction.SDRVideo, YCbCrMatrix = AVVideoYCbCrMatrix.BT601, ColorPrimaries = AVVideoColorPrimaries.SMPTE_C }; exportSession.VideoSettings = outputSettings.Dictionary; exportSession.ExportAsynchronously(() => { if (exportSession.Status == AVAssetExportSessionStatus.Completed) { // 转码完成后加载SDR视频 LoadVideoUsingURL(outputPath); } else { Console.WriteLine($"转码失败: {exportSession.Error?.LocalizedDescription}"); } }); }
在LoadVideoUsingURL的后台线程中,可先判断视频是否为HDR,再决定是否转码:
avasset.LoadValuesAsynchronously(new string[] { "duration", "playable", "commonMetadata" }, () => { DispatchQueue.MainQueue.DispatchAsync(() => { // 判断视频是否为HDR bool isHDR = avasset.CommonMetadata.Any(meta => meta.CommonKey == AVMetadataCommonKey.ColorSpace && meta.StringValue?.Contains("HDR") == true); if (isHDR) { string tempSDRPath = Path.Combine(Path.GetTempPath(), "temp_sdr_video.mp4"); ConvertHDRToSDR(avasset, tempSDRPath); } else { var item = new AVPlayerItem(avasset); if (this.queuePlayer.CurrentItem != item) { this.queuePlayer.ReplaceCurrentItemWithPlayerItem(item); this.looperPlayer = AVPlayerLooper.FromPlayer(this.queuePlayer, item); } } }); });
这种方式适合需要重复播放同一视频的场景,避免实时转换带来的性能开销。
额外优化(iOS 16+/macOS Ventura+)
如果系统版本符合要求,可直接设置AVPlayerViewController的动态范围偏好:
playerViewController.PreferredVideoDynamicRange = AVPlayerViewControllerVideoDynamicRange.SDR;
该属性可直接控制播放器的动态范围输出,实现更简洁的HDR转SDR播放。
内容的提问来源于stack exchange,提问作者Ahmed Mohamed Anas
相关产品推荐
相关产品推荐

