@realsee/vreo 1.0.0-alpha.8 → 1.1.0-dev.0
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/CHANGELOG.md +9 -1
- package/README.md +46 -36
- package/lib/PlayController/index.js +1 -1
- package/lib/Player/Controller.d.ts +3 -2
- package/lib/Player/Controller.js +31 -14
- package/lib/Player/index.js +27 -16
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.d.ts +2 -2
- package/lib/Player/modules/VideoAgent/VideoAgentMesh.js +7 -12
- package/lib/Player/modules/VideoAgent/index.js +1 -1
- package/lib/Player/modules/Wave/index.js +160 -25
- package/lib/Player/modules/keyframes/BgMusic/index.js +52 -40
- package/lib/Player/modules/keyframes/PanoTag/index.js +1 -0
- package/lib/fivePlugins/CameraMovementPlugin/index.js +3 -2
- package/lib/shared-utils/Audio.d.ts +14 -0
- package/lib/shared-utils/Audio.js +158 -0
- package/lib/shared-utils/{AduioLike.d.ts → AudioLike.d.ts} +0 -0
- package/lib/shared-utils/{AduioLike.js → AudioLike.js} +4 -6
- package/lib/shared-utils/animationFrame/tween.d.ts +3 -58
- package/lib/shared-utils/animationFrame/tween.js +3 -9
- package/lib/typings/VreoUnit.d.ts +8 -5
- package/package.json +8 -6
- package/stylesheets/default.css +9 -2
- package/docs/.nojekyll +0 -1
- package/docs/assets/custom.css +0 -78
- package/docs/assets/highlight.css +0 -127
- package/docs/assets/icons.css +0 -1043
- package/docs/assets/icons.png +0 -0
- package/docs/assets/icons@2x.png +0 -0
- package/docs/assets/main.js +0 -52
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1414
- package/docs/assets/widgets.png +0 -0
- package/docs/assets/widgets@2x.png +0 -0
- package/docs/classes/Player.AudioLike.html +0 -52
- package/docs/classes/Player.Controller.html +0 -54
- package/docs/classes/Player.Player-1.html +0 -50
- package/docs/classes/Player.VideoAgentMesh.html +0 -142
- package/docs/classes/Player.VideoAgentScene.html +0 -1
- package/docs/demo/assets/AppReact.6a524c19.js +0 -1
- package/docs/demo/assets/default.361f7c9c.js +0 -3988
- package/docs/demo/assets/default.63ebc790.css +0 -1
- package/docs/demo/assets/dynamic.dc5a9120.js +0 -1
- package/docs/demo/assets/examples.a3b2ec8a.js +0 -25
- package/docs/demo/assets/examples.dac4a6fe.css +0 -1
- package/docs/demo/assets/index.12496cce.js +0 -1
- package/docs/demo/assets/index.9331038f.css +0 -1
- package/docs/demo/assets/main.b05c3bb6.js +0 -1
- package/docs/demo/assets/react.2ee8565f.css +0 -1
- package/docs/demo/assets/react.61c6e2de.js +0 -25
- package/docs/demo/assets/znRoyv06SZQeqA7m.0057e8ae.js +0 -1
- package/docs/demo/examples.html +0 -17
- package/docs/demo/index-react-dynamic.html +0 -20
- package/docs/demo/index-react.html +0 -20
- package/docs/demo/index.html +0 -19
- package/docs/enums/Player.InfoPanelStyleEnum.html +0 -1
- package/docs/enums/Player.InfoPanelTypeEnum.html +0 -3
- package/docs/enums/Player.PanoEffectEnum.html +0 -5
- package/docs/enums/Player.PanoTagEnum.html +0 -3
- package/docs/enums/Player.PanoTagStyleEnum.html +0 -7
- package/docs/enums/Player.VreoKeyframeEnum.html +0 -25
- package/docs/enums/fivePlugins.CameraMovementEffect.html +0 -1
- package/docs/enums/fivePlugins.Rotation.html +0 -1
- package/docs/index.html +0 -245
- package/docs/interfaces/Player.CustomVreoKeyframeProps.html +0 -1
- package/docs/interfaces/Player.PlayerConfigs.html +0 -7
- package/docs/interfaces/Player.Vertex.html +0 -3
- package/docs/interfaces/Player.VideoAgentMeshOptions.html +0 -8
- package/docs/interfaces/Player.VreoKeyframe.html +0 -3
- package/docs/interfaces/Player.VreoUnit.html +0 -3
- package/docs/interfaces/Player.VreoVideo.html +0 -3
- package/docs/interfaces/fivePlugins.CSS3DRenderPluginExportType.html +0 -4
- package/docs/interfaces/fivePlugins.CameraMovementOptsCallback.html +0 -1
- package/docs/interfaces/fivePlugins.CameraMovementPluginExportType.html +0 -7
- package/docs/interfaces/fivePlugins.CameraMovementPluginParameterType.html +0 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginData.html +0 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginExportType.html +0 -1
- package/docs/interfaces/fivePlugins.ModelTVVideoPluginParameterType.html +0 -1
- package/docs/interfaces/fivePlugins.Vector3Position.html +0 -3
- package/docs/interfaces/react.VreoActionCallbacks.html +0 -23
- package/docs/interfaces/react.VreoProviderProps.html +0 -1
- package/docs/modules/Player.html +0 -37
- package/docs/modules/custom.html +0 -3
- package/docs/modules/fivePlugins.html +0 -6
- package/docs/modules/react.html +0 -1
- package/docs/modules.html +0 -1
- package/resources/PlayController/createHTMLAudioElement.ts +0 -53
- package/resources/PlayController/index.ts +0 -154
- package/resources/Player/App.tsx +0 -66
- package/resources/Player/Controller.ts +0 -294
- package/resources/Player/custom/SpatialScenePanel/index.tsx +0 -264
- package/resources/Player/hooks.ts +0 -26
- package/resources/Player/index.tsx +0 -227
- package/resources/Player/modules/Drawer/index.tsx +0 -40
- package/resources/Player/modules/PopUp/index.tsx +0 -26
- package/resources/Player/modules/ResizeObserver/index.tsx +0 -23
- package/resources/Player/modules/VideoAgent/VideoAgentMesh.ts +0 -302
- package/resources/Player/modules/VideoAgent/VideoAgentScene.ts +0 -56
- package/resources/Player/modules/VideoAgent/index.tsx +0 -53
- package/resources/Player/modules/Wave/index.tsx +0 -18
- package/resources/Player/modules/keyframes/BgMusic/index.tsx +0 -66
- package/resources/Player/modules/keyframes/CameraMovement/index.tsx +0 -37
- package/resources/Player/modules/keyframes/InfoPanel/index.tsx +0 -165
- package/resources/Player/modules/keyframes/ModelVideo/index.tsx +0 -77
- package/resources/Player/modules/keyframes/PanoEffect/index.tsx +0 -99
- package/resources/Player/modules/keyframes/PanoEffect/lineAnime.ts +0 -31
- package/resources/Player/modules/keyframes/PanoTag/index.tsx +0 -82
- package/resources/Player/modules/keyframes/PanoTextLabel/index.tsx +0 -117
- package/resources/Player/modules/keyframes/Prompter/index.tsx +0 -56
- package/resources/Player/modules/keyframes/UpdateVRPanorama/index.tsx +0 -99
- package/resources/Player/modules/keyframes/VideoEffect/index.tsx +0 -115
- package/resources/Player/typings.ts +0 -49
- package/resources/fivePlugins/CSS3DRenderPlugin/centerPoint.ts +0 -5
- package/resources/fivePlugins/CSS3DRenderPlugin/createResizeObserver.ts +0 -17
- package/resources/fivePlugins/CSS3DRenderPlugin/evenNumber.ts +0 -4
- package/resources/fivePlugins/CSS3DRenderPlugin/index.ts +0 -254
- package/resources/fivePlugins/CSS3DRenderPlugin/transformPositionToVector3.ts +0 -5
- package/resources/fivePlugins/CameraMovementPlugin/index.ts +0 -226
- package/resources/fivePlugins/CameraMovementPlugin/typings.ts +0 -59
- package/resources/fivePlugins/ModelTVVideoPlugin/index.ts +0 -278
- package/resources/index.ts +0 -1
- package/resources/react/index.tsx +0 -121
- package/resources/shared-utils/AduioLike.ts +0 -109
- package/resources/shared-utils/Preloader.ts +0 -35
- package/resources/shared-utils/addResizeListener.ts +0 -46
- package/resources/shared-utils/animationFrame/BetterTween.ts +0 -33
- package/resources/shared-utils/animationFrame/index.ts +0 -48
- package/resources/shared-utils/animationFrame/tween.ts +0 -51
- package/resources/shared-utils/createTransMatrix.ts +0 -12
- package/resources/shared-utils/getFileExpandedName.ts +0 -6
- package/resources/shared-utils/getMediaInfo.ts +0 -52
- package/resources/shared-utils/setElementDataset.ts +0 -18
- package/resources/typings/VreoUnit.ts +0 -314
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three'
|
|
2
|
-
import { Preloader } from '../../../shared-utils/Preloader'
|
|
3
|
-
import { makeObservable, observable, runInAction } from 'mobx'
|
|
4
|
-
import AudioLike from '../../../shared-utils/AduioLike'
|
|
5
|
-
import { getMediaType } from '../../../shared-utils/getMediaInfo'
|
|
6
|
-
|
|
7
|
-
const vertexShader = `
|
|
8
|
-
varying vec2 vUv;
|
|
9
|
-
varying vec2 vColorUv;
|
|
10
|
-
varying vec2 vMaskUv;
|
|
11
|
-
void main(){
|
|
12
|
-
vUv = uv;
|
|
13
|
-
vColorUv = vec2(uv.x / 2.0, uv.y);
|
|
14
|
-
vMaskUv = vec2(0.5 + uv.x / 2.0, uv.y);
|
|
15
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
16
|
-
}
|
|
17
|
-
`
|
|
18
|
-
const fragmentShaderTpl = () => `
|
|
19
|
-
uniform int enable;
|
|
20
|
-
uniform sampler2D map;
|
|
21
|
-
varying vec2 vUv;
|
|
22
|
-
varying vec2 vColorUv;
|
|
23
|
-
varying vec2 vMaskUv;
|
|
24
|
-
|
|
25
|
-
vec3 hsv2rgb(vec3 c) {
|
|
26
|
-
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
27
|
-
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
|
28
|
-
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
vec3 rgb2hsv(vec3 c) {
|
|
32
|
-
const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
|
33
|
-
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
|
34
|
-
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
|
35
|
-
|
|
36
|
-
float d = q.x - min(q.w, q.y);
|
|
37
|
-
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + 0.001)), d / (q.x + 0.001), q.x);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
void main(void) {
|
|
41
|
-
vec3 color = texture2D(map, vUv).xyz;
|
|
42
|
-
float amask = 1.0;
|
|
43
|
-
|
|
44
|
-
float ref = color.r;
|
|
45
|
-
if (ref < color.b) ref = color.b;
|
|
46
|
-
amask = color.g - ref + 0.1;
|
|
47
|
-
amask = smoothstep(0.1, 0.3, amask);
|
|
48
|
-
amask = 1.0 - amask;
|
|
49
|
-
|
|
50
|
-
vec3 target = rgb2hsv(vec3(0.0 / 255.0, 255.0 / 255.0, 0.0 / 255.0));
|
|
51
|
-
vec3 hsv = rgb2hsv(color);
|
|
52
|
-
float distance = abs(hsv.x - target.x);
|
|
53
|
-
if (distance < 0.15) {
|
|
54
|
-
hsv.y = 0.0;
|
|
55
|
-
}
|
|
56
|
-
color = hsv2rgb(hsv);
|
|
57
|
-
|
|
58
|
-
gl_FragColor = vec4(color.rgb, amask * float(enable));
|
|
59
|
-
}
|
|
60
|
-
`
|
|
61
|
-
|
|
62
|
-
const cacheInstance: {
|
|
63
|
-
videoInstance?: HTMLVideoElement
|
|
64
|
-
audioInstance?: HTMLAudioElement
|
|
65
|
-
} = {}
|
|
66
|
-
|
|
67
|
-
export interface VideoAgentMeshOptions {
|
|
68
|
-
/**
|
|
69
|
-
* 自定义视频实例。
|
|
70
|
-
*/
|
|
71
|
-
videoInstance?: HTMLVideoElement
|
|
72
|
-
/**
|
|
73
|
-
* 自定义音频实例。
|
|
74
|
-
*/
|
|
75
|
-
audioInstance?: HTMLAudioElement
|
|
76
|
-
/**
|
|
77
|
-
* 是否开启音频预载能力。**仅对`.mp3`有效**。
|
|
78
|
-
*
|
|
79
|
-
* @description 开启预载能力后会通过 `Fetch/XHR` 方式将音频文件下载转成二进制 [`Blob`](https://developer.mozilla.org/zh-CN/docs/Web/API/Blob) 提供给多媒体实例。这样的好处是 **能够保障音视频播放过程中不卡顿**。 但在部分 iOS 系统中会存在兼容问题——播 25s 之后会静音(`muted` 为 `false`,但是没有声音)。
|
|
80
|
-
*/
|
|
81
|
-
preload?: boolean
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* 视频经纪人MESH
|
|
86
|
-
*/
|
|
87
|
-
export class VideoAgentMesh extends THREE.Mesh {
|
|
88
|
-
options: VideoAgentMeshOptions
|
|
89
|
-
videoUrl?: string
|
|
90
|
-
freeze: boolean
|
|
91
|
-
paused: boolean
|
|
92
|
-
audioInstance: HTMLAudioElement
|
|
93
|
-
audioLikeInstance: AudioLike
|
|
94
|
-
$removeEventListener: () => void
|
|
95
|
-
|
|
96
|
-
get mediaInstance(): HTMLAudioElement | HTMLVideoElement | AudioLike {
|
|
97
|
-
if (!this.videoUrl) {
|
|
98
|
-
return this.audioLikeInstance
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (getMediaType(this.videoUrl) === 'audio') {
|
|
102
|
-
return this.audioInstance
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const uniforms = (this.material as THREE.ShaderMaterial).uniforms
|
|
106
|
-
const videoInstance = uniforms.map.value.image as HTMLVideoElement
|
|
107
|
-
|
|
108
|
-
return videoInstance
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
*
|
|
113
|
-
* @param width
|
|
114
|
-
* @param height
|
|
115
|
-
* @param widthSegments
|
|
116
|
-
* @param heightSegments
|
|
117
|
-
* @param options
|
|
118
|
-
*/
|
|
119
|
-
constructor(
|
|
120
|
-
width: number,
|
|
121
|
-
height: number,
|
|
122
|
-
widthSegments: number,
|
|
123
|
-
heightSegments: number,
|
|
124
|
-
options: VideoAgentMeshOptions = {
|
|
125
|
-
preload: true
|
|
126
|
-
},
|
|
127
|
-
) {
|
|
128
|
-
if (!options.videoInstance) {
|
|
129
|
-
if (cacheInstance.videoInstance) {
|
|
130
|
-
options.videoInstance = cacheInstance.videoInstance
|
|
131
|
-
} else {
|
|
132
|
-
const videoInstance = document.createElement('video')
|
|
133
|
-
videoInstance.style.opacity = '0'
|
|
134
|
-
videoInstance.style.pointerEvents = 'none'
|
|
135
|
-
videoInstance.style.display = 'none'
|
|
136
|
-
document.body.append(videoInstance)
|
|
137
|
-
options.videoInstance = videoInstance
|
|
138
|
-
cacheInstance.videoInstance = videoInstance
|
|
139
|
-
videoInstance.playsInline = true
|
|
140
|
-
videoInstance.controls = false
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const geometry = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments)
|
|
145
|
-
const videoTexture = new THREE.VideoTexture(options.videoInstance)
|
|
146
|
-
const material = new THREE.ShaderMaterial({
|
|
147
|
-
uniforms: {
|
|
148
|
-
map: { value: videoTexture },
|
|
149
|
-
enable: { value: 0 },
|
|
150
|
-
},
|
|
151
|
-
vertexShader,
|
|
152
|
-
fragmentShader: fragmentShaderTpl(),
|
|
153
|
-
transparent: true,
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
super(geometry, material)
|
|
157
|
-
this.options = options
|
|
158
|
-
this.freeze = false
|
|
159
|
-
this.paused = true
|
|
160
|
-
|
|
161
|
-
if (!options.audioInstance) {
|
|
162
|
-
if (cacheInstance.audioInstance) {
|
|
163
|
-
this.audioInstance = cacheInstance.audioInstance
|
|
164
|
-
} else {
|
|
165
|
-
const audioInstance = document.createElement('audio')
|
|
166
|
-
audioInstance.crossOrigin = ''
|
|
167
|
-
// videoInstance.muted = true
|
|
168
|
-
audioInstance.muted = false
|
|
169
|
-
audioInstance.autoplay = false
|
|
170
|
-
audioInstance.style.display = 'none'
|
|
171
|
-
document.body.appendChild(audioInstance)
|
|
172
|
-
this.audioInstance = audioInstance
|
|
173
|
-
cacheInstance.audioInstance = audioInstance
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
this.audioInstance = options.audioInstance
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this.audioLikeInstance = new AudioLike()
|
|
180
|
-
|
|
181
|
-
makeObservable(this, { paused: observable })
|
|
182
|
-
|
|
183
|
-
const updatePaused = (paused: boolean) => runInAction(() => (this.paused = paused))
|
|
184
|
-
const onPause = () => updatePaused(true)
|
|
185
|
-
const onPlay = () => updatePaused(false)
|
|
186
|
-
const onEnded = () => console.log('vreo: video 播放结束')
|
|
187
|
-
|
|
188
|
-
this.audioInstance.addEventListener('pause', onPause)
|
|
189
|
-
this.audioInstance.addEventListener('play', onPlay)
|
|
190
|
-
this.options.videoInstance?.addEventListener('pause', onPause)
|
|
191
|
-
this.options.videoInstance?.addEventListener('play', onPlay)
|
|
192
|
-
this.audioLikeInstance.addEventListener('pause', onPause)
|
|
193
|
-
this.audioLikeInstance.addEventListener('play', onPlay)
|
|
194
|
-
this.options.videoInstance?.addEventListener('ended', onEnded)
|
|
195
|
-
|
|
196
|
-
this.$removeEventListener = () => {
|
|
197
|
-
this.audioInstance.removeEventListener('pause', onPause)
|
|
198
|
-
this.audioInstance.removeEventListener('play', onPlay)
|
|
199
|
-
this.options.videoInstance?.removeEventListener('pause', onPause)
|
|
200
|
-
this.options.videoInstance?.removeEventListener('play', onPlay)
|
|
201
|
-
this.audioLikeInstance.removeEventListener('pause', onPause)
|
|
202
|
-
this.audioLikeInstance.removeEventListener('play', onPlay)
|
|
203
|
-
this.options.videoInstance?.removeEventListener('ended', onEnded)
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
private async update(videoUrl: string) {
|
|
208
|
-
|
|
209
|
-
if (this.videoUrl === videoUrl) {
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
this.videoUrl = videoUrl
|
|
214
|
-
|
|
215
|
-
// // 兼容非视频场景
|
|
216
|
-
// if (this.mediaInstance instanceof HTMLAudioElement) {
|
|
217
|
-
// this.mediaInstance.style.display = 'none'
|
|
218
|
-
// } else if (this.mediaInstance instanceof HTMLVideoElement) {
|
|
219
|
-
// this.mediaInstance.style.display = 'block'
|
|
220
|
-
// }
|
|
221
|
-
|
|
222
|
-
this.freeze = true
|
|
223
|
-
await this.mediaInstance.pause()
|
|
224
|
-
|
|
225
|
-
const uniforms = (this.material as THREE.ShaderMaterial).uniforms
|
|
226
|
-
this.mediaInstance.muted = true
|
|
227
|
-
|
|
228
|
-
this.mediaInstance.src = (this.options.preload || this.options.preload === undefined || getMediaType(this.videoUrl) === 'video') ?
|
|
229
|
-
await URL.createObjectURL((await Preloader.blob(this.videoUrl)) as unknown as Blob) : this.videoUrl
|
|
230
|
-
this.mediaInstance.setAttribute('data-src', this.videoUrl)
|
|
231
|
-
|
|
232
|
-
const onStart = () => {
|
|
233
|
-
if (this.mediaInstance.currentTime === 0) return
|
|
234
|
-
this.freeze = false
|
|
235
|
-
this.mediaInstance.muted = false
|
|
236
|
-
uniforms.enable.value = getMediaType(this.videoUrl) ? 1 : 0
|
|
237
|
-
this.mediaInstance.removeEventListener('timeupdate', onStart, false)
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
this.mediaInstance.addEventListener('timeupdate', onStart, false)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
async play(videoUrl = '', currentTime = 0, duration?: number) {
|
|
245
|
-
videoUrl = videoUrl || ''
|
|
246
|
-
|
|
247
|
-
if (duration && !videoUrl) {
|
|
248
|
-
if (this.currentTime) {
|
|
249
|
-
this.mediaInstance.currentTime = currentTime
|
|
250
|
-
}
|
|
251
|
-
(this.mediaInstance as AudioLike).duration = duration
|
|
252
|
-
this.videoUrl = ''
|
|
253
|
-
this.mediaInstance.play()
|
|
254
|
-
return true
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (!videoUrl) {
|
|
258
|
-
if (this.videoUrl) await this.mediaInstance.play()
|
|
259
|
-
else console.warn('警告:视频资源未初始化。')
|
|
260
|
-
return true
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (videoUrl === this.videoUrl) {
|
|
264
|
-
this.mediaInstance.currentTime = currentTime
|
|
265
|
-
await this.mediaInstance.play()
|
|
266
|
-
return true
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
await this.update(videoUrl)
|
|
270
|
-
|
|
271
|
-
this.mediaInstance.pause()
|
|
272
|
-
|
|
273
|
-
return await new Promise((resolve) =>
|
|
274
|
-
setTimeout(async () => {
|
|
275
|
-
this.mediaInstance.currentTime = currentTime
|
|
276
|
-
await this.mediaInstance.play()
|
|
277
|
-
resolve(true)
|
|
278
|
-
}, 20),
|
|
279
|
-
)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* 转成毫秒,保障精准度
|
|
284
|
-
*/
|
|
285
|
-
get currentTime() {
|
|
286
|
-
return this.mediaInstance.currentTime * 1000
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
dispose() {
|
|
290
|
-
// 销毁事件监听
|
|
291
|
-
this.$removeEventListener()
|
|
292
|
-
if (cacheInstance.audioInstance) {
|
|
293
|
-
document.body.removeChild(cacheInstance.audioInstance)
|
|
294
|
-
cacheInstance.audioInstance = undefined
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (cacheInstance.videoInstance) {
|
|
298
|
-
document.body.removeChild(cacheInstance.videoInstance)
|
|
299
|
-
cacheInstance.videoInstance = undefined
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three'
|
|
2
|
-
import { addResizeListener } from '../../../shared-utils/addResizeListener'
|
|
3
|
-
import { getMediaType } from '../../../shared-utils/getMediaInfo'
|
|
4
|
-
import { VideoAgentMesh, VideoAgentMeshOptions } from './VideoAgentMesh'
|
|
5
|
-
|
|
6
|
-
export class VideoAgentScene {
|
|
7
|
-
videoAgentMesh: VideoAgentMesh
|
|
8
|
-
|
|
9
|
-
scene = new THREE.Scene()
|
|
10
|
-
camera = new THREE.OrthographicCamera(-240, 240, 135, -135)
|
|
11
|
-
renderer = new THREE.WebGLRenderer({ alpha: true })
|
|
12
|
-
disposers: (() => void)[] = []
|
|
13
|
-
|
|
14
|
-
constructor(container?: HTMLElement, options?: VideoAgentMeshOptions) {
|
|
15
|
-
|
|
16
|
-
this.videoAgentMesh = new VideoAgentMesh(480, 270, 1, 1, options)
|
|
17
|
-
|
|
18
|
-
// const needRender = getMediaType(this.videoAgentMesh.videoUrl) === 'video'
|
|
19
|
-
|
|
20
|
-
if (container) {
|
|
21
|
-
|
|
22
|
-
this.camera.position.set(0, 0, 10)
|
|
23
|
-
this.camera.lookAt(0, 0, 0)
|
|
24
|
-
|
|
25
|
-
const domElement = this.renderer.domElement
|
|
26
|
-
domElement.classList.add('VideoAgent-canvas')
|
|
27
|
-
|
|
28
|
-
const dispose = addResizeListener(container, (width, height) => {
|
|
29
|
-
this.renderer.setSize(width * window.devicePixelRatio, height * window.devicePixelRatio)
|
|
30
|
-
domElement.style.width = `${width}px`
|
|
31
|
-
domElement.style.height = `${height}px`
|
|
32
|
-
} )
|
|
33
|
-
|
|
34
|
-
this.disposers.push(dispose)
|
|
35
|
-
|
|
36
|
-
container.append(domElement)
|
|
37
|
-
this.scene.add(this.videoAgentMesh)
|
|
38
|
-
|
|
39
|
-
this.run()
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
run = () => {
|
|
44
|
-
// 视频开始 1s 不渲染:规避某些设备黑屏闪烁问题。视频前 2s 是最好是静默的。
|
|
45
|
-
if (!(this.videoAgentMesh.paused || this.videoAgentMesh.freeze) && this.videoAgentMesh.currentTime > 1000) {
|
|
46
|
-
this.renderer.render(this.scene, this.camera)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
requestAnimationFrame(this.run)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
dispose = () => {
|
|
53
|
-
this.videoAgentMesh?.dispose()
|
|
54
|
-
this.disposers.forEach(disposer => disposer?.())
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import { useController } from '../../hooks'
|
|
3
|
-
import { VideoAgentMeshOptions } from './VideoAgentMesh'
|
|
4
|
-
import { VideoAgentScene } from './VideoAgentScene'
|
|
5
|
-
import classNames from 'classnames'
|
|
6
|
-
|
|
7
|
-
export function VideoAgent(props: { onClick?: () => void; options?: VideoAgentMeshOptions }) {
|
|
8
|
-
const ref = React.useRef<HTMLDivElement>(null)
|
|
9
|
-
const controller = useController()
|
|
10
|
-
|
|
11
|
-
const showAvatar = React.useMemo(() => {
|
|
12
|
-
return controller.avatar?.url && (controller.avatar.force === true)
|
|
13
|
-
}, [controller.avatar])
|
|
14
|
-
|
|
15
|
-
const showVideoAgent = React.useMemo(() => {
|
|
16
|
-
if (showAvatar) return false
|
|
17
|
-
return controller.videoAgentScene?.videoAgentMesh.mediaInstance instanceof HTMLVideoElement
|
|
18
|
-
}, [controller.videoAgentScene])
|
|
19
|
-
|
|
20
|
-
React.useEffect(() => {
|
|
21
|
-
if (!ref.current) throw new Error('React 渲染异常,请稍后重试 ...')
|
|
22
|
-
if (controller.videoAgentScene) {
|
|
23
|
-
console.warn('VideoAgentScene" 重复初始化,已被过滤')
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
const videoAgentScene = new VideoAgentScene(ref.current, props.options)
|
|
27
|
-
controller.videoAgentScene = videoAgentScene
|
|
28
|
-
|
|
29
|
-
return () => {
|
|
30
|
-
controller.dispose()
|
|
31
|
-
controller.videoAgentScene?.dispose()
|
|
32
|
-
}
|
|
33
|
-
}, [])
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<>
|
|
37
|
-
<div className="Avatar" style={{display: showAvatar ? 'block' : 'none'}}>
|
|
38
|
-
<div className="Avatar-wrapper ratio-1-1">
|
|
39
|
-
<img className="Avatar-img" src={controller.avatar?.url} onClick={() => props.onClick?.()} />
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
42
|
-
<div className={classNames('VideoAgent', { hide: !showVideoAgent })}>
|
|
43
|
-
<div className="VideoAgent-container">
|
|
44
|
-
<div className="VideoAgent-wrapper ratio-16-9">
|
|
45
|
-
<div className="VideoAgent-inner" ref={ref}>
|
|
46
|
-
<div className="VideoAgent-play" onClick={() => props.onClick?.()}></div>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
</>
|
|
52
|
-
)
|
|
53
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { WaveAppearance } from '../../typings'
|
|
3
|
-
|
|
4
|
-
export function Wave(props?: { appearance?: WaveAppearance }) {
|
|
5
|
-
const waveUrl = React.useMemo(() => {
|
|
6
|
-
const appearance = props?.appearance ?? 'solid'
|
|
7
|
-
switch (appearance) {
|
|
8
|
-
default: return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-solid.64438b63cbb346906d066bb7b8dc3e20.webm'
|
|
9
|
-
case 'solid': return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-solid.64438b63cbb346906d066bb7b8dc3e20.webm'
|
|
10
|
-
case 'single': return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-single.eda65de390a830193fff40d1f1255555.webm'
|
|
11
|
-
case 'double': return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-double.77dfe8548ebcb3f3d336785d4fe9c7b2.webm'
|
|
12
|
-
case 'swap': return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-swap.c02e4b94cf05aecf6e7a0023bc7bb90f.webm'
|
|
13
|
-
case 'expand': return 'https://vr-public.realsee-cdn.cn/release/static/image/release/vapor/static/wave-expand.a0d2a0074001cd3d4fea56818c6d3c38.webm'
|
|
14
|
-
}
|
|
15
|
-
}, [props?.appearance])
|
|
16
|
-
|
|
17
|
-
return <video className='vreo-wave' width="100%" preload="auto" muted autoPlay loop playsInline disablePictureInPicture controls={false} src={waveUrl} />
|
|
18
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import { BgMusicData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
|
|
3
|
-
import { useController } from '../../../hooks'
|
|
4
|
-
|
|
5
|
-
export function BgMusic() {
|
|
6
|
-
const controller = useController()
|
|
7
|
-
const timeoutIdRef = React.useRef<NodeJS.Timeout | null>(null)
|
|
8
|
-
const cleanTimeout = React.useCallback( () => {
|
|
9
|
-
if (timeoutIdRef.current) {
|
|
10
|
-
clearTimeout(timeoutIdRef.current)
|
|
11
|
-
timeoutIdRef.current = null
|
|
12
|
-
}
|
|
13
|
-
}, [])
|
|
14
|
-
|
|
15
|
-
React.useEffect(() => {
|
|
16
|
-
const audio = new Audio()
|
|
17
|
-
audio.setAttribute('id', 'vreo-singleton-bgmusic')
|
|
18
|
-
audio.style.display = 'none'
|
|
19
|
-
|
|
20
|
-
audio.setAttribute('playsinline', 'true')
|
|
21
|
-
audio.loop = true
|
|
22
|
-
document.body.append(audio)
|
|
23
|
-
|
|
24
|
-
const callback = (keyframe: VreoKeyframe) => {
|
|
25
|
-
const { start, end } = keyframe
|
|
26
|
-
const { url } = keyframe.data as BgMusicData
|
|
27
|
-
audio.src = url
|
|
28
|
-
const playCallback = () => {
|
|
29
|
-
audio.play()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
audio.addEventListener('canplaythrough', playCallback)
|
|
33
|
-
|
|
34
|
-
cleanTimeout()
|
|
35
|
-
|
|
36
|
-
const cleanAudio = () => {
|
|
37
|
-
audio.pause()
|
|
38
|
-
audio.currentTime = 0
|
|
39
|
-
audio.src = ''
|
|
40
|
-
cleanTimeout()
|
|
41
|
-
audio.removeEventListener('canplaythrough', playCallback)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const duration = (end - start) || 5000
|
|
45
|
-
|
|
46
|
-
timeoutIdRef.current = setTimeout(() => {
|
|
47
|
-
cleanAudio()
|
|
48
|
-
}, duration)
|
|
49
|
-
|
|
50
|
-
controller.once('paused', () => {
|
|
51
|
-
cleanAudio()
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
controller.on(VreoKeyframeEnum.BgMusic, callback)
|
|
57
|
-
|
|
58
|
-
return () => {
|
|
59
|
-
controller.off(VreoKeyframeEnum.BgMusic, callback)
|
|
60
|
-
document.body.removeChild(audio)
|
|
61
|
-
cleanTimeout()
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
return <></>
|
|
66
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import { CameraMovementPlugin } from '../../../../fivePlugins/CameraMovementPlugin'
|
|
3
|
-
import { CameraMovementEffect, MoveArgs, RotateArgs } from '../../../../fivePlugins/CameraMovementPlugin/typings'
|
|
4
|
-
import { CameraMovementData, VreoKeyframe, VreoKeyframeEnum } from '../../../../typings/VreoUnit'
|
|
5
|
-
import { useController, useFiveInstance } from '../../../hooks'
|
|
6
|
-
|
|
7
|
-
export function CameraMovement() {
|
|
8
|
-
const controller = useController()
|
|
9
|
-
const five = useFiveInstance()
|
|
10
|
-
const ref = React.useRef<ReturnType<typeof CameraMovementPlugin>>()
|
|
11
|
-
|
|
12
|
-
React.useEffect(() => {
|
|
13
|
-
const callback = async (keyframe: VreoKeyframe) => {
|
|
14
|
-
if (!ref.current) {
|
|
15
|
-
ref.current = CameraMovementPlugin(five, {})
|
|
16
|
-
}
|
|
17
|
-
const { start, end, data } = keyframe
|
|
18
|
-
const cameraMovementData = data as CameraMovementData
|
|
19
|
-
const effect = cameraMovementData.effect
|
|
20
|
-
if (effect === CameraMovementEffect.Rotate) {
|
|
21
|
-
await ref.current.rotate(data as RotateArgs, end - start)
|
|
22
|
-
} else if (effect === CameraMovementEffect.Move) {
|
|
23
|
-
await ref.current.move(data as MoveArgs, end - start)
|
|
24
|
-
} else if (cameraMovementData.panoIndex !== undefined && cameraMovementData.panoIndex !== five.panoIndex) {
|
|
25
|
-
await ref.current.move(data as MoveArgs, end - start)
|
|
26
|
-
} else {
|
|
27
|
-
await ref.current.rotate(data as RotateArgs, end - start)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
controller.on(VreoKeyframeEnum.CameraMovement, callback)
|
|
32
|
-
return () => {
|
|
33
|
-
controller.off(VreoKeyframeEnum.CameraMovement, callback)
|
|
34
|
-
}
|
|
35
|
-
}, [controller])
|
|
36
|
-
return <></>
|
|
37
|
-
}
|