@realsee/vreo 0.2.0-alpha.5 → 0.2.0-alpha.8

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.
Files changed (69) hide show
  1. package/README.md +47 -3
  2. package/docs/assets/custom.css +2 -2
  3. package/docs/assets/search.js +1 -1
  4. package/docs/classes/Player.Controller.html +3 -3
  5. package/docs/classes/Player.Player-1.html +3 -3
  6. package/docs/classes/Player.VideoAgentMesh.html +11 -11
  7. package/docs/classes/Player.VideoAgentScene.html +1 -1
  8. package/docs/enums/Player.InfoPanelStyleEnum.html +1 -0
  9. package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
  10. package/docs/enums/Player.PanoEffectEnum.html +1 -1
  11. package/docs/enums/Player.PanoTagEnum.html +1 -1
  12. package/docs/enums/Player.VreoKeyframeEnum.html +12 -12
  13. package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
  14. package/docs/enums/fivePlugins.Rotation.html +1 -1
  15. package/docs/index.html +26 -2
  16. package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
  17. package/docs/interfaces/Player.PlayerConfigs.html +3 -3
  18. package/docs/interfaces/Player.Vertex.html +1 -1
  19. package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -1
  20. package/docs/interfaces/Player.VreoKeyframe.html +1 -1
  21. package/docs/interfaces/Player.VreoUnit.html +1 -1
  22. package/docs/interfaces/Player.VreoVideo.html +1 -1
  23. package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
  24. package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
  25. package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
  26. package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
  27. package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
  28. package/docs/interfaces/react.VreoActionCallbacks.html +6 -6
  29. package/docs/interfaces/react.VreoProviderProps.html +1 -1
  30. package/docs/modules/Player.html +13 -13
  31. package/docs/modules/custom.html +1 -1
  32. package/docs/modules/fivePlugins.html +2 -2
  33. package/docs/modules/react.html +1 -1
  34. package/lib/PlayController/createHTMLAudioElement.d.ts +1 -0
  35. package/lib/PlayController/createHTMLAudioElement.js +47 -0
  36. package/lib/PlayController/index.d.ts +38 -0
  37. package/lib/PlayController/index.js +300 -0
  38. package/lib/Player/Controller.d.ts +2 -0
  39. package/lib/Player/Controller.js +14 -0
  40. package/lib/Player/custom/SpatialScenePanel/index.d.ts +2 -2
  41. package/lib/Player/custom/SpatialScenePanel/index.js +96 -15
  42. package/lib/Player/index.d.ts +1 -1
  43. package/lib/Player/index.js +71 -10
  44. package/lib/Player/modules/PopUp/index.d.ts +2 -0
  45. package/lib/Player/modules/PopUp/index.js +43 -0
  46. package/lib/Player/modules/keyframes/CameraMovement/index.js +41 -5
  47. package/lib/Player/modules/keyframes/InfoPanel/index.js +73 -35
  48. package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +23 -15
  49. package/lib/Player/typings.d.ts +4 -0
  50. package/lib/fivePlugins/CameraMovementPlugin/index.js +101 -90
  51. package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +3 -2
  52. package/lib/typings/VreoUnit.d.ts +9 -3
  53. package/lib/typings/VreoUnit.js +14 -6
  54. package/package.json +2 -2
  55. package/resources/PlayController/createHTMLAudioElement.ts +53 -0
  56. package/resources/PlayController/index.ts +167 -0
  57. package/resources/Player/Controller.ts +12 -0
  58. package/resources/Player/custom/SpatialScenePanel/index.tsx +143 -34
  59. package/resources/Player/index.tsx +36 -2
  60. package/resources/Player/modules/PopUp/index.tsx +26 -0
  61. package/resources/Player/modules/keyframes/CameraMovement/index.tsx +7 -3
  62. package/resources/Player/modules/keyframes/InfoPanel/index.tsx +79 -34
  63. package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +20 -15
  64. package/resources/Player/typings.ts +2 -0
  65. package/resources/fivePlugins/CameraMovementPlugin/index.ts +55 -47
  66. package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
  67. package/resources/typings/VreoUnit.ts +11 -4
  68. package/stylesheets/custom/SpatialScenePanel.css +14 -8
  69. package/stylesheets/default.css +66 -0
@@ -18,6 +18,10 @@ export interface PlayerConfigs {
18
18
  */
19
19
  customPanelChildren?: ReactNode;
20
20
  customKeyframes?: React.FC<CustomVreoKeyframeProps>[];
21
+ imageOptions?: {
22
+ size: number;
23
+ };
24
+ autoPreload?: boolean;
21
25
  }
22
26
  export declare type VreoSubscribe = Pick<Subscribe<VreoKeyframeEvent>, 'on' | 'once' | 'off'>;
23
27
  export interface CustomVreoKeyframeProps {
@@ -54,114 +54,125 @@ function progressNumber(from, to, pst) {
54
54
 
55
55
 
56
56
  var CameraMovementPlugin = function CameraMovementPlugin(five) {
57
- var move = /*#__PURE__*/function () {
58
- var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(args, duration) {
59
- var opts,
60
- _args = arguments;
61
- return regeneratorRuntime.wrap(function _callee$(_context) {
62
- while (1) {
63
- switch (_context.prev = _context.next) {
64
- case 0:
65
- opts = _args.length > 2 && _args[2] !== undefined ? _args[2] : {
66
- preload: true
67
- };
57
+ var move = function move(args, duration) {
58
+ var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
59
+ preload: true
60
+ };
61
+ return new Promise( /*#__PURE__*/function () {
62
+ var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(resolve, reject) {
63
+ var panoIndex, movePanoOptions;
64
+ return regeneratorRuntime.wrap(function _callee$(_context) {
65
+ while (1) {
66
+ switch (_context.prev = _context.next) {
67
+ case 0:
68
+ if (opts.asyncStartCallback) {
69
+ opts.asyncStartCallback();
70
+ }
68
71
 
69
- if (opts.asyncStartCallback) {
70
- opts.asyncStartCallback();
71
- }
72
+ if (!(five.panoIndex === undefined)) {
73
+ _context.next = 3;
74
+ break;
75
+ }
72
76
 
73
- if (!(args.mode && args.mode !== five.currentMode)) {
74
- _context.next = 5;
75
- break;
76
- }
77
+ return _context.abrupt("return", reject(false));
78
+
79
+ case 3:
80
+ if (!(args.mode && args.mode !== five.currentMode)) {
81
+ _context.next = 6;
82
+ break;
83
+ }
77
84
 
78
- _context.next = 5;
79
- return new Promise(function (resolve) {
80
- if (!args.mode) return;
81
- five.once('modeChange', function (mode) {
82
- five.once('initAnimationEnded', function () {
83
- if (mode === args.mode) {
84
- resolve(true);
85
- }
85
+ _context.next = 6;
86
+ return new Promise(function (resolve) {
87
+ if (!args.mode) return;
88
+ five.once('modeChange', function (mode) {
89
+ five.once('initAnimationEnded', function () {
90
+ if (mode === args.mode) {
91
+ resolve(true);
92
+ }
93
+ });
94
+ });
95
+ five.changeMode(args.mode, {
96
+ fov: args.fov || undefined,
97
+ latitude: args.latitude || undefined,
98
+ longitude: args.longitude || undefined,
99
+ panoIndex: args.panoIndex || undefined
86
100
  });
87
101
  });
88
- five.changeMode(args.mode, {
89
- fov: args.fov || undefined,
90
- latitude: args.latitude || undefined,
91
- longitude: args.longitude || undefined,
92
- panoIndex: args.panoIndex || undefined
93
- });
94
- });
95
102
 
96
- case 5:
97
- if (!(args.mode === _five.Five.Mode.Floorplan)) {
98
- _context.next = 7;
99
- break;
100
- }
103
+ case 6:
104
+ if (!(args.mode === _five.Five.Mode.Floorplan)) {
105
+ _context.next = 8;
106
+ break;
107
+ }
101
108
 
102
- return _context.abrupt("return", true);
109
+ return _context.abrupt("return", resolve(true));
103
110
 
104
- case 7:
105
- if (!(opts.preload && args.panoIndex !== undefined && args.panoIndex !== five.panoIndex)) {
106
- _context.next = 10;
107
- break;
108
- }
111
+ case 8:
112
+ if (!(opts.preload && args.panoIndex !== undefined && args.panoIndex !== five.panoIndex)) {
113
+ _context.next = 11;
114
+ break;
115
+ }
109
116
 
110
- _context.next = 10;
111
- return five.preloadPano(args.panoIndex);
117
+ _context.next = 11;
118
+ return five.preloadPano(args.panoIndex);
112
119
 
113
- case 10:
114
- if (opts.asyncEndCallback) {
115
- opts.asyncEndCallback();
116
- }
120
+ case 11:
121
+ if (opts.asyncEndCallback) {
122
+ opts.asyncEndCallback();
123
+ }
117
124
 
118
- if (!(args.panoIndex === undefined && args.fov === undefined && args.latitude === undefined && args.longitude === undefined)) {
119
- _context.next = 13;
120
- break;
121
- }
125
+ if (!(args.panoIndex === undefined && args.fov === undefined && args.latitude === undefined && args.longitude === undefined)) {
126
+ _context.next = 14;
127
+ break;
128
+ }
122
129
 
123
- return _context.abrupt("return", true);
130
+ return _context.abrupt("return", resolve(true));
124
131
 
125
- case 13:
126
- _context.next = 15;
127
- return new Promise(function (resolve, reject) {
128
- var panoIndex = args.panoIndex !== undefined ? args.panoIndex : five.panoIndex;
129
-
130
- if (panoIndex !== undefined) {
131
- var movePanoOptions = {
132
- duration: duration,
133
- // 移动耗时
134
- moveEndCallback: function moveEndCallback() {
135
- return resolve(true);
136
- },
137
- // 移动结束
138
- moveCancelCallback: function moveCancelCallback() {
139
- return reject(false);
140
- },
141
- // 移动开始
142
- effect: 'fade'
143
- };
144
- five.moveToPano(panoIndex, Object.assign(movePanoOptions, args));
145
- } else {
146
- reject(false);
132
+ case 14:
133
+ panoIndex = args.panoIndex !== undefined ? args.panoIndex : five.panoIndex;
134
+
135
+ if (!(panoIndex !== undefined)) {
136
+ _context.next = 21;
137
+ break;
147
138
  }
148
- });
149
139
 
150
- case 15:
151
- return _context.abrupt("return", _context.sent);
140
+ movePanoOptions = Object.assign(args, {
141
+ duration: duration,
142
+ // 移动耗时
143
+ moveEndCallback: function moveEndCallback() {
144
+ return resolve(true);
145
+ },
146
+ // 移动结束
147
+ moveCancelCallback: function moveCancelCallback() {
148
+ resolve(true);
149
+ } // 移动开始
150
+ // effect: args.transEffect || 'fade',
152
151
 
153
- case 16:
154
- case "end":
155
- return _context.stop();
152
+ });
153
+ _context.next = 19;
154
+ return five.moveToPano(panoIndex, movePanoOptions);
155
+
156
+ case 19:
157
+ _context.next = 22;
158
+ break;
159
+
160
+ case 21:
161
+ reject(false);
162
+
163
+ case 22:
164
+ case "end":
165
+ return _context.stop();
166
+ }
156
167
  }
157
- }
158
- }, _callee);
159
- }));
168
+ }, _callee);
169
+ }));
160
170
 
161
- return function move(_x, _x2) {
162
- return _ref.apply(this, arguments);
163
- };
164
- }();
171
+ return function (_x, _x2) {
172
+ return _ref.apply(this, arguments);
173
+ };
174
+ }());
175
+ };
165
176
 
166
177
  var getAnimeParams = function getAnimeParams(args) {
167
178
  var currentFiveState = five.state; // latitude
@@ -1,4 +1,4 @@
1
- import { Mode, MovePanoOptions, Pose } from '@realsee/five';
1
+ import { Mode, Pose } from '@realsee/five';
2
2
  export interface CameraMovementPluginParameterType {
3
3
  }
4
4
  export interface CameraMovementPluginExportType {
@@ -33,7 +33,8 @@ export interface CameraMovementOptsCallback {
33
33
  export declare type MoveArgs = {
34
34
  mode: Mode;
35
35
  panoIndex: number;
36
- } & Pose & Pick<MovePanoOptions, 'effect'>;
36
+ transEffect?: "fly" | "fade" | "instant";
37
+ } & Pose;
37
38
  export declare type MoveOpts = {
38
39
  preload?: boolean;
39
40
  } & CameraMovementOptsCallback;
@@ -61,7 +61,7 @@ export declare type VreoKeyframeConfigMap = {
61
61
  * 剧本关键帧
62
62
  */
63
63
  export interface VreoKeyframe {
64
- uuid: string;
64
+ uuid?: string;
65
65
  type: VreoKeyframeEnum;
66
66
  start: number;
67
67
  end: number;
@@ -95,7 +95,7 @@ export declare type VreoKeyframeEvent = {
95
95
  [key in VreoKeyframeEnum]: (keyframe: VreoKeyframe) => void;
96
96
  } & {
97
97
  loaded: (vreoUnit: VreoUnit) => void;
98
- paused: () => void;
98
+ paused: (ended?: boolean) => void;
99
99
  playing: () => void;
100
100
  unknownKeyframeType: (keyframe: Record<string, any>) => void;
101
101
  };
@@ -103,7 +103,8 @@ export declare type VreoKeyframeEvent = {
103
103
  * 相机运动
104
104
  */
105
105
  export declare type CameraMovementData = {
106
- effect: CameraMovementEffect;
106
+ effect?: CameraMovementEffect;
107
+ transEffect?: "fly" | "fade" | "instant";
107
108
  mode: Mode;
108
109
  panoIndex: number;
109
110
  loop?: boolean;
@@ -210,11 +211,16 @@ export declare enum InfoPanelTypeEnum {
210
211
  Image = "Image",
211
212
  Video = "Video"
212
213
  }
214
+ export declare enum InfoPanelStyleEnum {
215
+ Drawer = "Drawer",
216
+ PopUp = "PopUp"
217
+ }
213
218
  /**
214
219
  * 信息面板
215
220
  */
216
221
  export declare type InfoPanelData = {
217
222
  type: InfoPanelTypeEnum;
223
+ style?: InfoPanelStyleEnum;
218
224
  url: string;
219
225
  title?: string;
220
226
  subTitle?: string;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VreoKeyframeEnum = exports.PanoTagEnum = exports.PanoEffectEnum = exports.InfoPanelTypeEnum = void 0;
6
+ exports.VreoKeyframeEnum = exports.PanoTagEnum = exports.PanoEffectEnum = exports.InfoPanelTypeEnum = exports.InfoPanelStyleEnum = void 0;
7
7
  var VreoKeyframeEnum;
8
8
  /**
9
9
  * 支持自定义剧本关键帧配置项
@@ -55,13 +55,21 @@ exports.PanoEffectEnum = PanoEffectEnum;
55
55
  * 信息面板类型枚举
56
56
  */
57
57
  var InfoPanelTypeEnum;
58
- /**
59
- * 信息面板
60
- */
61
-
62
58
  exports.InfoPanelTypeEnum = InfoPanelTypeEnum;
63
59
 
64
60
  (function (InfoPanelTypeEnum) {
65
61
  InfoPanelTypeEnum["Image"] = "Image";
66
62
  InfoPanelTypeEnum["Video"] = "Video";
67
- })(InfoPanelTypeEnum || (exports.InfoPanelTypeEnum = InfoPanelTypeEnum = {}));
63
+ })(InfoPanelTypeEnum || (exports.InfoPanelTypeEnum = InfoPanelTypeEnum = {}));
64
+
65
+ var InfoPanelStyleEnum;
66
+ /**
67
+ * 信息面板
68
+ */
69
+
70
+ exports.InfoPanelStyleEnum = InfoPanelStyleEnum;
71
+
72
+ (function (InfoPanelStyleEnum) {
73
+ InfoPanelStyleEnum["Drawer"] = "Drawer";
74
+ InfoPanelStyleEnum["PopUp"] = "PopUp";
75
+ })(InfoPanelStyleEnum || (exports.InfoPanelStyleEnum = InfoPanelStyleEnum = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realsee/vreo",
3
- "version": "0.2.0-alpha.5",
3
+ "version": "0.2.0-alpha.8",
4
4
  "description": "Vreo (VR Video 缩写) 是基于如视三维渲染引擎 Five 和 用户界面构建库 React 实现的如视 3D 空间剧本播放器。",
5
5
  "keywords": [
6
6
  "realsee",
@@ -18,7 +18,7 @@
18
18
  "LICENSE"
19
19
  ],
20
20
  "scripts": {
21
- "dev": "vite --port=3088",
21
+ "dev": "vite --port=3088 --host 0.0.0.0",
22
22
  "build": "tsc && vite build",
23
23
  "preview": "vite preview",
24
24
  "docs": "npx typedoc",
@@ -0,0 +1,53 @@
1
+
2
+ const BLANK_AUDIO = ''
3
+ + 'data:audio/mpeg;base64,'
4
+ + '//uQxAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAADAAAGhgBVVVVVVVVVVVVVVVVVVVVVVVV'
5
+ + 'VVVVVVVVVVVVVVVVVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr///////////'
6
+ + '////////////////////////////////8AAAA5TEFNRTMuOThyAc0AAAAAAAAAABSAJAiqQgAAg'
7
+ + 'AAABobxtI73AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
8
+ + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
9
+ + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
10
+ + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
11
+ + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//uQxAACFEII9ACZ/sJZwWEoEb8w/////N//////Jcxj'
12
+ + 'Hjf+7/v/H2PzCCFAiDtGeyBCIx7bJJ1mmEEMy6g8mm2c8nrGABB4h2Mkmn//4z/73u773R5qHHu'
13
+ + '/j/w7Kxkzh5lWRWdsifCkNAnY9Zc1HvDAhjhSHdFkHFzLmabt/AQxSg2wwzLhHIJOBnAWwVY4zr'
14
+ + 'hIYhhc2kvhYDfQ4hDi2Gmh5KyFn8EcGIrHAngNgIwVIEMf5bzbAiTRoAD///8z/KVhkkWEle6IX'
15
+ + '+d/z4fvH3BShK1e5kmjkCMoxVmXhd4ROlTKo3iipasvTilY21q19ta30/v/0/idPX1v8PNxJL6r'
16
+ + 'amnOVsdvMv2akO0iSYIzdJFirtzWXCZicS9vHqvSKyqm5XJBdqBwPxyfJdykhWTZ0G0ZyTZGpLK'
17
+ + 'xsNwwoRhsx3tZfhwmeOBVISm3impAC/IT/8hP/EKEM1KMdVdVKM2rHV4x7HVXZvbVVKN/qq8CiV'
18
+ + '9VL9jjH/6l6qf7MBCjZmOqsAibjcP+qqqv0oxqpa/NVW286hPo1nz2L/h8+jXt//uSxCmDU2IK/'
19
+ + 'ECN98KKtE5IYzNoCfbw+u9i5r8PoadUMFPKqWL4LK3T/LCraMSHGkW4bpLXR/E6LlHOVQxmslKV'
20
+ + 'J8IULktMN06N0FKCpHCoYsjC4F+Z0NVqdNFoGSTjSiyjzLdnZ2fNqTi2eHKONONKLMPMKLONKLM'
21
+ + 'PQRJGlFxZRoKcJFAYEeIFiRQkUWUeYfef//Ko04soswso40UJAgMw8wosososy0EalnZyjQUGBR'
22
+ + 'QGIFggOWUacWUeYmuadrZziQKKEgQsQLAhQkUJAgMQDghltLO1onp0cpkNInSFMqlYeSEJ5AHsq'
23
+ + 'FdOwy1DA2sRmRJKxdKRfLhfLw5BzUxBTUUzLjk4LjJVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
24
+ + 'VVVVVVVVVVVVVVVVVUxBTUUzLjk4LjJVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
25
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
26
+ + 'VVVVVVVVVVVVVVVVVVVf/7ksRRA8AAAaQAAAAgAAA0gAAABFVVVVVVVVVVVVVVVVVVVVVVVVVVV'
27
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
28
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
29
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
30
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
31
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
32
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV'
33
+ + 'VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=';
34
+
35
+
36
+ export function createHTMLAudioElement(): HTMLAudioElement {
37
+ const ndAudio = document.querySelector('#vreo-playController-audio')
38
+ if (ndAudio) {
39
+ return ndAudio as HTMLAudioElement
40
+ }
41
+
42
+ const audio = document.createElement('audio')
43
+ audio.style.display = 'none'
44
+ audio.setAttribute('id', 'vreo-playController-audio')
45
+ audio.controls = false
46
+ document.body.appendChild(audio)
47
+ audio.src = BLANK_AUDIO
48
+
49
+ // 触发一次播放
50
+ Promise.resolve(async () => await audio.play())
51
+
52
+ return audio
53
+ }
@@ -0,0 +1,167 @@
1
+ import { Subscribe } from '@realsee/five'
2
+ import { requestAnimationFrameInterval } from '../shared-utils/animationFrame'
3
+ import { VreoKeyframe, VreoKeyframeEvent, VreoUnit } from '../typings/VreoUnit'
4
+ import { createHTMLAudioElement } from './createHTMLAudioElement'
5
+
6
+ export interface PlayControllerConfig {
7
+ audio?: HTMLAudioElement
8
+ }
9
+
10
+ const closures: Record<string, any> = {}
11
+
12
+ export class PlayController extends Subscribe<VreoKeyframeEvent> {
13
+
14
+ vreoUnit?: VreoUnit
15
+
16
+ config: PlayControllerConfig = {}
17
+ stopInterval: () => void
18
+
19
+ get paused() {
20
+ return this.audioInstance.paused
21
+ }
22
+
23
+ get audioInstance() {
24
+ return this.config.audio!
25
+ }
26
+
27
+ get currentTime() {
28
+ return this.audioInstance.currentTime * 1000
29
+ }
30
+
31
+ get currentKeyframes() {
32
+ if (!this.vreoUnit) return []
33
+ const keyframes = this.vreoUnit.keyframes
34
+ // 没有被解析过且开始时间低于当前时间戳 100ms
35
+ return keyframes.filter((keyframe: VreoKeyframe) => {
36
+ if (keyframe.parsed) return false
37
+ const dur = this.currentTime - keyframe.start
38
+ return dur <= 100 && dur >= 0
39
+ })
40
+ }
41
+
42
+ /**
43
+ * 音频时长 不一定能获取得到,建议以 VreoUnit 配置的时长为准。
44
+ */
45
+ get duration() {
46
+ return this.audioInstance.duration * 1000
47
+ }
48
+
49
+ constructor(config: PlayControllerConfig = {}) {
50
+ super()
51
+
52
+ if (!config.audio) {
53
+ config.audio = createHTMLAudioElement()
54
+ }
55
+
56
+ this.config = Object.assign(this.config, config)
57
+
58
+ closures.onPlaying = () => this.emit('playing')
59
+ closures.onPaused = () => this.emit('paused')
60
+ closures.onEnded = () => this.emit('paused', true)
61
+
62
+ this.audioInstance.addEventListener('play', closures.onPlaying)
63
+ this.audioInstance.addEventListener('pause', closures.onPaused)
64
+ this.audioInstance.addEventListener('ended', closures.onEnded)
65
+
66
+ this.stopInterval = requestAnimationFrameInterval(() => {
67
+ if (this.audioInstance.paused) {
68
+ return
69
+ }
70
+
71
+ if (!this.vreoUnit) {
72
+ return
73
+ }
74
+
75
+ const keyframes = this.vreoUnit.keyframes
76
+ const currentTime = this.currentTime
77
+ // 没有被解析过且开始时间低于当前时间戳 100ms
78
+ const currentKeyframes = keyframes.filter((keyframe: VreoKeyframe) => {
79
+ if (keyframe.parsed) return false
80
+
81
+ const dur = currentTime - keyframe.start
82
+ return dur <= 60 && dur >= 0
83
+ })
84
+
85
+ currentKeyframes.forEach((keyframe) => {
86
+ if (keyframe.parsed) return
87
+ keyframe.parsed = true
88
+ this.emit(keyframe.type, keyframe)
89
+ })
90
+ })
91
+
92
+ }
93
+
94
+
95
+
96
+ /**
97
+ * 载入数据
98
+ */
99
+ async load(vreoUnit: VreoUnit): Promise<boolean> {
100
+ this.vreoUnit = vreoUnit
101
+
102
+ await this.pause()
103
+ return await new Promise((resolve, reject) => {
104
+ if (vreoUnit.video.url === this.audioInstance.src) {
105
+ return resolve(true)
106
+ }
107
+
108
+ this.audioInstance.src = vreoUnit.video.url
109
+ const canplaythrough = () => {
110
+ resolve(true)
111
+ this.audioInstance.removeEventListener('canplaythrough', canplaythrough)
112
+ }
113
+ const error = (err: any) => {
114
+ reject(err)
115
+ this.audioInstance.removeEventListener('error', error)
116
+ }
117
+ this.audioInstance.addEventListener('canplaythrough', canplaythrough)
118
+ this.audioInstance.addEventListener('error', error)
119
+ })
120
+ }
121
+
122
+ /**
123
+ * 播放
124
+ */
125
+ async play() {
126
+ closures.playPromise = this.audioInstance.play()
127
+ }
128
+
129
+ /**
130
+ * 暂停
131
+ */
132
+ async pause() {
133
+ if (closures.playPromise) {
134
+ await closures.playPromise
135
+ }
136
+ this.audioInstance.pause()
137
+ }
138
+
139
+ /**
140
+ * 销毁资源
141
+ * @notice 一旦销毁,创建的实例将不可用:需重新创建实例。
142
+ *
143
+ * @deprecated **慎重执行**
144
+ */
145
+ dispose() {
146
+ // 清理事件监听
147
+ this.audioInstance.removeEventListener('play', closures.onPlaying)
148
+ this.audioInstance.removeEventListener('pasue', closures.onPaused)
149
+ this.audioInstance.removeEventListener('ended', closures.onEnded)
150
+ if (this.stopInterval) {
151
+ this.stopInterval()
152
+ }
153
+ }
154
+ }
155
+
156
+ console.log(`
157
+
158
+ ┏━━━┓━━━━━━━━━┏┓━━━━━━━━━━━━━
159
+ ┃┏━┓┃━━━━━━━━━┃┃━━━━━━━━━━━━━
160
+ ┃┗━┛┃┏━━┓┏━━┓━┃┃━┏━━┓┏━━┓┏━━┓
161
+ ┃┏┓┏┛┃┏┓┃┗━┓┃━┃┃━┃━━┫┃┏┓┃┃┏┓┃
162
+ ┃┃┃┗┓┃┃━┫┃┗┛┗┓┃┗┓┣━━┃┃┃━┫┃┃━┫
163
+ ┗┛┗━┛┗━━┛┗━━━┛┗━┛┗━━┛┗━━┛┗━━┛
164
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
165
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
166
+
167
+ `)
@@ -24,6 +24,16 @@ export class Controller extends Subscribe<VreoKeyframeEvent> {
24
24
  return !this.videoAgentScene?.videoAgentMesh.videoUrl?.endsWith('.mp4')
25
25
  }
26
26
 
27
+ popUp: string | JSX.Element | null = null
28
+
29
+ openPopUp(popUp: string | JSX.Element | false) {
30
+ if (!popUp) {
31
+ this.popUp = null
32
+ return
33
+ }
34
+ this.popUp = popUp
35
+ }
36
+
27
37
  drawerConfig: {
28
38
  content: string | JSX.Element
29
39
  height?: number | string
@@ -57,6 +67,8 @@ export class Controller extends Subscribe<VreoKeyframeEvent> {
57
67
  setVisible: action,
58
68
  playing: observable,
59
69
  setPlaying: action,
70
+ popUp: observable.ref,
71
+ openPopUp: action,
60
72
  drawerConfig: observable.ref,
61
73
  openDrawer: action,
62
74
  })