EZUIKit JavaScript SDK

repository·master·Indexed 43 days ago

https://github.com/ezviz-openbiz/ezuikit-javascript-npm

A lightweight JavaScript library (version 9.0.22) for integrating EZVIZ video services into web applications. It supports low-latency live streaming, cloud and SD card playback, two-way talk, and video recording. The SDK provides integration examples for React, Vue 2/3, Next.js, Electron, and UniApp.

Tokens
41.6K
Snippets
114
Records
162
Agent score
53%

What's inside EZUIKit

  1. Important EZUIKitNative limitations and notes

    master

    Keep the following constraints in mind when using EZUIKitNative:

    • Browser Support: Currently supports Chrome only.
    • Max Streams (Plugin Mode): Up to 25 streams (5×5 layout).
    • Max Streams (Non-Plugin Mode): Up to 9 streams.
    • Connection Limits: Only one active CEF connection is allowed per computer across multiple tabs/browsers.
    • Heartbeat/Timeout: Heartbeat interval is 15s; connections automatically disconnect after 30s of inactivity.
    • Performance: Large cellTemplate HTML content (>10KB per cell) will increase initialization time.
    • Laboratory Feature: EZUIKitNative is currently a laboratory feature; perform thorough testing for your specific business scenarios.
  2. What is EZUIKitNative

    master

    EZUIKitNative is a multi-screen video player solution designed for high-concurrency video streaming. It uses a local CEF (Chromium Embedded Framework) desktop plugin to communicate via WebSocket, allowing a separate local window to overlay on the browser page. This architecture enables playing up to 25 video streams simultaneously, bypassing standard browser resource limitations.

    Key Features

    • Dual Modes: Supports both plugin-based (up to 25 screens) and plugin-less modes.
    • Adaptive Layout: The plugin window automatically adapts to the browser's position, size, and visibility.
    • Custom Rendering: Allows injecting custom HTML templates and CSS to overlay UI elements (menus, controls, etc.) on top of video cells.
    • DPI Scaling: Built-in support for system scaling (100% to 175%) to prevent layout misalignment.
  3. Overview of EZUIKitNative Local Plugin Player

    master

    EZUIKitNative is a local plugin-based player designed for high-density video walls (up to 5×5 = 25 channels). It bypasses browser decoding and memory limits by rendering video in an independent local window overlaid on the web page.

    Key Constraints:

    1. Plugin Requirement: Users must have the local playback plugin installed on their machine. The SDK only handles triggering the plugin.
    2. Rendering Model: Video frames are not part of your page's DOM; they are in a local window on top of your page. To add UI elements (badges, borders, buttons) over the video, you must use the SDK's render.cellTemplate and cell() API. You cannot overlay standard HTML elements from your page onto the video.
    3. Browser Support: Currently supports Chrome only. Only one active plugin connection can be active per machine.
  4. What is EZUIKitNative and how does it work?

    master

    EZUIKitNative is a local plugin player module within the EZUIKit SDK. It uses WebSocket communication to talk to a local CEF (Chromium Embedded Framework) desktop plugin process. This allows the browser to overlay an independent local window to host multiple video streams, supporting up to 25 simultaneous views (a 5×5 grid).

    Architecture

    The system consists of three layers:

    1. Controller (User Page): Runs in your web application. It sends control commands, handles window positioning, and listens for events.
    2. CEF Plugin: A local desktop process that provides the WebSocket server, manages windows, and acts as a message relay.
    3. Player (Embedded Page): Runs inside the CEF-embedded page. It receives commands, manages EZUIKitPlayer instances, and reports events back to the Controller.

    Communication Flow

    User Page (Controller) <-> WebSocket (ws://localhost:18082) <-> CEF Plugin <-> WebSocket (ws://localhost:18082) <-> Embedded Player Page

  5. Use Proxy for automatic command forwarding

    master

    The EZUIKitNative Controller instance is wrapped in a JavaScript Proxy. This means any method call that is not explicitly defined on the Controller class will be automatically intercepted and forwarded to the Player side as an apiOptions message via WebSocket.

    This allows you to call player-specific methods directly on the native instance without manually using sendCommand.

    Example

    // These calls are intercepted by the Proxy and forwarded to the Player
    native.capturePicture(0, { download: true });
    native.openSound(0);
    // 以下调用会被 Proxy 拦截,转发为 apiOptions 消息
    native.capturePicture(0, { download: true });
    native.openSound(0);
  6. Listen to player events using eventEmitter

    master

    All player events are managed through the player.eventEmitter. You can listen to events using player.eventEmitter.on(eventName, callback) and remove listeners using player.eventEmitter.off(eventName, callback). Event names are provided by the EZUIKitPlayer.EVENTS constant.

    // Example of listening to an event
    player.eventEmitter.on(EZUIKitPlayer.EVENTS.someEvent, (data) => {
      console.log("Event received:", data);
    });
  7. Handle Cell Actions and Events

    master

    Actions are defined in the render.cellTemplate.action object using the syntax [actionName]:[eventSuffix].

    Event Suffixes:

    • :click: Responds only to single clicks.
    • :dblclick: Responds only to double clicks.
    • (No suffix): Responds to both (note: a double click will trigger click twice and then dblclick).

    Action Context (ctx): When an action is triggered, the handler receives a context object. Note: This is not a native MouseEvent; it is a serialized object from the plugin process. It does not contain target, clientX, or offsetX.

    Context Object Structure:

    {
      index: number;        // Cell index
      id: string;           // Cell deviceId
      data: Record<string, string>; // data-* attributes from the element (excluding data-action)
      event: {
        type: 'click' | 'dblclick';
        ctrlKey: boolean;
        shiftKey: boolean;
        altKey: boolean;
        metaKey: boolean;
      };
      cell: CellHandle;     // Equivalent to native.cell(index)
      native: EZUIKitNative; // The SDK instance
    }
  8. Choose the correct EZUIKitNative mode

    master

    EZUIKitNative supports three modes via the mode option in the constructor:

    ModeValueDescriptionMax Streams
    Plugin-less0Initializes multiple EZUIKitPlayer instances. Best for complex UI/layout needs.9
    Auto1Automatically decides between plugin and plugin-less modes based on device count.-
    Plugin2Forces communication with the local CEF plugin. Best for high-concurrency/large displays.25

    Example (Plugin-less mode):

    const native = new EZUIKit.EZUIKitNative({
      container: 'players-container',
      mode: 0,
      deviceList: [
        {
          id: 'player0',
          url: 'ezopen://open.ys7.com/SERIAL/1.live',
          accessToken: 'at.xxx',
          // ... other options
        }
      ],
    });
  9. Custom Rendering with cellTemplate

    master

    Starting from v9.0.10, you can use HTML templates and CSS injection to overlay custom DOM elements (like menu buttons, playback controls, or headers) on top of existing EZUIKit video cells without modifying the SDK source code.

    Core Concepts

    • cellTemplate: An HTML template shared by all cells (as an object) or unique to each cell (as a function).
    • [data-ezuikit-video]: The mandatory "video slot" in your template where the SDK embeds the video canvas.
    • {index} and {id}: Placeholders in the template that are automatically HTML-escaped.
    • [data-action="<name>"]: Elements that trigger action handlers when clicked or double-clicked.
    • CellHandle / ElementHandle / NodeListHandle: Chainable APIs used to dynamically modify cell states at runtime.

    Layout Constraints

    • Template Root: The root element of your cellTemplate must be a positioning container that fills the cell. It should have at least: position: relative; width: 100%; height: 100%; box-sizing: border-box;.
    • containerStyle: Only use properties that do not affect the layout size of the #player-container grid (e.g., background, border-radius, box-shadow).
    • Warning: Do not use padding, gap, border, or margin in containerStyle. Doing so can cause the canvas buffer to mismatch the display area, resulting in black screens. For visual separation (borders/spacing), apply styles to the .cell class within your cellTemplate.css instead.
    const native = new EZUIKit.EZUIKitNative({
      container: 'players-container',
      render: {
        containerStyle: 'background: #1e3a8a;', // Only non-layout properties
        cellTemplate: {
          template: `<div class="cell"><div data-ezuikit-video></div></div>`,
          css: `.cell { position: relative; width: 100%; height: 100%; }`,
        },
      },
    });
  10. Customize UI using themeData

    master

    The themeData object allows you to localize and customize the player's UI. You can modify button positions, colors, and the appearance of the header and footer.

    Important: When using themeData to set local data, you must remove the template parameter from your configuration.

    // Example of a themeData configuration object
    {
        "autoFocus": 5,
        "header": {
            "color": "#1890ff",
            "backgroundColor": "#000000"
        },
        "footer": {
            "color": "#FFFFFF",
            "backgroundColor": "#00000021"
        }
    }
  11. Understand the connection lifecycle and events

    master

    The connection lifecycle follows this state machine: idle → connecting → connected → closed (with a retrying state between connecting and closed).

    Connection Flow

    1. Initialization: Connection is attempted immediately upon construction.
    2. Protocol Wake-up: If the connection fails, the SDK attempts to wake the plugin via a custom protocol (may trigger a browser 'Open external app' prompt).
    3. Retries: The SDK retries up to 3 times. The first two failures are handled internally and do not emit errors. Only the 3rd failure emits launchFailed.

    Key Events

    EventTimingParameters
    connectConnection state changes{ code: 0 (success) / -1 (disconnected) / -2 (final failure) }
    launchFailedAfter 3 failed wake-up attempts{ code: -3, attempts: 3 }
    initAfter calling init(){ code: 0 } (code -1 if > 9 channels in non-plugin mode)
    errorWhen an operation is rejected-1 (not inited), -2 (invalid params), -3 (playback not ready), -4 (cell not found)
    websocketPlayback engine is ready{ code: 0 (ready) / -1 (closed) / -2 (error) }

    Critical Timing Note

    websocket code: 0 is the signal that you can start sending commands. connect code: 0 only means the plugin process is connected. Do not attempt to set text, overlays, or initial playback commands until the websocket event confirms readiness.

  12. Configure custom rendering with cellTemplate

    master

    Starting from v9.0.10, you can use cellTemplate to customize the UI of each video cell. Follow these critical requirements to avoid rendering issues:

    1. Video Slot: The template MUST include an element with the attribute [data-ezuikit-video].
    2. Container Sizing: The root element of the template must fill the grid cell and establish a positioning context. Use position: relative; width: 100%; height: 100%; box-sizing: border-box;.
    3. Avoid Layout Interference: Do not use flex: 1, standard document flow, or height: calc(...) to control the video slot size. The SDK uses absolute positioning for the video slot. Use absolute positioning and z-index > 0 for overlays like titles or buttons.
    4. containerStyle Restrictions: Only use properties that do not affect grid layout dimensions (e.g., background, border-radius, box-shadow, filter). Do not use padding, gap, border, or margin in containerStyle, as these can cause the video to be clipped or appear as a black screen.
    5. Action Handlers: To distinguish between single and double clicks, use the :click and :dblclick suffixes in your action keys.
    6. API Behavior: Read APIs (hasClass, getAttr, getText) are asynchronous and return Promises. Write APIs are synchronous (aggregated via microtasks).