Help

Watermark Editor — User Guide

Visually create video watermarks and logo overlays. Supports image and text watermarks, dynamic anti-screen-recording, tile mode, template variables, and ZWMAP JSON export.

Overview

The Watermark Editor is a browser-based WYSIWYG tool for creating video watermark configurations. It outputs JSON conforming to the ZWMAP/1.0 specification, which can be rendered by ZWPlayer during video playback.

Key Features:

Quick Start

  1. Load a video: Paste a video URL in the address bar, or drag and drop a local video file onto the canvas area.
  2. Add a watermark: Click "+ Image Watermark" or "+ Text Watermark", or drag an image file directly onto the canvas.
  3. Visual editing: Drag the watermark on the canvas to adjust position. Drag corner handles to resize images. The properties panel updates in real time.
  4. Configure properties: Adjust opacity, behavior mode, dock direction, font settings, etc. in the detail panel.
  5. Export: Click "Export JSON" to download the configuration file, or "Copy" to copy the JSON to clipboard.

Layer Types

Image Watermark

Used for brand logos, channel icons, and other static branding elements.

Text Watermark

Used for copyright notices, user tracking, dynamic information display, and anti-screen-recording protection.

Behavior Modes

Static

The watermark stays fixed at the specified position. Suitable for brand logos and fixed copyright notices.

Dynamic

The watermark moves across the screen. A key technique for anti-screen-recording protection.

Tile (Text Only)

Text fills the entire screen in a tilted grid pattern, forming a dense anti-screen-recording watermark matrix. Only available for text watermarks.

Template Variables

Text watermarks support {key} template variables that are resolved dynamically at playback time.

Built-in Variables

VariableDescriptionUpdate Frequency
{sys_time}Client local time (YYYY-MM-DD HH:mm:ss)Every second

Custom Variables

Any {key} can be used. Values are passed via the variables parameter at playback time.

const player = new ZWPlayer({
  url: 'video.mp4',
  watermarks: config.watermarks,
  variables: {
    user_id: '138****1234',
    user_name: 'John',
    department: 'Engineering',
    ip_address: '192.168.1.100'
  }
});

Unresolved variables are displayed as-is in the player.

Example

"Confidential | {department} | {user_name} | {sys_time}"
→ "Confidential | Engineering | John | 2026-05-08 14:30:00"

Export Formats

Copy JSON

Copies the ZWMAP JSON to the clipboard. Images are embedded as Base64 data URIs or original URLs.

Export JSON

Downloads a {title}_watermark.json file.

Import JSON

Imports a ZWMAP JSON configuration from a local file, restoring all watermark layers and their properties.

Shortcuts

ShortcutAction
PToggle preview mode
SpacePlay/pause video
EscExit preview / Deselect
DeleteDelete selected layer
Ctrl+ZUndo
Ctrl+Shift+ZRedo
Ctrl+SExport JSON
Ctrl+VPaste image from clipboard

ZWMAP Protocol

The watermark editor outputs JSON conforming to the ZWMAP/1.0 specification:

{
  "zwp_protocol": "ZWMAP/1.0",
  "zwp_type": "watermark",
  "zwp_version": "1.0",
  "watermarks": [
    {
      "id": "wm-1",
      "type": "image",
      "behavior": "static",
      "icon": "logo.png",
      "dock": "right",
      "x": "5%", "y": "5%",
      "width": "15%", "height": "15%",
      "opacity": 70
    },
    {
      "id": "wm-2",
      "type": "text",
      "behavior": "dynamic",
      "text": "{user_id} | {sys_time}",
      "font_size": 16,
      "font_color": "rgba(255,255,255,0.3)",
      "opacity": 40,
      "movement": {
        "direction": "diagonal",
        "speed": 2,
        "interval": 0,
        "duration": 0
      }
    },
    {
      "id": "wm-3",
      "type": "text",
      "behavior": "tile",
      "text": "Confidential",
      "font_size": 16,
      "font_color": "rgba(255,255,255,0.15)",
      "opacity": 30,
      "tile": {
        "angle": -30,
        "rowSpacing": 120,
        "colSpacing": 300
      }
    }
  ]
}

Watermark Format Reference

Input Formats

ZWPlayer supports three ways to pass watermark data:

  1. URL string — A URL pointing to a ZWMAP JSON file; the player fetches and parses it automatically. — A URL pointing to a ZWMAP JSON file; the player fetches and parses it automatically. — A URL pointing to a ZWMAP JSON file. The player fetches and parses it automatically.
  2. ZWMAP object — A JSON object with the full protocol header; the player extracts the inner watermarks array. — A JSON object with the full protocol header; the player extracts the inner watermarks array. — A complete JSON object with protocol headers. The player unwraps the inner watermarks array.
  3. Watermark array — A plain array of watermark objects, no protocol header required. — A plain array of watermark objects, no protocol header required. — A plain array of watermark objects, passed directly without protocol headers.
// URL string
watermarks: 'https://example.com/watermark.json'

// ZWMAP object
watermarks: { zwp_protocol: 'ZWMAP/1.0', zwp_type: 'watermark', watermarks: [...] }

// Plain array
watermarks: [{ type: 'image', behavior: 'static', icon: 'logo.png', ... }]

Common Fields

FieldTypeDefaultDescription
typestringRequired. "image" or "text" "image" or "text" "image" or "text"
behaviorstring"static""static", "dynamic", or "tile"
dockstring"right"X-axis origin: "left" or "right"
xstring"5%"Horizontal position (px or %)
ystring"5%"Vertical position (px or %)
opacitynumber70Opacity 0–100
hiddenbooleanfalseHide this watermark

Image Watermark Fields

FieldTypeDescription
iconstringRequired. Image URL or Base64 data URI Image URL or Base64 data URI Image URL or Base64 data URI
widthstringWidth (px or %), default "5%"
heightstringHeight (px, %, or "auto")

Text Watermark Fields

FieldTypeDescription
textstringRequired. Text content, supports {key} template variables Text content, supports {key} template variables Text content, supports {key} template variables
font_sizenumberFont size (px), default 14
font_colorstringFont color (RGBA), default "rgba(255,255,255,0.4)"

Dynamic Movement Fields

When behavior is "dynamic", add a movement object:

FieldTypeDefaultDescription
movement.directionstring"diagonal""horizontal", "vertical", "diagonal", or "random"
movement.speednumber2Movement speed (1–10)
movement.intervalnumber0Hide wait time (seconds), 0 = always visible
movement.durationnumber0Visible duration per cycle (seconds), 0 = always visible

Tile Watermark Fields

When behavior is "tile" (text only), add a tile object:

FieldTypeDefaultDescription
tile.anglenumber-30Tilt angle (degrees), -90 to 90
tile.rowSpacingnumber120Row spacing (px)
tile.colSpacingnumber300Column spacing (px)

ZWPlayer Integration

Use the exported watermark configuration with ZWPlayer:

// 1. Load JSON configuration
const config = await fetch('watermark.json').then(r => r.json());

// 2. Initialize ZWPlayer with watermark configuration
const player = new ZWPlayer({
  playerElm: 'video-container',
  url: 'https://example.com/video.mp4',
  watermarks: config.watermarks,
  variables: {
    user_id: '138****1234',
    user_name: 'John',
    department: 'Engineering'
  }
});

Integration notes: