@realsee/vreo 0.2.0-alpha.6 → 0.2.0-alpha.9
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 +47 -0
- package/docs/assets/search.js +1 -1
- package/docs/classes/Player.Controller.html +3 -3
- package/docs/classes/Player.Player-1.html +3 -3
- package/docs/classes/Player.VideoAgentMesh.html +11 -11
- package/docs/classes/Player.VideoAgentScene.html +1 -1
- package/docs/enums/Player.InfoPanelStyleEnum.html +1 -1
- package/docs/enums/Player.InfoPanelTypeEnum.html +1 -1
- package/docs/enums/Player.PanoEffectEnum.html +1 -1
- package/docs/enums/Player.PanoTagEnum.html +1 -1
- package/docs/enums/Player.VreoKeyframeEnum.html +12 -12
- package/docs/enums/fivePlugins.CameraMovementEffect.html +1 -1
- package/docs/enums/fivePlugins.Rotation.html +1 -1
- package/docs/index.html +21 -1
- package/docs/interfaces/Player.CustomVreoKeyframeProps.html +1 -1
- package/docs/interfaces/Player.PlayerConfigs.html +3 -3
- package/docs/interfaces/Player.Vertex.html +1 -1
- package/docs/interfaces/Player.VideoAgentMeshOptions.html +1 -1
- package/docs/interfaces/Player.VreoKeyframe.html +1 -1
- package/docs/interfaces/Player.VreoUnit.html +1 -1
- package/docs/interfaces/Player.VreoVideo.html +1 -1
- package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +1 -1
- package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +2 -2
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +1 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +1 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +1 -1
- package/docs/interfaces/react.VreoActionCallbacks.html +6 -6
- package/docs/interfaces/react.VreoProviderProps.html +1 -1
- package/docs/modules/Player.html +13 -13
- package/docs/modules/custom.html +1 -1
- package/docs/modules/fivePlugins.html +2 -2
- package/docs/modules/react.html +1 -1
- package/lib/PlayController/createHTMLAudioElement.d.ts +1 -0
- package/lib/PlayController/createHTMLAudioElement.js +47 -0
- package/lib/PlayController/index.d.ts +38 -0
- package/lib/PlayController/index.js +300 -0
- package/lib/Player/App.js +4 -3
- package/lib/Player/custom/SpatialScenePanel/index.js +86 -14
- package/lib/Player/index.d.ts +1 -1
- package/lib/Player/index.js +68 -9
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +1 -0
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +5 -1
- package/lib/Player/modules/VideoAgent/VideoAgentScene.d.ts +4 -1
- package/lib/Player/modules/VideoAgent/VideoAgentScene.js +2 -1
- package/lib/Player/modules/VideoAgent/index.d.ts +2 -0
- package/lib/Player/modules/VideoAgent/index.js +1 -1
- package/lib/Player/modules/keyframes/CameraMovement/index.js +41 -5
- package/lib/Player/modules/keyframes/UpdateVRPanorama/index.js +23 -15
- package/lib/Player/typings.d.ts +6 -0
- package/lib/fivePlugins/CameraMovementPlugin/index.js +101 -90
- package/lib/fivePlugins/CameraMovementPlugin/typings.d.ts +3 -2
- package/lib/typings/VreoUnit.d.ts +4 -3
- package/package.json +2 -2
- package/resources/PlayController/createHTMLAudioElement.ts +53 -0
- package/resources/PlayController/index.ts +167 -0
- package/resources/Player/App.tsx +2 -0
- package/resources/Player/custom/SpatialScenePanel/index.tsx +84 -8
- package/resources/Player/index.tsx +34 -2
- package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +4 -3
- package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +2 -2
- package/resources/Player/modules/VideoAgent/index.tsx +3 -2
- package/resources/Player/modules/keyframes/CameraMovement/index.tsx +7 -3
- package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +20 -15
- package/resources/Player/typings.ts +5 -0
- package/resources/fivePlugins/CameraMovementPlugin/index.ts +55 -47
- package/resources/fivePlugins/CameraMovementPlugin/typings.ts +2 -1
- package/resources/typings/VreoUnit.ts +5 -4
- package/stylesheets/custom/SpatialScenePanel.css +14 -8
|
@@ -54,114 +54,125 @@ function progressNumber(from, to, pst) {
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
var CameraMovementPlugin = function CameraMovementPlugin(five) {
|
|
57
|
-
var move =
|
|
58
|
-
var
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
if (!(five.panoIndex === undefined)) {
|
|
73
|
+
_context.next = 3;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
103
|
+
case 6:
|
|
104
|
+
if (!(args.mode === _five.Five.Mode.Floorplan)) {
|
|
105
|
+
_context.next = 8;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
101
108
|
|
|
102
|
-
|
|
109
|
+
return _context.abrupt("return", resolve(true));
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
111
|
-
|
|
117
|
+
_context.next = 11;
|
|
118
|
+
return five.preloadPano(args.panoIndex);
|
|
112
119
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
case 11:
|
|
121
|
+
if (opts.asyncEndCallback) {
|
|
122
|
+
opts.asyncEndCallback();
|
|
123
|
+
}
|
|
117
124
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
130
|
+
return _context.abrupt("return", resolve(true));
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
151
|
-
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
}
|
|
159
|
-
}));
|
|
168
|
+
}, _callee);
|
|
169
|
+
}));
|
|
160
170
|
|
|
161
|
-
|
|
162
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
|
106
|
+
effect?: CameraMovementEffect;
|
|
107
|
+
transEffect?: "fly" | "fade" | "instant";
|
|
107
108
|
mode: Mode;
|
|
108
109
|
panoIndex: number;
|
|
109
110
|
loop?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@realsee/vreo",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.9",
|
|
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
|
+
`)
|
package/resources/Player/App.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import { VideoAgent } from './modules/VideoAgent'
|
|
|
16
16
|
import { BgMusic } from './modules/keyframes/BgMusic'
|
|
17
17
|
|
|
18
18
|
const AppView = observer(({ controller }: { controller: Controller }) => {
|
|
19
|
+
|
|
19
20
|
return (
|
|
20
21
|
<div
|
|
21
22
|
className={classNames('vreo-panel', {
|
|
@@ -34,6 +35,7 @@ const AppView = observer(({ controller }: { controller: Controller }) => {
|
|
|
34
35
|
controller.setPlaying(true)
|
|
35
36
|
}
|
|
36
37
|
}}
|
|
38
|
+
options={controller.configs?.videoAgentMeshOptions || {}}
|
|
37
39
|
/>
|
|
38
40
|
<Prompter />
|
|
39
41
|
{controller.configs?.customPanelChildren}
|