@ray-js/ipc-player-integration 0.0.53-beta.1 → 0.0.53-beta.10

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.
@@ -1,4 +1,4 @@
1
- import React, { useContext, useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
2
  import { View, Text, usePageEvent } from '@ray-js/ray';
3
3
  import clsx from 'clsx';
4
4
  import { getVideoBitrateKbps, requestWifiSignal } from '@ray-js/ray-ipc-utils';
@@ -7,8 +7,6 @@ import { PlayState } from '../../interface';
7
7
  import './videoBitKBP.less';
8
8
  import { useStore } from '../../ctx/store';
9
9
  import Strings from '../../i18n';
10
- import { UIEventContext } from '../../ui/context';
11
- import { autoClarityChange } from '../../ui/constant';
12
10
  export const VideoBitKBP = props => {
13
11
  const {
14
12
  devId,
@@ -19,32 +17,12 @@ export const VideoBitKBP = props => {
19
17
  } = props;
20
18
  const [bitKBP, setBitKBP] = useState('');
21
19
  const [signalStrength, setSignalStrength] = useState(null);
22
- // 自动清晰度当前实际档位:null 表示未开启自动模式,不展示
23
- const [autoClarity, setAutoClarity] = useState(null);
24
20
  const store = useStore({
25
21
  playState,
26
- resolution: props.resolution
22
+ resolution: props.resolution,
23
+ autoClarity: props.autoClarity
27
24
  });
28
- const {
29
- event
30
- } = useContext(UIEventContext);
31
25
  const timerRef = useRef();
32
-
33
- // 监听 Resolution 控件广播的自动清晰度状态
34
- useEffect(() => {
35
- const onAutoClarityChange = payload => {
36
- setAutoClarity(payload.enabled ? payload.clarity : null);
37
- };
38
- event.on(autoClarityChange, onAutoClarityChange);
39
- return () => {
40
- event.off(autoClarityChange, onAutoClarityChange);
41
- };
42
- }, [event]);
43
- useEffect(() => {
44
- if (store.resolution !== ClarityType.AUTO) {
45
- setAutoClarity(null);
46
- }
47
- }, [store.resolution]);
48
26
  useEffect(() => {
49
27
  if (store.playState === PlayState.PLAYING && (!hideKbsMenu || !hideSignalMenu)) {
50
28
  init();
@@ -78,12 +56,34 @@ export const VideoBitKBP = props => {
78
56
  }
79
57
  }
80
58
  };
81
- const hasKbps = !hideKbsMenu && bitKBP !== '' && bitKBP !== '0';
82
- const hasSignal = !hideSignalMenu && signalStrength !== null;
83
- if (!hasKbps && !hasSignal || store.playState !== PlayState.PLAYING) {
59
+ const isPlaying = store.playState === PlayState.PLAYING;
60
+ const hasKbps = isPlaying && !hideKbsMenu && bitKBP !== '' && bitKBP !== '0';
61
+ const hasSignal = isPlaying && !hideSignalMenu && signalStrength !== null;
62
+ const activeClarity = store.resolution === ClarityType.AUTO ? store.autoClarity : null;
63
+ const hasClarity = Boolean(activeClarity);
64
+ const bitrateLabel = [activeClarity ? (clarity => {
65
+ switch (clarity) {
66
+ case ClarityType.SS:
67
+ return Strings.getLang('ipc_player_resolution_SS');
68
+ case ClarityType.SD:
69
+ return Strings.getLang('ipc_player_resolution_SD');
70
+ case ClarityType.HD:
71
+ return Strings.getLang('ipc_player_resolution_HD');
72
+ case ClarityType.UD:
73
+ return Strings.getLang('ipc_player_resolution_UD');
74
+ case ClarityType.SSP:
75
+ return Strings.getLang('ipc_player_resolution_SSP');
76
+ case ClarityType.AUTO:
77
+ return Strings.getLang('ipc_player_resolution_AUTO');
78
+ case ClarityType.AUDIO:
79
+ return Strings.getLang('ipc_player_resolution_AUDIO');
80
+ default:
81
+ return clarity;
82
+ }
83
+ })(activeClarity) : '', hasKbps ? `${bitKBP} KB/S` : ''].filter(Boolean).join(' ');
84
+ if (!hasKbps && !hasSignal && !hasClarity) {
84
85
  return null;
85
86
  }
86
- if (hideKbsMenu && hideSignalMenu) return null;
87
87
  return /*#__PURE__*/React.createElement(View, {
88
88
  className: clsx({
89
89
  'ipc-player-plugin-videoBitKBP-container': true,
@@ -97,13 +97,11 @@ export const VideoBitKBP = props => {
97
97
  className: clsx('icon-panel', 'icon-panel-wi-Fi', 'ipc-player-plugin-videoBitKBP-signal-icon')
98
98
  }), /*#__PURE__*/React.createElement(Text, null, signalStrength), /*#__PURE__*/React.createElement(Text, {
99
99
  className: "ipc-player-plugin-videoBitKBP-unit-percent"
100
- }, signalStrength > 0 ? '%' : 'dBm')), hasSignal && hasKbps && /*#__PURE__*/React.createElement(View, {
100
+ }, signalStrength > 0 ? '%' : 'dBm')), hasSignal && (hasKbps || hasClarity) && /*#__PURE__*/React.createElement(View, {
101
101
  className: "ipc-player-plugin-videoBitKBP-divider"
102
- }), hasKbps && /*#__PURE__*/React.createElement(View, {
102
+ }), (hasKbps || hasClarity) && /*#__PURE__*/React.createElement(View, {
103
103
  className: "ipc-player-plugin-videoBitKBP-kbps"
104
- }, autoClarity && /*#__PURE__*/React.createElement(Text, {
105
- className: "ipc-player-plugin-videoBitKBP-clarity"
106
- }, autoClarity === 'HD' ? Strings.getLang('ipc_player_resolution_HD') : Strings.getLang('ipc_player_resolution_SD')), /*#__PURE__*/React.createElement(Text, null, bitKBP), /*#__PURE__*/React.createElement(Text, {
107
- className: "ipc-player-plugin-videoBitKBP-unit-kbs"
108
- }, "KB/S"))));
104
+ }, /*#__PURE__*/React.createElement(Text, {
105
+ className: "ipc-player-plugin-videoBitKBP-kbps-text"
106
+ }, bitrateLabel))));
109
107
  };
