@ray-js/ipc-player-integration 0.0.38 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,37 @@ English | [简体中文](./README-zh_CN.md)
4
4
 
5
5
  [![latest](https://img.shields.io/npm/v/@ray-js/ipc-player-integration/latest.svg)](https://www.npmjs.com/package/@ray-js/ipc-player-integration) [![download](https://img.shields.io/npm/dt/@ray-js/ipc-player-integration.svg)](https://www.npmjs.com/package/@ray-js/ipc-player-integration)
6
6
 
7
- > IPC 播放器功能集成
7
+ > IPC integrated player — an all-in-one IPC (camera) player feature integration component for the Tuya Ray framework.
8
+
9
+ Built on top of [`@ray-js/ray-ipc-player`](https://www.npmjs.com/package/@ray-js/ray-ipc-player), it wraps a complete set of upper-layer player capabilities: resolution switching, screenshot, recording, mute, two-way talk, PTZ control, zoom, battery / temperature & humidity / signal status display, portrait–landscape switching, multi-camera layouts and more — ready to use out of the box, while remaining highly customizable for both widgets and styles.
10
+
11
+ ## Table of Contents
12
+
13
+ - [Features](#features)
14
+ - [Installation](#installation)
15
+ - [Quick Start](#quick-start)
16
+ - [Core Concepts](#core-concepts)
17
+ - [API](#api)
18
+ - [`<IPCPlayerIntegration />`](#ipcplayerintegration-)
19
+ - [`useCtx(options)`](#usectxoptions)
20
+ - [`useStore(atoms)`](#usestoreatoms)
21
+ - [`Features`](#features-1)
22
+ - [`Widgets`](#widgets)
23
+ - [`Hooks`](#hooks)
24
+ - [`Utils` & device helpers](#utils--device-helpers)
25
+ - [Custom Styling](#custom-styling)
26
+ - [Events](#events)
27
+ - [Multi-Camera](#multi-camera)
28
+ - [Develop](#develop)
29
+
30
+ ## Features
31
+
32
+ - 🎥 **Integrated player**: encapsulates preview, connection and play-state management on top of `@ray-js/ray-ipc-player`.
33
+ - 🧩 **Declarative widget orchestration**: initialize default widgets with one call to `Features.initPlayerWidgets`, or add/remove widgets in the four corners and the absolute-positioned area on demand.
34
+ - 🛠 **Rich built-in widgets**: resolution, screenshot, recording, mute, intercom, PTZ, zoom, battery, temperature & humidity, 4G signal, floodlight, siren, trial, and more.
35
+ - 🎨 **Customizable**: tailor brand color, icons and fonts via `brandColor` and `CSSVariable`.
36
+ - 📱 **Portrait / landscape / multi-camera**: supports portrait, fullscreen, landscape, and PiP / tile / grid multi-camera layouts.
37
+ - 🪝 **Hook toolkit**: `useBattery`, `usePtz`, `useTemperature` and others for convenient device-state access.
8
38
 
9
39
  ## Installation
10
40
 
@@ -14,19 +44,318 @@ $ npm install @ray-js/ipc-player-integration
14
44
  $ yarn add @ray-js/ipc-player-integration
15
45
  ```
16
46
 
47
+ > This component requires `ahooks` (a peerDependency); make sure it is installed in the host project.
48
+
49
+ ## Quick Start
50
+
51
+ ```tsx
52
+ import React, { useEffect, useRef } from 'react';
53
+ import { View } from '@ray-js/components';
54
+ import {
55
+ IPCPlayerIntegration,
56
+ useCtx,
57
+ useStore,
58
+ Features,
59
+ EventInstance,
60
+ } from '@ray-js/ipc-player-integration';
61
+
62
+ export default function Home(props) {
63
+ const devId = props.location.query?.deviceId;
64
+ // 1. Create the player context instance
65
+ const instance = useCtx({ devId });
66
+ // 2. Subscribe to the state you want to render reactively
67
+ const { screenType } = useStore({ screenType: instance.screenType });
68
+ const eventRef = useRef<EventInstance>();
69
+
70
+ // 3. Initialize default widgets (resolution / screenshot / record / fullscreen ...)
71
+ useEffect(() => {
72
+ Features.initPlayerWidgets(instance, {
73
+ hideRecordVideoMenu: false,
74
+ hideScreenShotMenu: false,
75
+ hideResolutionMenu: false,
76
+ showToggleVerticalFull: true,
77
+ });
78
+ }, []);
79
+
80
+ return (
81
+ <View>
82
+ <IPCPlayerIntegration
83
+ instance={instance}
84
+ devId={instance.devId}
85
+ eventRef={eventRef}
86
+ deviceOnline
87
+ brandColor="#FF592A"
88
+ landscapeMode="fill"
89
+ playerFit="contain"
90
+ style={{ height: screenType === 'vertical' ? 'calc(100vw * 0.56)' : '100vh' }}
91
+ />
92
+ </View>
93
+ );
94
+ }
95
+ ```
96
+
97
+ ## Core Concepts
98
+
99
+ | Concept | Description |
100
+ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
101
+ | **instance** | Created by `useCtx({ devId })`, it spans the whole player and manages state atoms, the player instance, widget content and the event bus. Pass it to `<IPCPlayerIntegration instance={instance} />`. |
102
+ | **atom** | Based on [jotai](https://jotai.org/). State on the `instance` (e.g. `screenType`, `mute`, `resolution`) are atoms; subscribe via `useStore` to render reactively. |
103
+ | **content areas** | Widgets on the player are distributed across 5 areas: `topLeft`, `topRight`, `bottomLeft`, `bottomRight`, `absolute`. Managed via `addContent` / `deleteContent` / `updateContent`, etc. |
104
+ | **event** | `instance.event` provides `on/off/emit`. Expose it to the page through `eventRef` to listen for clicks, resolution switches and other events. |
105
+
106
+ ## API
107
+
108
+ ### `<IPCPlayerIntegration />`
109
+
110
+ The main player component.
111
+
112
+ | Prop | Type | Default | Description |
113
+ | ------------------------ | -------------------------------- | -------------------- | ----------------------------------------------------------------- |
114
+ | `devId` | `string` | — | Device ID (required) |
115
+ | `instance` | `ReturnType<useCtx>` | — | The context instance from `useCtx`; created internally if omitted |
116
+ | `eventRef` | `React.RefObject<EventInstance>` | — | Event-bus ref for listening on the page side |
117
+ | `playerFit` | `'contain' \| 'cover'` | `'contain'` | Video fit mode |
118
+ | `landscapeMode` | `'fill' \| 'standard'` | `'standard'` | Landscape display mode |
119
+ | `brandColor` | `string` | `'#FF592A'` | Brand color |
120
+ | `CSSVariable` | `Partial<CSSVariable>` | — | Custom CSS variables, see [Custom Styling](#custom-styling) |
121
+ | `deviceOnline` | `boolean` | `true` | Whether the device is online |
122
+ | `privateState` | `boolean` | `false` | Whether privacy mode (mask) is on |
123
+ | `verticalMic` | `boolean` | `true` | Whether to show the mic intercom in portrait |
124
+ | `isShare` | `boolean` | `false` | Whether it is a shared device |
125
+ | `ignoreHideStopPreview` | `boolean` | `false` | Ignore stop-preview when widgets hide |
126
+ | `awakeStatus` | `boolean` | `undefined` | Wake-up status for low-power devices |
127
+ | `autoWakeUp` | `boolean` | `false` | Auto wake up the device |
128
+ | `limitFlow` | `boolean` | `false` | Whether flow is limited |
129
+ | `showFlowLowTip` | `boolean` | `false` | Show the low-flow tip |
130
+ | `previewEnabled` | `boolean` | `undefined` | Controlled preview switch |
131
+ | `refreshElement` | `boolean` | `false` | Trigger a CoverView height refresh |
132
+ | `playerRoute` | `string` | `'pages/home/index'` | Route the player lives on |
133
+ | `style` / `className` | `CSSProperties` / `string` | — | Container style / className |
134
+ | `onPlayStatus` | `(data: PlayStatusData) => void` | — | Play-state change callback |
135
+ | `onPlayerTap` | `(data) => void` | — | Tap-on-video callback |
136
+ | `onPreviewEnabledChange` | `(enabled: boolean) => void` | — | Preview-switch change callback |
137
+
138
+ ### `useCtx(options)`
139
+
140
+ Creates the player context instance.
141
+
142
+ ```ts
143
+ const instance = useCtx({
144
+ devId: string, // Device ID (required)
145
+ saveToAlbum?: 0 | 1, // 0: system album; 1: IPC album
146
+ showPtzControlTip?: boolean, // Show the PTZ control guide
147
+ videoSplitProtocol?: VideoSplitProtocol, // Multi-camera split protocol
148
+ initTopLeftContent?: ComponentConfig[], // Initial widgets per area
149
+ initTopRightContent?: ComponentConfig[],
150
+ initBottomLeftContent?: ComponentConfig[],
151
+ initBottomRightContent?: ComponentConfig[],
152
+ initAbsoluteContent?: ComponentConfig[],
153
+ });
154
+ ```
155
+
156
+ The returned `instance` provides:
157
+
158
+ - **State atoms**: `screenType`, `mute`, `intercom`, `recording`, `resolution`, `resolutionList`, `playState`, `brandColor`, `verticalMic`, `isVerticalFullLayout`, etc. (subscribe via `useStore`).
159
+ - **State setters**: `setMute`, `setIntercom`, `setRecording`, `setResolution`, `setScreenType`, `setBrandColor`, `setPlayState`, `changeStreamStatus`, `getStreamStatus`, etc.
160
+ - **Content management**: `addContent(type, config, position?)`, `deleteContent(type, id)`, `updateContent(type, data)`, `getContent()`, `hasContent`, `hideContent`, `showContent`.
161
+ - **Misc**: `IPCPlayerInstance` (the underlying player instance), `event` (event bus), `toast`, `multiCameraCtx` (multi-camera context).
162
+
163
+ ### `useStore(atoms)`
164
+
165
+ Subscribes to state atoms on the `instance` and returns a reactive value object.
166
+
167
+ ```tsx
168
+ const { screenType, mute, resolution } = useStore({
169
+ screenType: instance.screenType,
170
+ mute: instance.mute,
171
+ resolution: instance.resolution,
172
+ });
173
+ ```
174
+
175
+ ### `Features`
176
+
177
+ Widget-orchestration capabilities, imported via `import { Features } from '@ray-js/ipc-player-integration'`.
178
+
179
+ #### `Features.initPlayerWidgets(instance, options)`
180
+
181
+ Initializes the default widgets based on the device's DP info. Common `options`:
182
+
183
+ | Option | Type | Description |
184
+ | ----------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------ |
185
+ | `hideScreenShotMenu` | `boolean` | Hide the screenshot button |
186
+ | `hideRecordVideoMenu` | `boolean` | Hide the record button |
187
+ | `hideResolutionMenu` | `boolean` | Hide the resolution button |
188
+ | `hideKbsMenu` | `boolean` | Hide the bitrate display |
189
+ | `hideSignalMenu` | `boolean` | Hide the signal-strength button |
190
+ | `hideHorizontalMenu` | `boolean` | Hide the enter-landscape button |
191
+ | `verticalResolutionCustomClick` | `boolean` | Custom click for portrait resolution |
192
+ | `showToggleVerticalFull` | `boolean` | Show the single-cam portrait-fullscreen toggle |
193
+ | `showRealTimeMagnification` | `boolean` | Show the real-time magnification button |
194
+ | `hideSmartImageQualityState` | `boolean` | Hide the smart image-quality state |
195
+ | `directionControlProps` | `object` | Pass-through props for the PTZ direction control |
196
+ | `topLeftContent` / `topRightContent` / `bottomLeftContent` / `bottomRightContent` / `absoluteContent` | `ComponentConfig[]` | Override default widget config |
197
+
198
+ #### `Features.updatePlayerWidgetProps(ctx, area, widgetId, newProps)`
199
+
200
+ Dynamically updates props of a widget in a given area.
201
+
202
+ ```ts
203
+ Features.updatePlayerWidgetProps(instance, 'topRight', 'VideoBitKBP', {
204
+ hideKbsMenu: true,
205
+ });
206
+ ```
207
+
208
+ > `area`: `'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'absolute'`; for `widgetId` see the widget list below.
209
+
210
+ ### `Widgets`
211
+
212
+ Imported via `import { Widgets } from '@ray-js/ipc-player-integration'`; each widget can be used standalone. Common widgets:
213
+
214
+ | Widget | WidgetId | Description |
215
+ | ------------------------------- | --------------------------------------------- | -------------------------- |
216
+ | `Widgets.VoiceIntercom` | `FullSmallIntercom` / `VerticalSmallIntercom` | Two-way talk button |
217
+ | `Widgets.Screenshot` | `Screenshot` | Screenshot |
218
+ | `Widgets.RecordVideo` | `RecordVideo` | Recording |
219
+ | `Widgets.Muted` | `Muted` | Mute |
220
+ | `Widgets.Resolution` | `Resolution` | Resolution switch |
221
+ | `Widgets.FullScreen` | `FullScreen` | Fullscreen / landscape |
222
+ | `Widgets.Ptz` | `Ptz` | PTZ control |
223
+ | `Widgets.VideoBitKBP` | `VideoBitKBP` | Bitrate / signal |
224
+ | `Widgets.BatteryFull` | `BatteryFull` | Battery |
225
+ | `Widgets.TempHumidity` | `TempHumidity` | Temperature & humidity |
226
+ | `Widgets.Floodlight` | `Floodlight` | Floodlight |
227
+ | `Widgets.Siren` | `Siren` | Siren |
228
+ | `Widgets.TryExperience` | `TryExperience` | Trial |
229
+ | `Widgets.PtzControlTip` | — | PTZ control guide dialog |
230
+ | `Widgets.RealTimeMagnification` | — | Real-time magnification |
231
+ | `Widgets.ToggleVerticalFull` | — | Portrait-fullscreen toggle |
232
+ | `Widgets.FlowLowTip` | — | Low-flow tip |
233
+
234
+ Standalone `VoiceIntercom` example:
235
+
236
+ ```tsx
237
+ <Widgets.VoiceIntercom
238
+ ref={intercomRef}
239
+ IPCPlayerContext={instance?.IPCPlayerInstance}
240
+ {...instance}
241
+ mode="circle" // 'verticalSmall' | 'fullSmall' | 'circle'
242
+ disabled={false}
243
+ icon={intercomLightSvg}
244
+ talkingColor="#440F7C"
245
+ />
246
+ ```
247
+
248
+ Insert the PTZ guide dialog into the `absolute` area:
249
+
250
+ ```tsx
251
+ instance.addContent('absolute', {
252
+ id: 'ptzControlTipId',
253
+ content: props => <Widgets.PtzControlTip {...props} />,
254
+ absoluteContentClassName: 'ipc-player-plugin-ptz-control-tip-wrap',
255
+ initProps: { ...props },
256
+ });
257
+ ```
258
+
259
+ ### `Hooks`
260
+
261
+ Convenient device-state access (all exported from the package root):
262
+
263
+ | Hook | Signature | Description |
264
+ | ---------------- | ---------------------------------------------- | ------------------------------ |
265
+ | `useBattery` | `(devId) => { batteryValue, batteryCharging }` | Battery level / charging state |
266
+ | `usePtz` | `(devId) => boolean` | Whether PTZ is supported |
267
+ | `useTemperature` | `(devId) => number` | Temperature |
268
+ | `useHumidity` | `() => number` | Humidity |
269
+ | `useSignal4G` | `(devId) => { dpValue, signalKey }` | 4G signal strength |
270
+ | `useDpState` | — | Read/write DP state |
271
+ | `useDpSupport` | — | DP support check |
272
+ | `useSchemaInfo` | — | Device schema info |
273
+ | `useMemoizedFn` | — | Stable function reference |
274
+
275
+ ### `Utils` & device helpers
276
+
277
+ ```ts
278
+ import { Utils } from '@ray-js/ipc-player-integration';
279
+ // Device helpers are imported from a sub-path
280
+ import {
281
+ getDpValue,
282
+ getDeviceInfo,
283
+ getDpSchemaByCodes,
284
+ getDpSchemaByCodesSync,
285
+ hasDpCode,
286
+ } from '@ray-js/ipc-player-integration/utils/device';
287
+ ```
288
+
289
+ - `getDpSchemaByCodes(devId, codes)`: batch-fetch schema by DP code.
290
+ - `hasDpCode(devId, code)`: check whether the device has a given DP.
291
+ - `Utils.radialGradient(color)` / `Utils.adjustBrightness(hex, factor)`: color helpers.
292
+
293
+ ## Custom Styling
294
+
295
+ ### Brand color
296
+
297
+ Set via the `brandColor` prop or `instance.setBrandColor(color)`.
298
+
299
+ ### CSS variables
300
+
301
+ Override via the `CSSVariable` prop:
302
+
303
+ ```tsx
304
+ <IPCPlayerIntegration
305
+ CSSVariable={{
306
+ '--iconColor': '#fff',
307
+ '--iconActiveColor': '#ec653c',
308
+ '--iconFontSize': '20px',
309
+ '--bg-color': '#000',
310
+ '--fontColor': '#fff',
311
+ '--fontSize': '12px',
312
+ }}
313
+ />
314
+ ```
315
+
316
+ Available variables: `--iconColor`, `--iconActiveColor`, `--iconFontSize`, `--iconPlayerSize`, `--iconBoxSize`, `--bg-color`, `--shot-card-bg-color`, `--fontColor`, `--fontSize`.
317
+
318
+ ## Events
319
+
320
+ Once you have the event bus through `eventRef`, you can listen to internal player events:
321
+
322
+ ```tsx
323
+ const eventRef = useRef<EventInstance>();
324
+
325
+ useEffect(() => {
326
+ const onResolutionClick = () => console.log('resolution button clicked');
327
+ const onWidgetClick = data => console.log('widget clicked', data);
328
+ eventRef.current.on('resolutionBtnControlClick', onResolutionClick);
329
+ eventRef.current.on('widgetClick', onWidgetClick);
330
+ return () => {
331
+ eventRef.current.off('resolutionBtnControlClick', onResolutionClick);
332
+ eventRef.current.off('widgetClick', onWidgetClick);
333
+ };
334
+ }, []);
335
+ ```
336
+
337
+ ## Multi-Camera
338
+
339
+ Supports PiP, tile, grid and thumbnail multi-camera layouts. Related types are exported from the package root:
340
+
341
+ - `MultiCameraScreenMode`: screen mode (`short` / `full` / `landscape`).
342
+ - `MultiCameraLayoutStyle`: layout style (`pip` / `tile` / `grid` / `thumbnail`).
343
+ - `VideoSplitProtocol`: the multi-camera split protocol, passed via `useCtx({ videoSplitProtocol })`.
344
+ - `MultiCameraLenInfo`: lens info (index, name, whether PTZ / Zoom / Localizer is supported).
345
+
346
+ The multi-camera context is accessible via `instance.multiCameraCtx`.
347
+
17
348
  ## Develop
18
349
 
19
350
  ```sh
20
351
  # install deps
21
352
  yarn
22
353
 
23
- # watch compile demo
354
+ # watch & preview the demo (Tuya target)
24
355
  yarn start:tuya
25
- ```
26
-
27
- ## Usage
28
356
 
29
- ```tsx
30
- import Foo from '@ray-js/ipc-player-integration';
31
- export default () => <Foo />;
357
+ # build the component
358
+ yarn build
32
359
  ```
360
+
361
+ Other available scripts: `start:wechat`, `start:web`, `start:native`, `build:tuya`, `build:wechat`, `build:web`, `build:native`.
package/lib/ctx/ctx.js CHANGED
@@ -11,7 +11,7 @@ import { PlayState, IntercomMode } from '../interface';
11
11
  import { changeIgnoreHideStopPreview } from '../ui/constant';
12
12
  import { ClarityType } from '@ray-js/ray-ipc-utils/lib/interface';
13
13
  import { getEventInstance } from './event';
14
- import { useMultiCameraCtx } from './multiCameraCtx';
14
+ import { isMultiCameraTileSupported, useMultiCameraCtx } from './multiCameraCtx';
15
15
  const SAVE_TO_ALBUM = 1;
16
16
  export const createUseCtx = _ref => {
17
17
  let {
@@ -42,9 +42,16 @@ export const createUseCtx = _ref => {
42
42
  const streamStatus = useRef();
43
43
  // 全屏、竖屏
44
44
  const [screenType, setScreenType] = useAtom('vertical');
45
+ const IPCPlayerInstance = useRef();
46
+ if (!IPCPlayerInstance.current) {
47
+ IPCPlayerInstance.current = createPlayContext(devId);
48
+ }
45
49
 
46
- // 是否处于竖屏填充布局
47
- const [isVerticalFullLayout, setIsVerticalFullLayout] = useAtom(false);
50
+ // 是否处于竖屏填充布局。
51
+ // 多目平铺设备首帧即按竖屏填充渲染:screenMode 初始就是 full(multiCameraCtx),
52
+ // 若此处初始为 false,首帧会以 16:9 短屏渲染、effect 后才切全高,
53
+ // 原生层在该尺寸跳变窗口内可能丢失 viewPos 更新,残留短屏尺寸。
54
+ const [isVerticalFullLayout, setIsVerticalFullLayout] = useAtom(isMultiCameraTileSupported(videoSplitProtocol, IPCPlayerInstance.current));
48
55
 
49
56
  // 录像中
50
57
  const [recording] = useAtom(false);
@@ -184,10 +191,6 @@ export const createUseCtx = _ref => {
184
191
 
185
192
  // 判断是否已经有了对应id的content
186
193
 
187
- const IPCPlayerInstance = useRef();
188
- if (!IPCPlayerInstance.current) {
189
- IPCPlayerInstance.current = createPlayContext(devId);
190
- }
191
194
  const _setMute = async function (target) {
192
195
  let onlyUpdateAtom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
193
196
  if (onlyUpdateAtom) {
@@ -16,6 +16,10 @@ interface Props {
16
16
  IPCPlayerInstance: IpcContext;
17
17
  videoSplitProtocol?: VideoSplitProtocol;
18
18
  }
19
+ /**
20
+ * 是否支持多目平铺布局(协议 + 基础库能力),首次渲染即可同步判定
21
+ */
22
+ export declare const isMultiCameraTileSupported: (videoSplitProtocol?: VideoSplitProtocol, IPCPlayerInstance?: IpcContext) => boolean;
19
23
  /**
20
24
  * 多目摄像头相关状态、方法维护
21
25
  */
@@ -25,6 +25,13 @@ const DEFAULT_SELECTED_LEN_INFO = {
25
25
  supportLocalizer: false,
26
26
  supportZoom: false
27
27
  };
28
+ /**
29
+ * 是否支持多目平铺布局(协议 + 基础库能力),首次渲染即可同步判定
30
+ */
31
+ export const isMultiCameraTileSupported = (videoSplitProtocol, IPCPlayerInstance) => {
32
+ return (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.total_split_num) > 1 && (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.p_v) >= 3 && typeof (IPCPlayerInstance === null || IPCPlayerInstance === void 0 ? void 0 : IPCPlayerInstance.switchLayoutStyle) === 'function';
33
+ };
34
+
28
35
  /**
29
36
  * 多目摄像头相关状态、方法维护
30
37
  */
@@ -35,7 +42,7 @@ export const useMultiCameraCtx = props => {
35
42
  videoSplitProtocol = DEFAULT_VIDEO_SPLIT_PROTOCOL
36
43
  } = props;
37
44
  const isSupport = useMemo(() => {
38
- return (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.total_split_num) > 1 && (videoSplitProtocol === null || videoSplitProtocol === void 0 ? void 0 : videoSplitProtocol.p_v) >= 3 && typeof (IPCPlayerInstance === null || IPCPlayerInstance === void 0 ? void 0 : IPCPlayerInstance.switchLayoutStyle) === 'function';
45
+ return isMultiCameraTileSupported(videoSplitProtocol, IPCPlayerInstance);
39
46
  }, [IPCPlayerInstance, videoSplitProtocol]);
40
47
  const dpSupportMap = useDpSupport({
41
48
  devId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.38",
3
+ "version": "0.0.39",
4
4
  "description": "IPC 融合播放器",
5
5
  "main": "lib/index",
6
6
  "files": [
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "@ray-js/direction-control": "^0.0.8",
39
39
  "@ray-js/ipc-ptz-zoom": "^0.0.3",
40
- "@ray-js/ray-ipc-player": "^2.1.2",
40
+ "@ray-js/ray-ipc-player": "^2.1.3",
41
41
  "@ray-js/ray-ipc-utils": "^1.1.15",
42
42
  "@ray-js/svg": "0.2.0",
43
43
  "clsx": "^1.2.1",