@zcomponent/three-video-player 1.2.1 → 2.0.0-alpha.2
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 +1 -0
- package/index.js +0 -3
- package/lib/components/basevideo.d.ts +51 -53
- package/lib/components/basevideo.js +294 -180
- package/lib/components/videoplayer.d.ts +8 -6
- package/lib/components/videoplayer.js +136 -76
- package/lib/index.d.ts +2 -4
- package/lib/index.js +1 -2
- package/package.json +21 -4
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
|
+
import { ContextManager, Event, PlayOptions, Stream, ValueOf } from '@zcomponent/core';
|
|
2
|
+
import { Object3D } from '@zcomponent/three/components/Object3D';
|
|
3
|
+
import { MeshChromaKeyMaterial } from '@zcomponent/three/internal/MeshChromaKeyMaterial';
|
|
4
|
+
import { MeshSideBySideAlphaMaterial, SideBySideDirectionValue } from '@zcomponent/three/internal/MeshSideBySideAlphaMaterial';
|
|
1
5
|
import * as THREE from 'three';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
chromaKey = "chromaKey",
|
|
9
|
-
sideBySide = "sideBySide"
|
|
10
|
-
}
|
|
6
|
+
export declare const VideoTransparencyType: {
|
|
7
|
+
readonly none: "none";
|
|
8
|
+
readonly chromaKey: "chromaKey";
|
|
9
|
+
readonly sideBySide: "sideBySide";
|
|
10
|
+
};
|
|
11
|
+
export type VideoTransparencyTypeValue = ValueOf<typeof VideoTransparencyType>;
|
|
11
12
|
export interface BaseVideoConstructorProps {
|
|
12
13
|
geometry?: THREE.BufferGeometry;
|
|
13
14
|
/**
|
|
14
15
|
* Support videos with transparency
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
17
|
+
*
|
|
18
|
+
* @default none
|
|
18
19
|
*/
|
|
19
|
-
transparent:
|
|
20
|
-
/**
|
|
21
|
-
* @
|
|
20
|
+
transparent: VideoTransparencyTypeValue;
|
|
21
|
+
/**
|
|
22
|
+
* @default false
|
|
22
23
|
*/
|
|
23
24
|
autoplay: boolean;
|
|
24
25
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @
|
|
26
|
+
*
|
|
27
|
+
* @default default
|
|
27
28
|
*/
|
|
28
29
|
audioLayer?: string;
|
|
29
30
|
}
|
|
@@ -32,10 +33,6 @@ export interface BaseVideoConstructorProps {
|
|
|
32
33
|
* Supports various video transparency types, including chroma key and side-by-side transparency.
|
|
33
34
|
*
|
|
34
35
|
* Root element: [THREE.Group](https://threejs.org/docs/index.html#api/en/objects/Group)
|
|
35
|
-
* @zicon video_library
|
|
36
|
-
* @ztag three/Object3D/BaseVideo
|
|
37
|
-
* @zparents three/Object3D/Group/**
|
|
38
|
-
* @zgroup Media
|
|
39
36
|
* @zstream
|
|
40
37
|
*/
|
|
41
38
|
export declare abstract class BaseVideo extends Object3D implements Stream {
|
|
@@ -51,103 +48,104 @@ export declare abstract class BaseVideo extends Object3D implements Stream {
|
|
|
51
48
|
material: THREE.MeshBasicMaterial | MeshChromaKeyMaterial | MeshSideBySideAlphaMaterial;
|
|
52
49
|
mesh: THREE.Mesh;
|
|
53
50
|
texture: THREE.VideoTexture;
|
|
54
|
-
transparent:
|
|
51
|
+
transparent: VideoTransparencyTypeValue;
|
|
55
52
|
videoElement: HTMLVideoElement;
|
|
56
53
|
protected _gain: GainNode;
|
|
54
|
+
/**
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
57
|
protected _hadUserEvent: boolean;
|
|
58
58
|
constructor(ctx: ContextManager, constructorProps: BaseVideoConstructorProps);
|
|
59
59
|
private _updateSize;
|
|
60
60
|
private _updateMute;
|
|
61
61
|
/**
|
|
62
62
|
* The volume of the video, from 0 to 1.
|
|
63
|
-
* @
|
|
63
|
+
* @default 1
|
|
64
|
+
* @zui
|
|
64
65
|
* @ztype proportion
|
|
65
|
-
* @zdefault 1
|
|
66
66
|
*/
|
|
67
|
-
volume:
|
|
67
|
+
volume: number;
|
|
68
68
|
/**
|
|
69
69
|
* Whether the video is muted.
|
|
70
|
-
* @
|
|
71
|
-
* @zdefault false
|
|
70
|
+
* @default false
|
|
72
71
|
*/
|
|
73
|
-
muted:
|
|
72
|
+
muted: boolean;
|
|
74
73
|
/**
|
|
75
74
|
* Whether the video should loop when it reaches the end.
|
|
76
|
-
* @
|
|
77
|
-
* @zdefault false
|
|
75
|
+
* @default false
|
|
78
76
|
*/
|
|
79
|
-
loop:
|
|
77
|
+
loop: boolean;
|
|
80
78
|
/**
|
|
81
79
|
* Plays the video.
|
|
82
|
-
* @zprop
|
|
83
80
|
* @zui
|
|
84
81
|
*/
|
|
85
82
|
play(opts?: PlayOptions): void;
|
|
86
83
|
/**
|
|
87
84
|
* Pauses the video.
|
|
88
|
-
* @zprop
|
|
89
85
|
* @zui
|
|
90
86
|
*/
|
|
91
87
|
pause(): void;
|
|
92
88
|
/**
|
|
93
89
|
* Stops the video and resets the playback position to the beginning.
|
|
94
|
-
* @zprop
|
|
95
90
|
* @zui
|
|
96
91
|
*/
|
|
97
92
|
stop(): void;
|
|
98
93
|
/**
|
|
99
94
|
* Seeks to a specified time in the video in milliseconds.
|
|
100
|
-
* @zprop
|
|
101
95
|
* @zui
|
|
102
96
|
*/
|
|
103
|
-
seek(
|
|
97
|
+
seek(t: number): void;
|
|
104
98
|
length(): number | undefined;
|
|
105
99
|
isStalled(): boolean;
|
|
106
100
|
/**
|
|
107
101
|
* The chroma key similarity value, from 0 to 1.
|
|
108
|
-
* @
|
|
102
|
+
* @default 0.05
|
|
103
|
+
* @zui
|
|
109
104
|
* @zgroup Chroma Key Transparency
|
|
110
105
|
* @ztype proportion
|
|
111
|
-
* @zdefault 0.05
|
|
112
106
|
*/
|
|
113
|
-
similarity:
|
|
107
|
+
similarity: number;
|
|
114
108
|
/**
|
|
115
109
|
* The smoothness of the chroma key, from 0 to 1.
|
|
116
|
-
* @
|
|
110
|
+
* @default 0.08
|
|
111
|
+
* @zui
|
|
117
112
|
* @zgroup Chroma Key Transparency
|
|
118
113
|
* @ztype proportion
|
|
119
|
-
* @zdefault 0.08
|
|
120
114
|
*/
|
|
121
|
-
smoothness:
|
|
115
|
+
smoothness: number;
|
|
122
116
|
/**
|
|
123
117
|
* The spill of the chroma key, from 0 to 1.
|
|
124
|
-
* @
|
|
118
|
+
* @default 0.2
|
|
119
|
+
* @zui
|
|
125
120
|
* @zgroup Chroma Key Transparency
|
|
126
121
|
* @ztype proportion
|
|
127
|
-
* @zdefault 0.2
|
|
128
122
|
*/
|
|
129
|
-
spill:
|
|
123
|
+
spill: number;
|
|
130
124
|
/**
|
|
131
125
|
* The key color of the chroma key, as an RGB array.
|
|
132
|
-
* @
|
|
126
|
+
* @default [0,1,0]
|
|
127
|
+
* @zui
|
|
133
128
|
* @zgroup Chroma Key Transparency
|
|
134
129
|
* @ztype color-norm-rgb-linear
|
|
135
|
-
* @zdefault [0, 1, 0]
|
|
136
130
|
*/
|
|
137
|
-
keyColor:
|
|
131
|
+
keyColor: [
|
|
132
|
+
number,
|
|
133
|
+
number,
|
|
134
|
+
number
|
|
135
|
+
];
|
|
138
136
|
/**
|
|
139
137
|
* The direction of the side-by-side transparency.
|
|
140
|
-
* @
|
|
138
|
+
* @default "LeftRight"
|
|
139
|
+
* @zui
|
|
141
140
|
* @zgroup Side By Side Transparency
|
|
142
|
-
* @zdefault LeftRight
|
|
143
141
|
*/
|
|
144
|
-
direction:
|
|
142
|
+
direction: SideBySideDirectionValue;
|
|
145
143
|
/**
|
|
146
144
|
* Whether the alpha channel is first or second in the side-by-side transparency.
|
|
147
|
-
* @
|
|
145
|
+
* @default false
|
|
146
|
+
* @zui
|
|
148
147
|
* @zgroup Side By Side Transparency
|
|
149
|
-
* @zdefault false
|
|
150
148
|
*/
|
|
151
|
-
alphaFirst:
|
|
149
|
+
alphaFirst: boolean;
|
|
152
150
|
dispose(): never;
|
|
153
151
|
}
|
|
@@ -1,237 +1,351 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
import { AudioContextContext, Event, isDesignTime, nextUserEvent, registerLoadable, started, useOnBeforeRender, zObserve, zUI } from '@zcomponent/core';
|
|
36
|
+
import { Object3D } from '@zcomponent/three/components/Object3D';
|
|
37
|
+
import { MeshChromaKeyMaterial } from '@zcomponent/three/internal/MeshChromaKeyMaterial';
|
|
38
|
+
import { MeshSideBySideAlphaMaterial, SideBySideDirection } from '@zcomponent/three/internal/MeshSideBySideAlphaMaterial';
|
|
1
39
|
import * as THREE from 'three';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export var VideoTransparencyType;
|
|
9
|
-
(function (VideoTransparencyType) {
|
|
10
|
-
VideoTransparencyType["none"] = "none";
|
|
11
|
-
VideoTransparencyType["chromaKey"] = "chromaKey";
|
|
12
|
-
VideoTransparencyType["sideBySide"] = "sideBySide";
|
|
13
|
-
})(VideoTransparencyType || (VideoTransparencyType = {}));
|
|
40
|
+
export const VideoTransparencyType = {
|
|
41
|
+
none: 'none',
|
|
42
|
+
chromaKey: 'chromaKey',
|
|
43
|
+
sideBySide: 'sideBySide',
|
|
44
|
+
};
|
|
45
|
+
Object.freeze(VideoTransparencyType);
|
|
14
46
|
/**
|
|
15
47
|
* Abstract base class for video components in a 3D environment.
|
|
16
48
|
* Supports various video transparency types, including chroma key and side-by-side transparency.
|
|
17
49
|
*
|
|
18
50
|
* Root element: [THREE.Group](https://threejs.org/docs/index.html#api/en/objects/Group)
|
|
19
|
-
* @zicon video_library
|
|
20
|
-
* @ztag three/Object3D/BaseVideo
|
|
21
|
-
* @zparents three/Object3D/Group/**
|
|
22
|
-
* @zgroup Media
|
|
23
51
|
* @zstream
|
|
24
52
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
53
|
+
let BaseVideo = (() => {
|
|
54
|
+
let _classSuper = Object3D;
|
|
55
|
+
let _instanceExtraInitializers = [];
|
|
56
|
+
let _volume_decorators;
|
|
57
|
+
let _volume_initializers = [];
|
|
58
|
+
let _volume_extraInitializers = [];
|
|
59
|
+
let _muted_decorators;
|
|
60
|
+
let _muted_initializers = [];
|
|
61
|
+
let _muted_extraInitializers = [];
|
|
62
|
+
let _loop_decorators;
|
|
63
|
+
let _loop_initializers = [];
|
|
64
|
+
let _loop_extraInitializers = [];
|
|
65
|
+
let _play_decorators;
|
|
66
|
+
let _pause_decorators;
|
|
67
|
+
let _stop_decorators;
|
|
68
|
+
let _seek_decorators;
|
|
69
|
+
let _similarity_decorators;
|
|
70
|
+
let _similarity_initializers = [];
|
|
71
|
+
let _similarity_extraInitializers = [];
|
|
72
|
+
let _smoothness_decorators;
|
|
73
|
+
let _smoothness_initializers = [];
|
|
74
|
+
let _smoothness_extraInitializers = [];
|
|
75
|
+
let _spill_decorators;
|
|
76
|
+
let _spill_initializers = [];
|
|
77
|
+
let _spill_extraInitializers = [];
|
|
78
|
+
let _keyColor_decorators;
|
|
79
|
+
let _keyColor_initializers = [];
|
|
80
|
+
let _keyColor_extraInitializers = [];
|
|
81
|
+
let _direction_decorators;
|
|
82
|
+
let _direction_initializers = [];
|
|
83
|
+
let _direction_extraInitializers = [];
|
|
84
|
+
let _alphaFirst_decorators;
|
|
85
|
+
let _alphaFirst_initializers = [];
|
|
86
|
+
let _alphaFirst_extraInitializers = [];
|
|
87
|
+
return class BaseVideo extends _classSuper {
|
|
88
|
+
static {
|
|
89
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
90
|
+
_volume_decorators = [zUI({ type: 'proportion' }), zObserve((v, instance) => {
|
|
91
|
+
instance._gain.gain.value = v;
|
|
92
|
+
})];
|
|
93
|
+
_muted_decorators = [zUI()];
|
|
94
|
+
_loop_decorators = [zUI(), zObserve((v, instance) => {
|
|
95
|
+
instance.videoElement.loop = v;
|
|
96
|
+
})];
|
|
97
|
+
_play_decorators = [zUI()];
|
|
98
|
+
_pause_decorators = [zUI()];
|
|
99
|
+
_stop_decorators = [zUI()];
|
|
100
|
+
_seek_decorators = [zUI({ type: 'time-milliseconds' })];
|
|
101
|
+
_similarity_decorators = [zUI({ group: 'Chroma Key Transparency', type: 'proportion' })];
|
|
102
|
+
_smoothness_decorators = [zUI({ group: 'Chroma Key Transparency', type: 'proportion' })];
|
|
103
|
+
_spill_decorators = [zUI({ group: 'Chroma Key Transparency', type: 'proportion' })];
|
|
104
|
+
_keyColor_decorators = [zUI({ group: 'Chroma Key Transparency', type: 'color-norm-rgb-linear' })];
|
|
105
|
+
_direction_decorators = [zUI({ group: 'Side By Side Transparency' })];
|
|
106
|
+
_alphaFirst_decorators = [zUI({ group: 'Side By Side Transparency' })];
|
|
107
|
+
__esDecorate(this, null, _play_decorators, { kind: "method", name: "play", static: false, private: false, access: { has: obj => "play" in obj, get: obj => obj.play }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
108
|
+
__esDecorate(this, null, _pause_decorators, { kind: "method", name: "pause", static: false, private: false, access: { has: obj => "pause" in obj, get: obj => obj.pause }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
109
|
+
__esDecorate(this, null, _stop_decorators, { kind: "method", name: "stop", static: false, private: false, access: { has: obj => "stop" in obj, get: obj => obj.stop }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
110
|
+
__esDecorate(this, null, _seek_decorators, { kind: "method", name: "seek", static: false, private: false, access: { has: obj => "seek" in obj, get: obj => obj.seek }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
111
|
+
__esDecorate(null, null, _volume_decorators, { kind: "field", name: "volume", static: false, private: false, access: { has: obj => "volume" in obj, get: obj => obj.volume, set: (obj, value) => { obj.volume = value; } }, metadata: _metadata }, _volume_initializers, _volume_extraInitializers);
|
|
112
|
+
__esDecorate(null, null, _muted_decorators, { kind: "field", name: "muted", static: false, private: false, access: { has: obj => "muted" in obj, get: obj => obj.muted, set: (obj, value) => { obj.muted = value; } }, metadata: _metadata }, _muted_initializers, _muted_extraInitializers);
|
|
113
|
+
__esDecorate(null, null, _loop_decorators, { kind: "field", name: "loop", static: false, private: false, access: { has: obj => "loop" in obj, get: obj => obj.loop, set: (obj, value) => { obj.loop = value; } }, metadata: _metadata }, _loop_initializers, _loop_extraInitializers);
|
|
114
|
+
__esDecorate(null, null, _similarity_decorators, { kind: "field", name: "similarity", static: false, private: false, access: { has: obj => "similarity" in obj, get: obj => obj.similarity, set: (obj, value) => { obj.similarity = value; } }, metadata: _metadata }, _similarity_initializers, _similarity_extraInitializers);
|
|
115
|
+
__esDecorate(null, null, _smoothness_decorators, { kind: "field", name: "smoothness", static: false, private: false, access: { has: obj => "smoothness" in obj, get: obj => obj.smoothness, set: (obj, value) => { obj.smoothness = value; } }, metadata: _metadata }, _smoothness_initializers, _smoothness_extraInitializers);
|
|
116
|
+
__esDecorate(null, null, _spill_decorators, { kind: "field", name: "spill", static: false, private: false, access: { has: obj => "spill" in obj, get: obj => obj.spill, set: (obj, value) => { obj.spill = value; } }, metadata: _metadata }, _spill_initializers, _spill_extraInitializers);
|
|
117
|
+
__esDecorate(null, null, _keyColor_decorators, { kind: "field", name: "keyColor", static: false, private: false, access: { has: obj => "keyColor" in obj, get: obj => obj.keyColor, set: (obj, value) => { obj.keyColor = value; } }, metadata: _metadata }, _keyColor_initializers, _keyColor_extraInitializers);
|
|
118
|
+
__esDecorate(null, null, _direction_decorators, { kind: "field", name: "direction", static: false, private: false, access: { has: obj => "direction" in obj, get: obj => obj.direction, set: (obj, value) => { obj.direction = value; } }, metadata: _metadata }, _direction_initializers, _direction_extraInitializers);
|
|
119
|
+
__esDecorate(null, null, _alphaFirst_decorators, { kind: "field", name: "alphaFirst", static: false, private: false, access: { has: obj => "alphaFirst" in obj, get: obj => obj.alphaFirst, set: (obj, value) => { obj.alphaFirst = value; } }, metadata: _metadata }, _alphaFirst_initializers, _alphaFirst_extraInitializers);
|
|
120
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
121
|
+
}
|
|
122
|
+
constructorProps = __runInitializers(this, _instanceExtraInitializers);
|
|
123
|
+
onEnded = new Event();
|
|
124
|
+
onPause = new Event();
|
|
125
|
+
onPlay = new Event();
|
|
126
|
+
onPlaying = new Event();
|
|
127
|
+
onWaiting = new Event();
|
|
128
|
+
onError = new Event();
|
|
129
|
+
geometry;
|
|
130
|
+
material;
|
|
131
|
+
mesh;
|
|
132
|
+
texture;
|
|
133
|
+
transparent;
|
|
134
|
+
videoElement;
|
|
135
|
+
_gain;
|
|
136
|
+
/**
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
139
|
+
_hadUserEvent = false;
|
|
140
|
+
constructor(ctx, constructorProps) {
|
|
141
|
+
super(ctx, constructorProps, new THREE.Group());
|
|
142
|
+
__runInitializers(this, _alphaFirst_extraInitializers);
|
|
143
|
+
this.constructorProps = constructorProps;
|
|
144
|
+
const videoElement = document.createElement('video');
|
|
145
|
+
videoElement.crossOrigin = 'anonymous';
|
|
146
|
+
videoElement.playsInline = true;
|
|
147
|
+
videoElement.muted = true;
|
|
148
|
+
videoElement.preload = 'auto';
|
|
149
|
+
videoElement.onended = () => this.onEnded.emit(this);
|
|
150
|
+
videoElement.onpause = () => this.onPause.emit(this);
|
|
151
|
+
videoElement.onplay = () => this.onPlay.emit(this);
|
|
152
|
+
videoElement.onplaying = () => this.onPlaying.emit(this);
|
|
153
|
+
videoElement.onwaiting = () => this.onWaiting.emit(this);
|
|
154
|
+
videoElement.onerror = () => this.onError.emit(this);
|
|
155
|
+
this.geometry = constructorProps.geometry ?? new THREE.PlaneGeometry();
|
|
156
|
+
registerLoadable(ctx, new Promise((resolve, reject) => {
|
|
157
|
+
videoElement.addEventListener('canplaythrough', () => {
|
|
158
|
+
this._updateSize();
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
161
|
+
videoElement.addEventListener('error', err => {
|
|
162
|
+
console.error(err);
|
|
163
|
+
reject();
|
|
164
|
+
});
|
|
165
|
+
}));
|
|
166
|
+
const audioContextContext = ctx.get(AudioContextContext);
|
|
167
|
+
this._gain = new GainNode(audioContextContext.audioContext);
|
|
168
|
+
const audioSource = audioContextContext.audioContext.createMediaElementSource(videoElement);
|
|
169
|
+
audioSource.connect(this._gain);
|
|
170
|
+
this._gain.connect(audioContextContext.getLayer(constructorProps.audioLayer));
|
|
171
|
+
this.transparent = constructorProps.transparent ?? VideoTransparencyType.none;
|
|
172
|
+
this.videoElement = videoElement;
|
|
173
|
+
this.texture = new THREE.VideoTexture(videoElement);
|
|
174
|
+
this.texture.colorSpace = THREE.SRGBColorSpace;
|
|
175
|
+
if (this.transparent === VideoTransparencyType.chromaKey) {
|
|
176
|
+
const mat = new MeshChromaKeyMaterial();
|
|
177
|
+
this.material = mat;
|
|
178
|
+
mat.map = this.texture;
|
|
179
|
+
this.observe(this, 'similarity', v => {
|
|
180
|
+
mat.similarity = v;
|
|
181
|
+
});
|
|
182
|
+
this.observe(this, 'smoothness', v => {
|
|
183
|
+
mat.smoothness = v;
|
|
184
|
+
});
|
|
185
|
+
this.observe(this, 'spill', v => {
|
|
186
|
+
mat.spill = v;
|
|
187
|
+
});
|
|
188
|
+
this.observe(this, 'keyColor', v => {
|
|
189
|
+
mat.keyColor = [...v];
|
|
190
|
+
});
|
|
191
|
+
this.register(useOnBeforeRender(this.contextManager), () => mat.frame());
|
|
192
|
+
}
|
|
193
|
+
else if (this.transparent === VideoTransparencyType.sideBySide) {
|
|
194
|
+
const mat = new MeshSideBySideAlphaMaterial();
|
|
195
|
+
this.material = mat;
|
|
196
|
+
mat.map = this.texture;
|
|
197
|
+
this.observe(this, 'alphaFirst', v => {
|
|
198
|
+
mat.alphaFirst = v;
|
|
199
|
+
});
|
|
200
|
+
this.observe(this, 'direction', v => {
|
|
201
|
+
mat.direction = v;
|
|
202
|
+
});
|
|
203
|
+
this.register(useOnBeforeRender(this.contextManager), () => mat.frame());
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
this.material = new THREE.MeshBasicMaterial({ toneMapped: false, map: this.texture });
|
|
207
|
+
}
|
|
208
|
+
this.mesh = new THREE.Mesh(this.geometry, this.material);
|
|
209
|
+
this.element.add(this.mesh);
|
|
210
|
+
this.videoElement.addEventListener('loadeddata', this._updateSize);
|
|
211
|
+
this.videoElement.addEventListener('loadedmetadata', this._updateSize);
|
|
212
|
+
this.observe(this, 'muted', this._updateMute);
|
|
213
|
+
nextUserEvent(ctx).then(() => {
|
|
214
|
+
this._hadUserEvent = true;
|
|
215
|
+
this._updateMute();
|
|
216
|
+
});
|
|
217
|
+
if (!isDesignTime(ctx) && constructorProps.autoplay)
|
|
218
|
+
started(ctx).then(() => this.play());
|
|
219
|
+
}
|
|
220
|
+
_updateSize = () => {
|
|
37
221
|
if (this.videoElement.videoHeight === 0)
|
|
38
222
|
return;
|
|
39
223
|
let transparencyAspectFix = 1;
|
|
40
224
|
if (this.transparent === VideoTransparencyType.sideBySide) {
|
|
41
|
-
transparencyAspectFix = this.direction
|
|
225
|
+
transparencyAspectFix = this.direction === SideBySideDirection.LeftRight ? 0.5 : 2;
|
|
42
226
|
}
|
|
43
227
|
this.mesh.scale.set((transparencyAspectFix * this.videoElement.videoWidth) / this.videoElement.videoHeight, 1, 1);
|
|
44
228
|
};
|
|
45
|
-
|
|
229
|
+
_updateMute = () => {
|
|
46
230
|
if (!this.videoElement || !this._hadUserEvent)
|
|
47
231
|
return;
|
|
48
|
-
this.videoElement.muted = this.muted
|
|
232
|
+
this.videoElement.muted = this.muted;
|
|
49
233
|
};
|
|
50
234
|
/**
|
|
51
235
|
* The volume of the video, from 0 to 1.
|
|
52
|
-
* @
|
|
236
|
+
* @default 1
|
|
237
|
+
* @zui
|
|
53
238
|
* @ztype proportion
|
|
54
|
-
* @zdefault 1
|
|
55
239
|
*/
|
|
56
|
-
|
|
240
|
+
volume = __runInitializers(this, _volume_initializers, 1);
|
|
57
241
|
/**
|
|
58
242
|
* Whether the video is muted.
|
|
59
|
-
* @
|
|
60
|
-
* @zdefault false
|
|
243
|
+
* @default false
|
|
61
244
|
*/
|
|
62
|
-
|
|
245
|
+
muted = (__runInitializers(this, _volume_extraInitializers), __runInitializers(this, _muted_initializers, false));
|
|
63
246
|
/**
|
|
64
247
|
* Whether the video should loop when it reaches the end.
|
|
65
|
-
* @
|
|
66
|
-
|
|
248
|
+
* @default false
|
|
249
|
+
*/
|
|
250
|
+
loop = (__runInitializers(this, _muted_extraInitializers), __runInitializers(this, _loop_initializers, false));
|
|
251
|
+
/**
|
|
252
|
+
* Plays the video.
|
|
253
|
+
* @zui
|
|
254
|
+
*/
|
|
255
|
+
play(opts) {
|
|
256
|
+
this.videoElement.playbackRate = opts?.speed ?? 1;
|
|
257
|
+
this.videoElement.play();
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Pauses the video.
|
|
261
|
+
* @zui
|
|
262
|
+
*/
|
|
263
|
+
pause() {
|
|
264
|
+
this.videoElement.pause();
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Stops the video and resets the playback position to the beginning.
|
|
268
|
+
* @zui
|
|
67
269
|
*/
|
|
68
|
-
|
|
69
|
-
this.videoElement.
|
|
70
|
-
|
|
270
|
+
stop() {
|
|
271
|
+
this.videoElement.pause();
|
|
272
|
+
this.videoElement.currentTime = 0;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Seeks to a specified time in the video in milliseconds.
|
|
276
|
+
* @zui
|
|
277
|
+
*/
|
|
278
|
+
seek(t) {
|
|
279
|
+
this.videoElement.currentTime = t / 1000;
|
|
280
|
+
}
|
|
281
|
+
length() {
|
|
282
|
+
return isNaN(this.videoElement.duration) ? undefined : this.videoElement.duration * 1000;
|
|
283
|
+
}
|
|
284
|
+
isStalled() {
|
|
285
|
+
return this.videoElement.readyState <= 2;
|
|
286
|
+
}
|
|
71
287
|
/**
|
|
72
288
|
* The chroma key similarity value, from 0 to 1.
|
|
73
|
-
* @
|
|
289
|
+
* @default 0.05
|
|
290
|
+
* @zui
|
|
74
291
|
* @zgroup Chroma Key Transparency
|
|
75
292
|
* @ztype proportion
|
|
76
|
-
* @zdefault 0.05
|
|
77
293
|
*/
|
|
78
|
-
|
|
294
|
+
similarity = (__runInitializers(this, _loop_extraInitializers), __runInitializers(this, _similarity_initializers, 0.05));
|
|
79
295
|
/**
|
|
80
296
|
* The smoothness of the chroma key, from 0 to 1.
|
|
81
|
-
* @
|
|
297
|
+
* @default 0.08
|
|
298
|
+
* @zui
|
|
82
299
|
* @zgroup Chroma Key Transparency
|
|
83
300
|
* @ztype proportion
|
|
84
|
-
* @zdefault 0.08
|
|
85
301
|
*/
|
|
86
|
-
|
|
302
|
+
smoothness = (__runInitializers(this, _similarity_extraInitializers), __runInitializers(this, _smoothness_initializers, 0.08));
|
|
87
303
|
/**
|
|
88
304
|
* The spill of the chroma key, from 0 to 1.
|
|
89
|
-
* @
|
|
305
|
+
* @default 0.2
|
|
306
|
+
* @zui
|
|
90
307
|
* @zgroup Chroma Key Transparency
|
|
91
308
|
* @ztype proportion
|
|
92
|
-
* @zdefault 0.2
|
|
93
309
|
*/
|
|
94
|
-
|
|
310
|
+
spill = (__runInitializers(this, _smoothness_extraInitializers), __runInitializers(this, _spill_initializers, 0.2));
|
|
95
311
|
/**
|
|
96
312
|
* The key color of the chroma key, as an RGB array.
|
|
97
|
-
* @
|
|
313
|
+
* @default [0,1,0]
|
|
314
|
+
* @zui
|
|
98
315
|
* @zgroup Chroma Key Transparency
|
|
99
316
|
* @ztype color-norm-rgb-linear
|
|
100
|
-
* @zdefault [0, 1, 0]
|
|
101
317
|
*/
|
|
102
|
-
|
|
318
|
+
keyColor = (__runInitializers(this, _spill_extraInitializers), __runInitializers(this, _keyColor_initializers, [0, 1, 0]));
|
|
103
319
|
/**
|
|
104
320
|
* The direction of the side-by-side transparency.
|
|
105
|
-
* @
|
|
321
|
+
* @default "LeftRight"
|
|
322
|
+
* @zui
|
|
106
323
|
* @zgroup Side By Side Transparency
|
|
107
|
-
* @zdefault LeftRight
|
|
108
324
|
*/
|
|
109
|
-
|
|
325
|
+
direction = (__runInitializers(this, _keyColor_extraInitializers), __runInitializers(this, _direction_initializers, SideBySideDirection.LeftRight));
|
|
110
326
|
/**
|
|
111
327
|
* Whether the alpha channel is first or second in the side-by-side transparency.
|
|
112
|
-
* @
|
|
328
|
+
* @default false
|
|
329
|
+
* @zui
|
|
113
330
|
* @zgroup Side By Side Transparency
|
|
114
|
-
* @zdefault false
|
|
115
331
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
videoElement.
|
|
131
|
-
|
|
132
|
-
resolve();
|
|
133
|
-
});
|
|
134
|
-
videoElement.addEventListener('error', err => {
|
|
135
|
-
console.error(err);
|
|
136
|
-
reject();
|
|
137
|
-
});
|
|
138
|
-
}));
|
|
139
|
-
const audioContextContext = ctx.get(AudioContextContext);
|
|
140
|
-
this._gain = new GainNode(audioContextContext.audioContext);
|
|
141
|
-
const audioSource = audioContextContext.audioContext.createMediaElementSource(videoElement);
|
|
142
|
-
audioSource.connect(this._gain);
|
|
143
|
-
this._gain.connect(audioContextContext.getLayer(constructorProps.audioLayer));
|
|
144
|
-
this.transparent = constructorProps.transparent ?? VideoTransparencyType.none;
|
|
145
|
-
this.videoElement = videoElement;
|
|
146
|
-
this.texture = new THREE.VideoTexture(videoElement);
|
|
147
|
-
legacy_set_texture_encoding(this.texture, EncodingType.sRGBEncoding);
|
|
148
|
-
if (this.transparent === VideoTransparencyType.chromaKey) {
|
|
149
|
-
const mat = new MeshChromaKeyMaterial();
|
|
150
|
-
this.material = mat;
|
|
151
|
-
mat.map = this.texture;
|
|
152
|
-
this.register(this.similarity, v => (mat.similarity = v));
|
|
153
|
-
this.register(this.smoothness, v => (mat.smoothness = v));
|
|
154
|
-
this.register(this.spill, v => (mat.spill = v));
|
|
155
|
-
this.register(this.keyColor, v => (mat.keyColor = [...v]));
|
|
156
|
-
this.register(useOnBeforeRender(this.contextManager), () => mat.frame());
|
|
157
|
-
}
|
|
158
|
-
else if (this.transparent === VideoTransparencyType.sideBySide) {
|
|
159
|
-
const mat = new MeshSideBySideAlphaMaterial();
|
|
160
|
-
this.material = mat;
|
|
161
|
-
mat.map = this.texture;
|
|
162
|
-
this.register(this.alphaFirst, v => (mat.alphaFirst = v));
|
|
163
|
-
this.register(this.direction, v => (mat.direction = v));
|
|
164
|
-
this.register(useOnBeforeRender(this.contextManager), () => mat.frame());
|
|
332
|
+
alphaFirst = (__runInitializers(this, _direction_extraInitializers), __runInitializers(this, _alphaFirst_initializers, false));
|
|
333
|
+
dispose() {
|
|
334
|
+
this.geometry.dispose();
|
|
335
|
+
this.material.map?.dispose();
|
|
336
|
+
this.material.dispose();
|
|
337
|
+
this.texture.dispose();
|
|
338
|
+
this.videoElement.pause();
|
|
339
|
+
this.videoElement.onended = null;
|
|
340
|
+
this.videoElement.onpause = null;
|
|
341
|
+
this.videoElement.onplay = null;
|
|
342
|
+
this.videoElement.onplaying = null;
|
|
343
|
+
this.videoElement.onwaiting = null;
|
|
344
|
+
this.videoElement.onerror = null;
|
|
345
|
+
this.videoElement.src = '';
|
|
346
|
+
this.videoElement.srcObject = null;
|
|
347
|
+
return super.dispose();
|
|
165
348
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.mesh = new THREE.Mesh(this.geometry, this.material);
|
|
170
|
-
this.element.add(this.mesh);
|
|
171
|
-
this.videoElement.addEventListener('loadeddata', this._updateSize);
|
|
172
|
-
this.videoElement.addEventListener('loadedmetadata', this._updateSize);
|
|
173
|
-
this.register(this.muted, this._updateMute);
|
|
174
|
-
nextUserEvent(ctx).then(() => {
|
|
175
|
-
this._hadUserEvent = true;
|
|
176
|
-
this._updateMute();
|
|
177
|
-
});
|
|
178
|
-
if (!isDesignTime(ctx) && constructorProps.autoplay)
|
|
179
|
-
started(ctx).then(() => this.play());
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Plays the video.
|
|
183
|
-
* @zprop
|
|
184
|
-
* @zui
|
|
185
|
-
*/
|
|
186
|
-
play(opts) {
|
|
187
|
-
this.videoElement.playbackRate = opts?.speed ?? 1;
|
|
188
|
-
this.videoElement.play();
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Pauses the video.
|
|
192
|
-
* @zprop
|
|
193
|
-
* @zui
|
|
194
|
-
*/
|
|
195
|
-
pause() {
|
|
196
|
-
this.videoElement.pause();
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Stops the video and resets the playback position to the beginning.
|
|
200
|
-
* @zprop
|
|
201
|
-
* @zui
|
|
202
|
-
*/
|
|
203
|
-
stop() {
|
|
204
|
-
this.videoElement.pause();
|
|
205
|
-
this.videoElement.currentTime = 0;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Seeks to a specified time in the video in milliseconds.
|
|
209
|
-
* @zprop
|
|
210
|
-
* @zui
|
|
211
|
-
*/
|
|
212
|
-
seek(/** @ztype time-milliseconds */ t) {
|
|
213
|
-
this.videoElement.currentTime = t / 1000;
|
|
214
|
-
}
|
|
215
|
-
length() {
|
|
216
|
-
return isNaN(this.videoElement.duration) ? undefined : this.videoElement.duration * 1000;
|
|
217
|
-
}
|
|
218
|
-
isStalled() {
|
|
219
|
-
return this.videoElement.readyState <= 2;
|
|
220
|
-
}
|
|
221
|
-
dispose() {
|
|
222
|
-
this.geometry.dispose();
|
|
223
|
-
this.material.map?.dispose();
|
|
224
|
-
this.material.dispose();
|
|
225
|
-
this.texture.dispose();
|
|
226
|
-
this.videoElement.pause();
|
|
227
|
-
this.videoElement.onended = null;
|
|
228
|
-
this.videoElement.onpause = null;
|
|
229
|
-
this.videoElement.onplay = null;
|
|
230
|
-
this.videoElement.onplaying = null;
|
|
231
|
-
this.videoElement.onwaiting = null;
|
|
232
|
-
this.videoElement.onerror = null;
|
|
233
|
-
this.videoElement.src = '';
|
|
234
|
-
this.videoElement.srcObject = null;
|
|
235
|
-
return super.dispose();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
349
|
+
};
|
|
350
|
+
})();
|
|
351
|
+
export { BaseVideo };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { ContextManager } from '@zcomponent/core';
|
|
2
|
-
import { BaseVideo, BaseVideoConstructorProps } from '
|
|
1
|
+
import { ContextManager, ProjectFile } from '@zcomponent/core';
|
|
2
|
+
import { BaseVideo, BaseVideoConstructorProps } from './basevideo';
|
|
3
3
|
export interface VideoConstructorProps extends BaseVideoConstructorProps {
|
|
4
|
-
/**
|
|
5
|
-
* @zvalues files *.m3u8, *.mp4
|
|
4
|
+
/**
|
|
6
5
|
*/
|
|
7
|
-
source:
|
|
6
|
+
source: ProjectFile<'*.m3u8' | '*.mp4'>;
|
|
8
7
|
}
|
|
9
8
|
/**
|
|
10
9
|
*
|
|
@@ -18,12 +17,15 @@ export interface VideoConstructorProps extends BaseVideoConstructorProps {
|
|
|
18
17
|
* Root element: [THREE.Group](https://threejs.org/docs/index.html#api/en/objects/Group)
|
|
19
18
|
* @zcomponent
|
|
20
19
|
* @zicon video_library
|
|
20
|
+
* @zgroup Media
|
|
21
21
|
* @ztag three/Object3D/Video
|
|
22
22
|
* @zparents three/Object3D/Group/**
|
|
23
|
-
* @zgroup Media
|
|
24
23
|
*/
|
|
25
24
|
export declare class VideoPlayer extends BaseVideo {
|
|
26
25
|
protected constructorProps: VideoConstructorProps;
|
|
26
|
+
/**
|
|
27
|
+
* @default null
|
|
28
|
+
*/
|
|
27
29
|
private hls;
|
|
28
30
|
constructor(ctx: ContextManager, constructorProps: VideoConstructorProps);
|
|
29
31
|
load(): Promise<void>;
|
|
@@ -1,7 +1,41 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
1
35
|
// TODO- import type and dynamic import later
|
|
36
|
+
import { registerLoadable, zComponent } from '@zcomponent/core';
|
|
2
37
|
import Hls from 'hls.js';
|
|
3
|
-
import {
|
|
4
|
-
import { BaseVideo } from '../index';
|
|
38
|
+
import { BaseVideo } from './basevideo';
|
|
5
39
|
/**
|
|
6
40
|
*
|
|
7
41
|
* Manages the playback and display of a video in a 3D environment.
|
|
@@ -14,87 +48,113 @@ import { BaseVideo } from '../index';
|
|
|
14
48
|
* Root element: [THREE.Group](https://threejs.org/docs/index.html#api/en/objects/Group)
|
|
15
49
|
* @zcomponent
|
|
16
50
|
* @zicon video_library
|
|
51
|
+
* @zgroup Media
|
|
17
52
|
* @ztag three/Object3D/Video
|
|
18
53
|
* @zparents three/Object3D/Group/**
|
|
19
|
-
* @zgroup Media
|
|
20
54
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
let VideoPlayer = (() => {
|
|
56
|
+
let _classDecorators = [zComponent({
|
|
57
|
+
icon: 'video_library',
|
|
58
|
+
group: 'Media',
|
|
59
|
+
tags: ['three/Object3D/Video'],
|
|
60
|
+
parents: ['three/Object3D/Group/**'],
|
|
61
|
+
})];
|
|
62
|
+
let _classDescriptor;
|
|
63
|
+
let _classExtraInitializers = [];
|
|
64
|
+
let _classThis;
|
|
65
|
+
let _classSuper = BaseVideo;
|
|
66
|
+
var VideoPlayer = class extends _classSuper {
|
|
67
|
+
static { _classThis = this; }
|
|
68
|
+
static {
|
|
69
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
70
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
71
|
+
VideoPlayer = _classThis = _classDescriptor.value;
|
|
72
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
73
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
39
74
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
75
|
+
constructorProps;
|
|
76
|
+
/**
|
|
77
|
+
* @default null
|
|
78
|
+
*/
|
|
79
|
+
hls = null;
|
|
80
|
+
constructor(ctx, constructorProps) {
|
|
81
|
+
super(ctx, constructorProps);
|
|
82
|
+
this.constructorProps = constructorProps;
|
|
83
|
+
registerLoadable(this.contextManager, this.load());
|
|
84
|
+
}
|
|
85
|
+
async load() {
|
|
86
|
+
const isHls = this.constructorProps.source.endsWith('.m3u8');
|
|
87
|
+
if (isHls && !isIOS())
|
|
88
|
+
return this._loadHlsVideo();
|
|
89
|
+
return this._loadMp4Video();
|
|
90
|
+
}
|
|
91
|
+
async _loadHlsVideo() {
|
|
92
|
+
if (!Hls.isSupported()) {
|
|
93
|
+
// Consider adding a fallback to MP4
|
|
94
|
+
console.error('HLS is not supported in this browser.');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.hls = new Hls();
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
this.hls?.on(Hls.Events.MEDIA_ATTACHED, () => { });
|
|
100
|
+
this.hls?.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
101
|
+
resolve();
|
|
102
|
+
});
|
|
103
|
+
this.hls?.on(Hls.Events.ERROR, (event, data) => {
|
|
104
|
+
if (data.fatal) {
|
|
105
|
+
switch (data.type) {
|
|
106
|
+
case Hls.ErrorTypes.NETWORK_ERROR:
|
|
107
|
+
console.error('HLS: Fatal network error encountered, trying to recover');
|
|
108
|
+
this.hls?.startLoad();
|
|
109
|
+
break;
|
|
110
|
+
case Hls.ErrorTypes.MEDIA_ERROR:
|
|
111
|
+
console.error('HLS: Fatal media error encountered, trying to recover');
|
|
112
|
+
this.hls?.recoverMediaError();
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
console.error('HLS: Fatal error, cannot recover');
|
|
116
|
+
this.hls?.destroy();
|
|
117
|
+
reject('HLS: Fatal error, cannot recover');
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
62
120
|
}
|
|
63
|
-
}
|
|
121
|
+
});
|
|
122
|
+
this.hls?.loadSource(this.constructorProps.source);
|
|
123
|
+
this.hls?.attachMedia(this.videoElement);
|
|
64
124
|
});
|
|
65
|
-
this.hls?.loadSource(this.constructorProps.source);
|
|
66
|
-
this.hls?.attachMedia(this.videoElement);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
async _loadMp4Video() {
|
|
70
|
-
return new Promise((resolve, reject) => {
|
|
71
|
-
const onCanPlay = () => {
|
|
72
|
-
cleanup();
|
|
73
|
-
resolve();
|
|
74
|
-
};
|
|
75
|
-
const onError = e => {
|
|
76
|
-
console.error('MP4: Error loading video', e);
|
|
77
|
-
cleanup();
|
|
78
|
-
reject(new Error('MP4 video loading error'));
|
|
79
|
-
};
|
|
80
|
-
const cleanup = () => {
|
|
81
|
-
this.videoElement.removeEventListener('canplay', onCanPlay);
|
|
82
|
-
this.videoElement.removeEventListener('error', onError);
|
|
83
|
-
};
|
|
84
|
-
this.videoElement.addEventListener('canplay', onCanPlay);
|
|
85
|
-
this.videoElement.addEventListener('error', onError);
|
|
86
|
-
this.videoElement.src = this.constructorProps.source;
|
|
87
|
-
this.videoElement.load();
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
dispose() {
|
|
91
|
-
if (this.hls) {
|
|
92
|
-
this.hls.destroy();
|
|
93
|
-
this.hls = null;
|
|
94
125
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
126
|
+
async _loadMp4Video() {
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
const onCanPlay = () => {
|
|
129
|
+
cleanup();
|
|
130
|
+
resolve();
|
|
131
|
+
};
|
|
132
|
+
const onError = e => {
|
|
133
|
+
console.error('MP4: Error loading video', e);
|
|
134
|
+
cleanup();
|
|
135
|
+
reject(new Error('MP4 video loading error'));
|
|
136
|
+
};
|
|
137
|
+
const cleanup = () => {
|
|
138
|
+
this.videoElement.removeEventListener('canplay', onCanPlay);
|
|
139
|
+
this.videoElement.removeEventListener('error', onError);
|
|
140
|
+
};
|
|
141
|
+
this.videoElement.addEventListener('canplay', onCanPlay);
|
|
142
|
+
this.videoElement.addEventListener('error', onError);
|
|
143
|
+
this.videoElement.src = this.constructorProps.source;
|
|
144
|
+
this.videoElement.load();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
dispose() {
|
|
148
|
+
if (this.hls) {
|
|
149
|
+
this.hls.destroy();
|
|
150
|
+
this.hls = null;
|
|
151
|
+
}
|
|
152
|
+
return super.dispose();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
return VideoPlayer = _classThis;
|
|
156
|
+
})();
|
|
157
|
+
export { VideoPlayer };
|
|
98
158
|
function isIOS() {
|
|
99
159
|
return ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator.platform) || (navigator.userAgent.includes('Mac') && 'ontouchend' in document);
|
|
100
160
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { BaseVideo, BaseVideoConstructorProps } from './components/basevideo';
|
|
2
|
-
export {
|
|
3
|
-
export { VideoConstructorProps } from './components/videoplayer';
|
|
4
|
-
export { VideoPlayer } from './components/videoplayer';
|
|
1
|
+
export { BaseVideo, BaseVideoConstructorProps, VideoTransparencyType } from './components/basevideo';
|
|
2
|
+
export { VideoConstructorProps, VideoPlayer } from './components/videoplayer';
|
package/lib/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zcomponent/three-video-player",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.2",
|
|
4
4
|
"description": "HLS & MP4 Player for Mattercraft",
|
|
5
5
|
"author": "Zappar Limited",
|
|
6
6
|
"license": "Proprietary",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"types": "index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"development": "./src/index.ts",
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"default": "./index.js"
|
|
14
|
+
},
|
|
15
|
+
"./*": {
|
|
16
|
+
"development": "./src/*.ts",
|
|
17
|
+
"types": "./lib/*.d.ts",
|
|
18
|
+
"default": "./lib/*.js"
|
|
19
|
+
},
|
|
20
|
+
"./lib/*": {
|
|
21
|
+
"development": "./src/*.ts",
|
|
22
|
+
"types": "./lib/*.d.ts",
|
|
23
|
+
"default": "./lib/*.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
9
26
|
"zexports": [
|
|
10
27
|
"./lib/**/*"
|
|
11
28
|
],
|
|
@@ -19,7 +36,7 @@
|
|
|
19
36
|
"public/**/*"
|
|
20
37
|
],
|
|
21
38
|
"scripts": {
|
|
22
|
-
"build": "rm -rf lib &&
|
|
39
|
+
"build": "rm -rf lib && tspc && tsc-alias",
|
|
23
40
|
"watch": "tsc -w",
|
|
24
41
|
"docs": "typedoc --out docs",
|
|
25
42
|
"predocs": "npm run ctix",
|
|
@@ -29,12 +46,12 @@
|
|
|
29
46
|
"hls.js": "1.5.x"
|
|
30
47
|
},
|
|
31
48
|
"devDependencies": {
|
|
32
|
-
"@zcomponent/three": "
|
|
49
|
+
"@zcomponent/three": "2.0.0-alpha.2"
|
|
33
50
|
},
|
|
34
51
|
"peerDependencies": {
|
|
35
52
|
"@zcomponent/three": "*",
|
|
36
53
|
"@zcomponent/core": "*",
|
|
37
|
-
"three": "0.
|
|
54
|
+
"three": "0.175.0 - 0.184.0"
|
|
38
55
|
},
|
|
39
56
|
"keywords": [],
|
|
40
57
|
"release": {
|