视频导出是一款视频水印导出应用,支持从相册选取视频,在视频上添加图片水印或文字水印(可拖拽、缩放),并通过 AVCodec NDK + OpenGL ES 在端侧完成视频解码、水印合成、重新编码的全流程。导出过程中利用 实况窗(Live View Kit) 实时展示进度,结合 后台任务(Background Tasks Kit) 实现后台持续导出,导出完成后通过通知或实况窗反馈结果。
| Files | Last commit | Last update |
|---|---|---|
| 3 months ago | ||
| 2 months ago | ||
| 3 months ago | ||
| 9 days ago | ||
| 3 months ago | ||
| 3 months ago | ||
| 2 months ago | ||
| 9 days ago | ||
| 3 months ago | ||
| 3 months ago | ||
| 3 months ago | ||
| 3 months ago |
Exporting Video Watermarks Based on the Background Continuous Task and Live View Capabilities
Overview
VideoExporter is an app that allows users to export video watermarks. It enables users to select videos from the album, add image or text watermarks (which can be dragged and scaled) to the videos, and complete the entire process of video decoding, watermark synthesis, and re-encoding on the device through AVCodec NDK + OpenGL ES. During the export process, Live View Kit is used to display the progress in real time, and Background Tasks Kit is used to continuously export data in the background. After the export is complete, the result is reported through notifications or live views.
Preview
| Video Editing | Video Export | Live View on the Lock Screen | Live Notification |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
How to Use
Permission Application
Live View Permission
Permission for Continuous Tasks of a Special Type
- Apply for the background running permission for special scenarios in the ACL permission application mode.
Notification Permission
- Request the permission from users in the app. For details, see Requesting Notification Authorization.
Note: After the permission application is complete, you need to generate a new signature file.
Experience Journey
- Start the app and tap the video adding button to select a video from the album.
- Select a watermark type (pattern or text).
- Drag the watermark in the preview area to adjust its position. After confirming the position, tap the button to export the video to the gallery.
- Go to the export progress screen and wait until the video synthesis is complete.
- During the export, you can switch to the background, and the live view will continue to display the progress.
- After the export is complete, the video is automatically saved to the system album.
Project Directory
VideoExporter
├──AppScope
│ ├──resources
│ │ └──base // App-level basic resources
│ └──app.json5 // App information (bundle name and version number)
├──entry
│ └──src/main
│ ├──cpp // C++ native video processing pipeline
│ │ ├──capabilities // Codec capability encapsulation
│ │ │ ├──include // Header file
│ │ │ │ ├──demuxer.h
│ │ │ │ ├──muxer.h
│ │ │ │ ├──video_decoder.h
│ │ │ │ └──video_encoder.h
│ │ │ ├──demuxer.cpp // Media demuxer (OH_AVDemuxer)
│ │ │ ├──muxer.cpp // Media muxer (OH_AVMuxer)
│ │ │ ├──video_decoder.cpp // Hardware video decoder (OH_VideoDecoder)
│ │ │ └──video_encoder.cpp // Hardware video encoder (OH_VideoEncoder)
│ │ ├──common // Common definitions
│ │ │ ├──dfx // Logs and error codes
│ │ │ ├──common.h // Namespace constant
│ │ │ ├──sample_callback.cpp // Asynchronous codec callback
│ │ │ ├──sample_callback.h
│ │ │ └──sample_info.h // Core data structures (SampleInfo and WatermarkInfo)
│ │ ├──render // OpenGL ES watermark rendering
│ │ │ ├──egl_render_context.cpp // EGL context management
│ │ │ ├──egl_render_context.h
│ │ │ ├──shader_program.cpp // GL shader compilation and uniform setting
│ │ │ ├──shader_program.h
│ │ │ ├──watermark_renderer.cpp // Watermark synthesis renderer (core)
│ │ │ └──watermark_renderer.h
│ │ ├──transform // Pipeline orchestration
│ │ │ ├──transform.cpp // Full-process controller (decapsulation → decoding → rendering → encoding → encapsulation)
│ │ │ └──transform.h
│ │ ├──types/libnativeexport // Node-API type declaration
│ │ ├──CMakeLists.txt // CMake build configuration
│ │ └──napi_init.cpp // Node-API bridge (startExport/cancelExport)
│ ├──ets // ArkTS application layer
│ │ ├──components
│ │ │ ├──MarkComponent.ets // Watermark components (drag and text input)
│ │ │ ├──TitleComponent.ets // Title bar component
│ │ │ └──VideoComponent.ets // Video preview component
│ │ ├──constants
│ │ │ └──CommonConstants.ets // Common constants
│ │ ├──controllers
│ │ │ ├──ContinueTaskController.ets // Background task controller
│ │ │ ├──LiveViewController.ets // Live view controller
│ │ │ ├──NotificationController.ets // Notification controller
│ │ │ └──TimeoutManager.ets // Timer manager
│ │ ├──entryability
│ │ │ └──EntryAbility.ets // Application entry ability
│ │ ├──model
│ │ │ ├──DataModel.ets // Data model definition
│ │ │ └──DraftStore.ets // Persistent draft storage
│ │ ├──pages
│ │ │ ├──ExportProgressPage.ets // Export progress page
│ │ │ └──MainPage.ets // Main page (video selection and watermark editing)
│ │ └──utils
│ │ ├──FileUtil.ets // File operation utility
│ │ ├──Loading.ets // Loading prompt utility
│ │ ├──Logger.ets // Log utility
│ │ ├──NativeExportUtil.ets // Native export bridge
│ │ ├──ThreadUtil.ets // Thread utility
│ │ └──WaterMarkNativeUtil.ets // Watermark synthesis process orchestration
│ ├──module.json5 // Module configuration (permissions and device types)
│ └──resources
│ ├──base // Basic resource
│ ├──dark // Dark theme resource
│ ├──en_US // English resource
│ ├──rawfile // Original resource file
│ └──zh_CN // Chinese resource
├──build-profile.json5 // Project-level build configuration
├──code-linter.json5 // Code check configuration
├──hvigorfile.ts // Project build script
├──oh-package.json5 // Project-level dependency configuration
└──README.md // Project description document
How to Implement
- Video selection: Use PhotoViewPicker to select a video from the album. The video width, height, and rotation angle are automatically obtained.
- Image watermark: Ten built-in watermark icon templates are provided. You can tap to add a watermark to the video preview area.
- Text watermark: You can enter a custom text watermark (up to 15 characters). The watermark image is generated based on the component screenshot.
- Drag and scale: Watermarks support gesture-based drag and positioning and relative size adjustment. The position is stored using relative coordinates.
- Native video processing pipeline: Full-link video processing is implemented based on the AVCodec NDK, and the multi-thread stream architecture is used:
- Demuxer: Use
OH_AVDemuxerto parse the video/audio track and extract encoding parameters. - Hardware decoding (VideoDecoder): Use
OH_VideoDecoderto decode video frames and output them to the NativeImage Surface. - Watermark rendering (WatermarkRenderer): In an independent GL thread, use OpenGL ES to dynamically build a fragment shader to support the overlay and synthesis of multiple watermarks and correctly process the video rotation angle.
- Hardware encoding (VideoEncoder): Use
OH_VideoEncoderto re-encode the composited frames. - Encapsulation (Muxer): Use
OH_AVMuxerto write the encoded video stream and audio stream into an MP4 file.
- Demuxer: Use
- Export progress display: Calculate and display the export progress in percentage in real time based on the number of decoded frames.
- Live view: During the export, the progress percentage is displayed in real time in the status bar or Dynamic Island. Multiple end states are supported, including successful, failed, and canceled.
- Continuous export in the background: Use the specialScenarioProcessing mode of Background Tasks Kit to continue the export after the app is switched to the background.
- Draft persistence: Export tasks are persisted to the sandbox directory as JSON drafts. If the export is interrupted unexpectedly, the editing state can be restored.
- Notification fallback: If the live view is unavailable, use Notification Kit to send a system notification to inform the user of the export result.
- Export to album: Use the SaveButton security control to obtain the write permission and directly save the exported video to the system album.
Required Permissions
ohos.permission.KEEP_BACKGROUND_RUNNING: permission to keep running in the background, ensuring that the export task is not interrupted in the background.ohos.permission.KEEP_BACKGROUND_RUNNING_SPECIAL_SCENARIO: permission to run in the background in special scenarios (in the specialScenarioProcessing mode).
Constraints
- This sample is only supported on bar phones, bi-fold devices (Mate X series), tri-fold devices, and tablets running standard systems.
- The HarmonyOS version must be HarmonyOS 26.0.0 Beta1 or later.
- The DevEco Studio version must be DevEco Studio 26.0.0 Beta1 or later.
- The HarmonyOS SDK version must be HarmonyOS 26.0.0 Beta1 or later.
Introduction
视频导出是一款视频水印导出应用,支持从相册选取视频,在视频上添加图片水印或文字水印(可拖拽、缩放),并通过 AVCodec NDK + OpenGL ES 在端侧完成视频解码、水印合成、重新编码的全流程。导出过程中利用 实况窗(Live View Kit) 实时展示进度,结合 后台任务(Background Tasks Kit) 实现后台持续导出,导出完成后通过通知或实况窗反馈结果。
Customize your domain


