在实时音视频通信中,你可以通过视频画面中添加的自定义水印,实现版权声明、品牌宣传或记录等。
说明:
- 不支持在由多路流合成的视频流上添加水印。参与合成且添加了水印的单路视频流会正常显示水印。
- 不支持在 iOS 的屏幕流上添加水印。
你已经集成了 V3.39.1 及以后版本的 RTC SDK,并实现了基本的音视频通话。
调用 setVideoWatermark 为指定视频画面添加水印图片。
//方法签名
public abstract int setVideoWatermark(StreamIndex streamIndex, String imagePath, RTCWatermarkConfig watermarkConfig);
java参看以下章节了解更多水印参数设置说明。
setVideoWatermark 的必填参数包含图片路径 imagePath。将水印图片所在目录的绝对路径通过 imagePath 传入。
除了绝对路径,你也可以通过 assets 或 uri 指定水印图片。示例代码以 assets 为例。
注意:不支持使用相对路径。
mRTCVideo.setVideoWatermark(StreamIndex.STREAM_INDEX_MAIN,"/assets/img.png",rtcWatermarkConfig);
java传入图片的绝对路径, 例如 Document 目录。
// 以 Document 目录下为例。
NSString * tmpdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString * filename = @"hang_up.png";
NSString * path = [NSString stringWithFormat:@"%@/%@",tmpdir,filename];
[self.rtcVideo SetVideoWatermark:ByteRTCStreamIndexMain WithImagePath:path WithRtcWatermarkConfig:conf];
objectivec在设置中将
Application supports iTunes file sharing设置为Yes,可以通过 ITunes 推送水印图片。
setVideoWatermark 的必填参数 watermarkConfig 类型为 ByteWatermark, 包含水印图片的分辨率大小和位置坐标。详见 RTCWatermarkConfig。
其中,横屏或竖屏的水印大小和位置,通过 RTCWatermarkConfig 的 positionInLandscapeMode 和 positionInPortraitMode 分别设置。参看 视频采集旋转方向 了解关于本地采集视频帧方向适配方法。 注意,ByteWatermark 各成员均为比例,而不是像素,计算方法和说明如下:
| 名称 | 说明 | 计算方法 |
|---|---|---|
x | 水印 x 方向偏移量 | 水印 x 偏移位置 (px) / 本地采集视频帧视频宽度 (px) |
y | 水印 y 方向偏移量 | 水印 y 偏移位置 (px) / 本地采集视频帧视频高度 (px) |
width | 水印宽 | 水印宽度(px) / 本地采集视频帧视频宽度 (px) |
height | 水印高 | 水印高度(px) / 本地采集视频帧视频高度 (px) |
获取本地视频帧采集分辨率:推荐通过 onFirstLocalVideoFrameCaptured 回调获取视频帧分辨率。 你也可以使用 setVideoCaptureConfig 中设置的分辨率。通过 ByteWatermark 中传入的位置和大小值均为距离和当前视频帧画面宽/高的比例。其中,位置的坐标原点为视频帧画面的左上角。
如果视频帧和本地渲染视图大小相同,或使用的渲染模式为 RENDER_MODE_FIT,按照上述公式传入水印的大小和位置信息即可。
当视频帧大小与渲染视图不同,而且渲染模式不为 RENDER_MODE_FIT 时,水印大小和位置的计算方式如下。
RENDER_MODE_HIDDEN 视频帧等比缩放,直到画布被填满:可能出现水印被设置在画布之外,导致不可见的情况。

ByteWatermark 的 x 或 y 的计算方法为:
y = 水印 y 偏移位置 / 视频高度 +((视频高度 - 画布高度)/2)/ 视频高度
x = 水印 x 偏移位置 / 视频宽度 +((视频宽度 - 画布宽度)/2)/ 视频宽度
RENDER_MODE_FILL 视频帧非等比,直到画布被填满:水印宽高比例也会发生变化。


如果不希望水印发生宽高比例变化,传入 ByteWatermark 的 x、y、width、height 应为距离与画布的边长比例系数,即以画布的边长为分母。例如,width = 水印图片宽度 / 画布宽度。
Android
RTCWatermarkConfig rtcWatermarkConfig =new RTCWatermarkConfig();
//水印图片实际大小,单位为 px
float w = 84f*2;
float h = 84f*2;
//水印位置坐标,单位为 px,根据实际情况替换
float x = 50;
float y = 50;
//视频帧宽高,如果不一致需要交换宽高
float videoW = 540f;
float videoH = 960f;
//画布宽高,由用布局确认
float CanvasH = 540f;
float markX = x/videoW;
float markY = y/videoH +((videoH-CanvasH)/2)/videoH;// 避免在渲染模式为 RENDER_MODE_HIDDEN 下水印出现在画布外。
float markW =w/videoW;
float markH =h/videoH;
rtcWatermarkConfig.positionInPortraitMode =new ByteWatermark(markX,markY,markW,markH);
javaconf.positionInLandscapeMode = [[ByteRTCVideoByteWatermark alloc] init];//横屏水印设置
conf.positionInPortraitMode = [[ByteRTCVideoByteWatermark alloc] init];//竖屏水印设置
conf.positionInLandscapeMode.x = 0.1;
conf.positionInLandscapeMode.y = 0.1;
conf.positionInLandscapeMode.width = 0.5;
conf.positionInLandscapeMode.height = 0.5;
conf.positionInPortraitMode.x = 0.1;
conf.positionInPortraitMode.y = 0.1;
conf.positionInPortraitMode.width = 0.5;
conf.positionInPortraitMode.height = 0.5;
[self.rtcVideo SetVideoWatermark:ByteRTCStreamIndexMain WithImagePath:path WithRtcWatermarkConfig:conf];
objectivec调用 clearVideoWatermark 为指定视频流移除水印。
mRTCVideo.clearVideoWatermark(StreamIndex.STREAM_INDEX_MAIN);
javaQ:为什么我通过接口成功设置了水印但是预览画面中没有水印? A:可根据以下列表进行排查:
如果远端能看到水印而本端预览没有水印,请将 RTCWatermarkConfig.visibleInPreview 设置为 true。
如果使用了 setLocalVideoCanvas 将 VideoCanvas 设置为 RENDER_MODE_HIDDEN,请按照 水印图片尺寸 小节中的计算方法提供水印位置参数。
确认已将正确的水印设置参数分别传入 positionInLandscapeMode 和 positionInPortraitMode 。当参数缺省时,对应的位置下的水印将无法显示。例如,只传入 positionInLandscapeMode 时,水印只会在横屏时显示,竖屏时不显示水印。
Q:对本地视频进行镜像设置时,已经添加的水印是否也会镜像? A:开启本地预览镜像,或本地预览和编码传输镜像时,远端水印均不镜像。开启本地预览镜像时,本端水印会镜像。开启本地预览镜像时,建议将 RTCWatermarkConfig.visibleInPreview 设置为 False,不显示本地预览水印。