在实时音视频通信中,你可以通过视频画面中添加的自定义水印,实现版权声明、品牌宣传或记录等。

说明:

  • 不支持在由多路流合成的视频流上添加水印。参与合成且添加了水印的单路视频流会正常显示水印。
  • 不支持在 iOS 的屏幕流上添加水印。
前提条件

你已经集成了 V3.39.1 及以后版本的 RTC SDK,并实现了基本的音视频通话。
支持水印功能的 SDK 详见API 参考。

功能说明
1. 添加水印

调用 setVideoWatermark 为指定视频画面添加水印图片。

public abstract int setVideoWatermark(StreamIndex streamIndex, String imagePath, RTCWatermarkConfig watermarkConfig);
java
- (int)setVideoWatermark:(ByteRTCStreamIndex)streamIndex
            withImagePath:(NSString * _Nullable)imagePath
   withRtcWatermarkConfig:(ByteRTCVideoWatermarkConfig* _Nonnull)rtcWatermarkConfig;
swift
int setVideoWatermark(StreamIndex stream_index, const char* image_path, RTCWatermarkConfig config)
cpp

参看以下章节了解更多水印参数设置说明。

水印图片路径

setVideoWatermark 的必填参数包含图片路径 imagePath。将水印图片所在目录的绝对路径通过 imagePath 传入。

// 除了绝对路径,你也可以通过 assets 或 uri 指定水印图片。以 assets 为例。
// 注意:不支持使用相对路径。
mRTCVideo.setVideoWatermark(StreamIndex.STREAM_INDEX_MAIN,"/assets/img.png",rtcWatermarkConfig);
java
// 传入图片的绝对路径, 以 Document 目录为例。
let filePath = Bundle.main.path(forResource: "watermark", ofType: "jpg")!
self.rtcVideo?.setVideoWatermark(.main, withImagePath: filePath, withRtcWatermarkConfig: config)
swift
// 传入图片的绝对路径, 以 Document 目录为例。
std::string path = "C:/Users/Admin/Documents/1.jpg";
ret = m_video->setVideoWatermark(bytertc::kStreamIndexMain, path.c_str(), config);
cpp

对于 Apple 应用,应在设置中将 Application supports iTunes file sharing 设置为 Yes,可以通过 ITunes 推送水印图片。

public abstract int setVideoWatermark(StreamIndex streamIndex, String imagePath, RTCWatermarkConfig watermarkConfig);
java
$color = "red";
echo "My car is " . $color . "<br>";
echo "My house is " . $COLOR . "<br>";
echo "My boat is " . $coLOR . "<br>";
swift
$color = "red";
echo "My car is " . $color . "<br>";
echo "My house is " . $COLOR . "<br>";
echo "My boat is " . $coLOR . "<br>";
cpp

水印图片尺寸

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 时,水印大小和位置的计算方式如下。

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);
java
let config = ByteRTCVideoWatermarkConfig.init()
config.visibleInPreview = true

let position = ByteRTCVideoByteWatermark.init()
position.x = Float(200.0/480.0)
position.y = Float(200.0/640)
position.width = Float(100.0/480.0)
position.height = Float(100.0/640.0)

//竖屏水印设置
config.positionInPortraitMode = position
//横屏水印设置
config.positionInLandscapeMode = position
swift
// Windows
bytertc::ByteWatermark mark;
config.visibleInPreview = true;
mark.x = 0;
mark.y = 0;
mark.width = 0.5;
mark.height = 0.5;
config.positionInLandscapeMode = mark;
config.positionInPortraitMode = mark;
ret = m_video->setVideoWatermark(bytertc::kStreamIndexMain, path.c_str(), config);
cpp
2. 移除水印

调用 clearVideoWatermark 为指定视频流移除水印。

mRTCVideo.clearVideoWatermark(StreamIndex.STREAM_INDEX_MAIN);
java
self.rtcVideo?.clearVideoWatermark(.main)
swift
ret = m_video->clearVideoWatermark(bytertc::kStreamIndexMain);
cpp
示例项目

参考以下项目获取完整代码。

常见问题

API 参考

说明:表格中的 macOS API 接口为 Objective-C,而示例项目中的 macOS 项目使用的是 Windows SDK 中的 API 接口。

接口AndroidiOSMacWindowsLinuxFlutterElectron
添加水印setVideoWatermarksetVideoWatermark:withImagePath:withRtcWatermarkConfig:setVideoWatermark:withImagePath:withRtcWatermarkConfig:setVideoWatermarksetVideoWatermarksetVideoWatermarksetVideoWatermark
清除水印clearVideoWatermarkclearVideoWatermark:clearVideoWatermark:clearVideoWatermarkclearVideoWatermarkclearVideoWatermarkclearVideoWatermark