许多人使用他们的 Android 设备共享视频。由于共享应用执行的处理,接收到的视频质量通常低于原始质量。本文档介绍了如何优化共享视频的质量以及一些常见的视频处理陷阱,以避免这些陷阱。要优化 HDR 视频内容的共享,请参阅本页上的使用 Transformer 模块将 HDR 转码为 SDR。
最重要的是保持恒定的分辨率,并在准备共享视频时尽可能长时间地保持尽可能高的视频质量。
共享管道
图1说明了共享视频的典型流程。
管道包括以下步骤
- 捕获并编码视频,可能在捕获过程中添加特效。或者,用户可以跳过此步骤并从存储中选择从其他应用预先录制好的视频。
- 编辑、过滤、修饰或以其他方式处理视频。
- 缩放或调整视频大小,以准备进行转码。
- 转码视频以供共享。步骤2中的过滤通常在此步骤中应用。
在管道中有两个步骤可以设置决定视频质量的参数:初始录制时的编码和共享前的转码。此外,您可能需要在最终转码步骤之前重新调整视频大小,这也会影响质量。
建议
表1显示了视频质量的五个主要参数,并指示哪些步骤可以使用它们。
参数 | 捕获 | 共享 |
配置文件 | Y | Y |
分辨率 | Y | Y |
比特率 | Y | Y |
量化参数 (QP) | (很少) | Y |
B帧 | N | Y |
配置文件
为了获得更好的结果,请使用特定编解码器提供的更高级的配置文件。对于AVC编码,请选择高配置文件和级别4。
分辨率、裁剪和缩放
您可以在共享前转码的缩放步骤中更改捕获视频的初始分辨率,但缩放会降低视频质量。我们建议您避免缩放,并为初始编码选择一个可以在整个管道中使用的分辨率。还要记住,极端的裁剪会导致图像质量下降,尤其是在您放大裁剪后的图像时。请遵循以下指南
- 选择的分辨率至少与最终共享分辨率一样大。
捕获分辨率不应大大超过共享分辨率,除非所有中间步骤都设计为支持更大分辨率(例如,初始捕获期间的更高比特率)。
- 如果共享编码生成720x1280分辨率,我们建议使用720x1280捕获分辨率。
- 如果捕获和共享之间的中间步骤包括裁剪,请使用更高的捕获分辨率,例如1080x1920,并提高捕获比特率以处理额外的像素。
极端的裁剪会导致图像质量下降,尤其是在放大裁剪后的图像时。
避免从较低分辨率向上缩放至较高分辨率。向上缩放会尝试创建不存在的细节。从一开始就保持所需的高分辨率。
如果必须进行向上缩放,请调整编码参数。例如,如果向上缩放后的分辨率具有两倍的像素,则将比特率加倍。
分辨率和比特率是相互关联的。例如,通过最终转码为低比特率的共享管道传输高分辨率视频,产生的图像质量低于从较低分辨率开始。随着比特率降低,会出现一些交叉点,在这些交叉点上,较小的分辨率开始产生更好的结果
比特率 | 分辨率 |
5+ Mbps | 1080x1920 |
1.5 - 5+ Mbps | 720x1280 |
1.5 Mbps或更低 | SD等效。9:16纵横比中相同的像素数约为416x736 |
许多流行的应用以720p或更低的分辨率共享视频。数据表明,对于1.5到5 Mbps之间的比特率目标,720p分辨率是一个合适的选择。
比特率
录制
使用更高的编码比特率可以最大程度地提高视频质量。我们建议选择与原生相机应用匹配的比特率。对于720x1280分辨率,我们建议捕获比特率为10 Mbps。
由于捕获编码是在设备上完成的,因此您可以使用更高的比特率来补偿大多数共享步骤转换,而不会产生负面影响。较大的结果文件仅用于设备上的操作。
您可以降低最终转码步骤中的比特率,如表2所示。
共享
比特率在共享时影响最大,因为它直接关系到将要上传的视频的大小。视频质量、文件传输时间和云存储成本之间存在权衡。
编码配置文件、B帧和QP边界值的选择在此阶段也比捕获阶段更重要。
我们建议使用4-5 Mbps之间的比特率(对于720x1280分辨率),以确保良好的视觉质量。
量化参数 (QP)
在Android 12及更高版本上,QP键已标准化,并在MediaFormat
API和NDK媒体库中可用。在较早的Android版本上,QP操作仅通过使用MediaFormat
配置中的供应商特定键的框架函数可用。
录制
在视频捕获期间,使用比特率控制而不是QP设置,因为QP设置并不总是可用。
我们不建议调整720x1280的10Mbps捕获比特率的QP设置。如果捕获比特率明显低于720x1280的5 Mbps,则QP设置为40是在提高质量与避免编解码器过于频繁地超出目标比特率之间的一个很好的折衷方案。
共享
我们建议最大QP边界为40,尤其是在比特率低于4 Mbps时。虽然这可以确保编码视频的最低质量,但它可能会产生比特率更高的结果。比特率的增加取决于视频的复杂性。尽管共享应用可能会容忍生成视频的比特率发生一些变化,但它可能无法容忍超过某个阈值的增加。
您可以通过使用限制较少的(更高的)最大QP边界重新编码要共享的视频来限制比特率的增加。这使编解码器能够更自由地牺牲质量并保留视频的其他部分。您可以重新编码要共享的视频,因为它是一个转码操作;您已经捕获了您打算共享的视频。
缺点是使用这些不同的参数重复转码步骤会增加共享视频所需的时间。减少此延迟的一种方法是查看部分转码的视频,以确定其是否在您的比特率超额容差范围内。如果不是,您可以停止转码并尝试使用更合适的QP参数再次进行转码。
B帧和编码配置文件
考虑仅在共享步骤期间使用B帧,并且仅在运行Android 10或更高版本时使用。
应用应使用CodecCapabilities
检查支持的编码配置文件,因为并非所有设备都支持主配置文件或高配置文件。使用AVC编码器支持的最高配置文件:高 > 主 > 基线。为了获得最安全的结果,在使用基线配置文件时不要配置B帧(KEY_LATENCY
或KEY_MAX_B_FRAMES
),因为某些编码器可能会配置失败。
以下代码段假设一个'MediaFormat format'
,它将用于配置AVC编码器
Android 10
API 29或更高版本
使用支持的最高配置文件并将B帧参数设置为1
format.setInt32(KEY_PROFILE, AVCProfileHigh);
format.setInt32(KEY_MAX_B_FRAMES, 1);
在这种情况下,不要设置KEY_LATENCY
。
Android 8、8.1和9
API 26、27、28
使用支持的最高配置文件,但禁用B帧的生成。这适应了这些系统版本中MediaMuxer
的一些限制
format.setInt32(KEY_PROFILE, AVCProfileHigh);
format.setInt32(KEY_LATENCY, 1);
KEY_LATENCY
值禁止编解码器生成B帧,但仍然可以利用其他编解码器效率。
如果您的应用未使用MediaMuxer
来组装最终输出文件,您可以通过将KEY_LATENCY
值设置为2而不是1来启用B帧。这应该允许编解码器生成B帧。
Android 7.1及更早版本
API 25及更早版本
为了获得最安全的结果,请使用基线配置文件。
format.setInt32(KEY_PROFILE, AVCProfileBaseline);
在版本7之前,Android AOSP仅支持基线配置文件。但是,OEM可能在某些设备上启用了主配置文件/高配置文件,可能是通过使用供应商特定的配置文件。
如果您的应用未使用MediaMuxer
,则可以在编解码器支持时使用主配置文件或高配置文件。没有公共格式键来控制B帧的数量。
使用Transformer模块将HDR转码为SDR
从Android 13(API级别33)开始,我们建议使用Jetpack Media3的Transformer模块来将HDR内容共享到不支持HDR的应用、服务和设备。Transformer模块通过将输入HDR视频流色调映射到SDR并将其结果保存为MP4来工作,从而可以在不损失细节或图像亮度的情况下成功播放。
注意:在目标系统版本介于Android 12(API级别32)到Android 7.0(API级别24)之间的设备上,Transformer模块的工作方式有所不同。如果设备支持HDR,您的应用将在不进行色调映射的情况下回放内容。如果设备不支持HDR,它将抛出一个错误,指示不支持HDR色调映射。
以下代码设置了一个将输入色调映射到SDR并以输入格式(例如H.264/AVC)重新编码的Transformer
Kotlin
val transformer = Transformer.Builder(context) .setTransformationRequest( TransformationRequest.Builder() .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR) .build()) .addListener(/* ... */) .build()
Java
Transformer transformer = new Transformer.Builder(context) .setTransformationRequest( new TransformationRequest.Builder() .setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR) .build()) .addListener(/* ... */) .build();
要试用色调映射功能,请参阅Transformer演示应用。
您还可以使用MediaCodec
设置色调映射,尽管实现更复杂。有关更多信息,请参阅MediaCodec
参考文档。