HarmonyOS 鸿蒙Next中视频添加水印;官网文档没有具体的API和实现流程;是只能用FFmpeg命令行实现嘛?后面官网文档会有具体的API实现和流程吗?
HarmonyOS 鸿蒙Next中视频添加水印;官网文档没有具体的API和实现流程;是只能用FFmpeg命令行实现嘛?后面官网文档会有具体的API实现和流程吗? 视频添加水印;官网文档没有具体的API和实现流程;是只能用FFmpeg命令行实现嘛?后面官网文档会有具体的API实现和流程吗?
开发者您好,可以采取以下方式解决:
【解决方案】
方案一:不对视频本身进行修改,在视频窗口上覆盖需要添加的字块或者图像,可使用Video组件的controls(value: boolean)属性控制视频播放的控制栏是否显示。
- 通过UI组件的overlay通用属性将自定义组件覆盖在Video组件显示页面上添加自定义水印效果。
@Builder
WatermarkBuilder() {
Column() {
// 自定义水印组件样式实现
// ...
}
}
Video({
// ...
})
.width('100%')
.height(600)
.alignItems(HorizontalAlign.Center)
.overlay(this.watermarkBuilder())
- 使用stack组件叠加在UI组件上层:
Stack({ alignContent: Alignment.Center }) {
Column() {
Image($r('app.media.empty'))
.width(110)
.height(88)
}
Watermark({ rotationAngle: 20 })
}
方案二:对视频本身进行修改,为每一帧视频添加水印效果。
获取视频的视频帧,对视频帧和水印内容在画布上绘制,绘制好的图像传递给视频编码器的buffer队列。例如在录像中需要对视频添加水印。在ArkTS侧通过监听相机预览流的imageArrival事件,获取预览帧,对每一帧图片添加水印,将添加水印后的图片buffer,传输给给编码器合成视频。具体实现步骤如下:
- 定义监听并绘制水印的函数: 注册ImageReceiver图像监听事件onImageArrival获取视频帧,并进行水印绘制。创建预览流获取数据的完整示例可见创建预览流获取数据。
onImageArrival(receiver: image.ImageReceiver): void {
// 注册imageArrival监听
receiver.on('imageArrival', () => {
// 获取视频帧图像
receiver.readNextImage((err: BusinessError, nextImage: image.Image) => {
if (err || nextImage === undefined) {
return;
}
// 解析图像内容
nextImage.getComponent(image.ComponentType.JPEG, async (err: BusinessError,imgComponent: image.Component) => {
// 绘制水印到视频帧
this.drawImage2Frame(nextImage, imgComponent)
// 确保当前buffer没有在使用的情况下,可进行资源释放。如果对buffer进行异步操作,需要在异步操作结束后再释放该资源(nextImage.release())
nextImage.release();
})
})
})
}
- 初始化ImageReceiver,关联获取预览流的SurfaceId,对从相机预览流中的每帧数据调用之前定义的onImageArrival。
async initImageReceiver(): Promise<void> {
if (!this.imageReceiver) {
// 创建ImageReceiver,size宽高业务自行定义
let size: image.Size = { width: this.imageWidth, height: this.imageHeight };
this.imageReceiver = image.createImageReceiver(size, image.ImageFormat.JPEG, EIGHT);
// 获取取第一路流SurfaceId
this.imageReceiverSurfaceId = await this.imageReceiver.getReceivingSurfaceId();
// 注册监听处理预览流每帧图像数据
this.onImageArrival(this.imageReceiver);
}
}
- 定义绘制水印的函数,在onImageArrival监听回调中,使用OffscreenCanvas.drawImage离屏画布接口,将帧图片和水印绘制到画布上。 绘制的过程可以在ArkTS侧完成,也可以在C++侧完成参考画布的获取与绘制结果的显示(ArkTS)/画布的获取与绘制结果的显示(C/C++)。
async drawImage2Frame(nextImage: image.Image, imgComponent: image.Component){
if (!imgComponent.byteBuffer) {
return
}
let width = nextImage.size.width;
let height = nextImage.size.height;
let pixelmap: PixelMap | undefined = await image.createPixelMap(imgComponent.byteBuffer, {
size: { height: height, width: width },
srcPixelFormat: EIGHT,
})
if (pixelmap && this.record) {
const height1 = px2vp(height);
const width1 = px2vp(width);
const offScreenCanvas = new OffscreenCanvas(width1, height1);
const offScreenContext = offScreenCanvas.getContext('2d');
// 绘制视频帧和视频水印到画布上
offScreenContext.drawImage(pixelmap, ZERO, ZERO, width1, height1);
offScreenContext.drawImage(this.watermarkPixelmap, top, left, bottom, right);
this.timer += 1;
this.inputpath = this.filepath + '/' + this.timer + '.jpeg';
let pixelmapshow: PixelMap = offScreenContext.getPixelMap(ZERO, ZERO, width1, height1);
let packOpts: image.PackingOption = { format: 'image/jpeg', quality: QUALITY };
let imagePackerApi = image.createImagePacker();
let file = fs.openSync(this.inputpath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
imagePackerApi.packToFile(pixelmapshow, file.fd, packOpts, (err: BusinessError) => {
imagePackerApi.release()
fs.closeSync(file.fd);
})
}
}
注:推荐在C++侧用CPU完成绘制过程,C++侧使用离屏画布有CPU和GPU两种模式,使用CPU绘制时性能更佳。在C++侧调用Bitmap和Canvas来绘画,绘画的内容会输出到绑定的Bitmap内存中。具体可参考CPU后端Canvas的创建与显示。
- 通过视频编码器将视频帧合成视频。参考视频编码。
参考完整demo:VideoWaterMark。
更多关于HarmonyOS 鸿蒙Next中视频添加水印;官网文档没有具体的API和实现流程;是只能用FFmpeg命令行实现嘛?后面官网文档会有具体的API实现和流程吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next视频水印可通过媒体处理框架实现。系统提供PixelMap API创建水印图像,通过AVMetadataExtractor和AVMetadataInjector处理媒体元数据。视频编辑模块支持图层合成,使用AVCompositeImageFilter将水印叠加到视频帧。FFmpeg非必需方案。官方路线图显示媒体能力持续增强,后续版本会提供更完整的多媒体处理API。
目前HarmonyOS Next的视频处理能力仍在完善中,官方暂未提供专门用于视频水印处理的API。现阶段可通过以下方式实现:
-
FFmpeg方案:可通过调用Native层集成FFmpeg库实现水印添加,这是当前较稳定的方案。需要自行处理跨平台编译和性能优化。
-
媒体处理能力:可关注@ohos.multimedia.mediaLibrary和@ohos.image模块,现有API支持基础媒体文件操作和图像处理,可结合使用实现简单水印效果。
-
图形绘制能力:利用@ohos.graphics模块的Canvas或WebGL能力,在播放器上层叠加水印图层,但此方案不改变原始视频文件。
关于后续规划,华为通常会随着系统版本迭代逐步开放多媒体处理能力。建议:
- 关注官方DevEco Studio更新日志
- 查阅ArkTS/NDK开发文档的版本变更说明
- 参与HDC开发者大会获取roadmap信息
当前建议优先采用FFmpeg方案保障功能完整性,同时保持对官方能力更新的关注。