@@ -36,11 +36,8 @@
36
36
  display: flex;
37
37
  align-items: center;
38
38
  }
39
- .ipc-player-plugin-videoBitKBP-clarity {
40
- margin-right: calc(4px * var(--ipc-player-size-scale, 1));
41
- }
42
- .ipc-player-plugin-videoBitKBP-unit-kbs {
43
- margin-left: calc(4px * var(--ipc-player-size-scale, 1));
39
+ .ipc-player-plugin-videoBitKBP-kbps-text {
40
+ white-space: nowrap;
44
41
  }
45
42
  .ipc-player-plugin-videoBitKBP-unit-percent {
46
43
  margin-left: calc(2px * var(--ipc-player-size-scale, 1));
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,112 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+ import { renderToStaticMarkup } from 'react-dom/server';
4
+ import { act } from 'react-dom/test-utils';
5
+ import { getVideoBitrateKbps } from '@ray-js/ray-ipc-utils';
6
+ let mockStoreState;
7
+ jest.mock('@ray-js/ray', () => ({
8
+ View: _ref => {
9
+ let {
10
+ children,
11
+ className
12
+ } = _ref;
13
+ return /*#__PURE__*/React.createElement("div", {
14
+ className: className
15
+ }, children);
16
+ },
17
+ Text: _ref2 => {
18
+ let {
19
+ children,
20
+ className
21
+ } = _ref2;
22
+ return /*#__PURE__*/React.createElement("span", {
23
+ className: className
24
+ }, children);
25
+ },
26
+ usePageEvent: () => undefined
27
+ }));
28
+ jest.mock('@ray-js/ray-ipc-utils', () => ({
29
+ getVideoBitrateKbps: jest.fn(),
30
+ requestWifiSignal: jest.fn()
31
+ }));
32
+ jest.mock('@ray-js/ray-ipc-utils/lib/interface', () => ({
33
+ ClarityType: {
34
+ SS: 'SS',
35
+ SD: 'SD',
36
+ HD: 'HD',
37
+ UD: 'UD',
38
+ SSP: 'SSP',
39
+ AUTO: 'AUTO',
40
+ AUDIO: 'AUDIO'
41
+ }
42
+ }));
43
+ jest.mock('../../ctx/store', () => ({
44
+ useStore: () => mockStoreState
45
+ }));
46
+ jest.mock('../../i18n', () => ({
47
+ __esModule: true,
48
+ default: {
49
+ getLang: key => key
50
+ }
51
+ }));
52
+ jest.mock('./videoBitKBP.less', () => ({}));
53
+ const {
54
+ VideoBitKBP
55
+ } = require('./videoBitKBP');
56
+ const renderWidget = function (resolution, autoClarity) {
57
+ let playState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
58
+ let hideKbsMenu = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
59
+ mockStoreState = {
60
+ resolution,
61
+ autoClarity,
62
+ playState
63
+ };
64
+ return renderToStaticMarkup(/*#__PURE__*/React.createElement(VideoBitKBP, {
65
+ devId: 'device',
66
+ playState: {},
67
+ resolution: {},
68
+ autoClarity: {},
69
+ hideKbsMenu,
70
+ hideSignalMenu: true
71
+ }));
72
+ };
73
+ describe('VideoBitKBP auto clarity', () => {
74
+ it('renders clarity, bitrate and unit in one text line', async () => {
75
+ const container = document.createElement('div');
76
+ getVideoBitrateKbps.mockResolvedValue({
77
+ code: 0,
78
+ data: {
79
+ kbps: '128'
80
+ }
81
+ });
82
+ mockStoreState = {
83
+ resolution: 'AUTO',
84
+ autoClarity: 'HD',
85
+ playState: 1
86
+ };
87
+ try {
88
+ await act(async () => {
89
+ ReactDOM.render(/*#__PURE__*/React.createElement(VideoBitKBP, {
90
+ devId: 'device',
91
+ hideKbsMenu: false,
92
+ hideSignalMenu: true
93
+ }), container);
94
+ });
95
+ expect(container.innerHTML).toContain('<span class="ipc-player-plugin-videoBitKBP-kbps-text">ipc_player_resolution_HD 128 KB/S</span>');
96
+ } finally {
97
+ ReactDOM.unmountComponentAtNode(container);
98
+ }
99
+ });
100
+ it('shows actual clarity independently of bitrate, signal and play state', () => {
101
+ const markup = renderWidget('AUTO', 'HD', 2);
102
+ expect(markup).toContain('ipc_player_resolution_HD');
103
+ expect(markup).not.toContain('KB/S');
104
+ expect(markup).toContain('<span class="ipc-player-plugin-videoBitKBP-kbps-text">ipc_player_resolution_HD</span>');
105
+ });
106
+ it('does not show clarity outside auto mode', () => {
107
+ expect(renderWidget('SD', 'HD')).toBe('');
108
+ });
109
+ it('waits for the native clarity report in auto mode', () => {
110
+ expect(renderWidget('AUTO', null)).toBe('');
111
+ });
112
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/ipc-player-integration",
3
- "version": "0.0.53-beta.1",
3
+ "version": "0.0.53-beta.10",
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.3",
40
+ "@ray-js/ray-ipc-player": "2.1.4-beta.0",
41
41
  "@ray-js/ray-ipc-utils": "^1.1.16",
42
42
  "@ray-js/svg": "0.2.0",
43
43
  "clsx": "^1.2.1",