@realsee/vreo 2.6.4-alpha.2 → 2.6.4-alpha.4

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.
@@ -5,7 +5,7 @@ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try {
5
5
  import * as THREE from 'three';
6
6
  export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
7
7
  var videoElement = _ref.videoElement,
8
- canPlay = _ref.canPlay;
8
+ mediaManager = _ref.mediaManager;
9
9
  var listeners = [];
10
10
  var on = function on(name, callback) {
11
11
  listeners.push(function () {
@@ -23,62 +23,115 @@ export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
23
23
  enabled: false,
24
24
  videoElement: videoElement
25
25
  };
26
+ var session;
27
+ var output;
28
+ var removeReady;
29
+ var stop = function stop() {
30
+ var _removeReady;
31
+ ++generation;
32
+ (_removeReady = removeReady) === null || _removeReady === void 0 || _removeReady();
33
+ removeReady = undefined;
34
+ if (output) {
35
+ output.muted = true;
36
+ output.pause();
37
+ }
38
+ output = undefined;
39
+ session = undefined;
40
+ state.enabled = false;
41
+ state.videoMeshes.forEach(function (mesh) {
42
+ mesh.geometry.dispose();
43
+ mesh.material.dispose();
44
+ five.scene.remove(mesh);
45
+ });
46
+ state.videoMeshes = [];
47
+ five.needsRender = true;
48
+ };
49
+ var controller = mediaManager === null || mediaManager === void 0 ? void 0 : mediaManager.createController({
50
+ label: 'vreo-model-video',
51
+ onCancel: stop
52
+ });
53
+ var bind = function bind(userAction, audible) {
54
+ var _state$videoTexture, _controller$begin;
55
+ var element = (_state$videoTexture = state.videoTexture) === null || _state$videoTexture === void 0 ? void 0 : _state$videoTexture.image;
56
+ if (!element) return undefined;
57
+ var next = (_controller$begin = controller === null || controller === void 0 ? void 0 : controller.begin({
58
+ userAction: userAction,
59
+ audible: audible
60
+ })) !== null && _controller$begin !== void 0 ? _controller$begin : undefined;
61
+ if (controller && !next) return undefined;
62
+ session = next;
63
+ return output = next ? next.bind(element) : element;
64
+ };
26
65
  var setMuted = function setMuted(muted) {
27
- if (state.videoTexture) {
28
- if (!muted && canPlay && !canPlay()) return;
29
- state.videoTexture.image.muted = muted;
30
- if (state.enabled && (!canPlay || canPlay())) void state.videoTexture.image.play();
66
+ var userAction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
67
+ var wasEnabled = state.enabled;
68
+ var media = !muted ? bind(userAction, true) : output;
69
+ if (!media) return;
70
+ media.muted = muted;
71
+ if (wasEnabled && !state.enabled) {
72
+ state.enabled = true;
73
+ state.videoMeshes = createPanoVideoMeshes();
74
+ state.videoMeshes.forEach(function (mesh) {
75
+ return five.scene.add(mesh);
76
+ });
31
77
  }
78
+ var run = session;
79
+ var current = generation;
80
+ if (state.enabled) void media.play().catch(function (error) {
81
+ if (current === generation && !(run !== null && run !== void 0 && run.signal.aborted)) {
82
+ disable();
83
+ console.error(error);
84
+ }
85
+ });
32
86
  };
33
87
  var getMuted = function getMuted() {
34
- if (state.videoTexture) return state.videoTexture.image.muted;else return true;
88
+ var _output$muted, _output;
89
+ return (_output$muted = (_output = output) === null || _output === void 0 ? void 0 : _output.muted) !== null && _output$muted !== void 0 ? _output$muted : true;
35
90
  };
36
91
  var enable = function enable() {
37
- if (disposed || state.enabled || canPlay && !canPlay()) return;
38
- if (!state.videoTexture) return;
92
+ if (disposed || state.enabled || !state.videoTexture) return;
93
+ var media = bind(false, false);
94
+ if (!media) return;
95
+ var current = generation;
96
+ var run = session;
97
+ var element = state.videoTexture.image;
98
+ var valid = function valid() {
99
+ return current === generation && !disposed && state.enabled && !(run !== null && run !== void 0 && run.signal.aborted);
100
+ };
39
101
  state.enabled = true;
40
102
  state.videoMeshes = createPanoVideoMeshes();
41
103
  state.videoMeshes.forEach(function (mesh) {
42
104
  return five.scene.add(mesh);
43
105
  });
44
- var play = function play() {
45
- if (!state.videoTexture || !state.enabled || canPlay && !canPlay()) return;
46
- var _timeupdate = function timeupdate() {
47
- var _state$videoTexture;
48
- if (!state.videoTexture) return;
49
- (_state$videoTexture = state.videoTexture) === null || _state$videoTexture === void 0 || _state$videoTexture.image.removeEventListener('timeupdate', _timeupdate);
50
- state.videoTextureEnabled = true;
51
- state.videoMeshes.forEach(function (mesh) {
52
- if (mesh.material.map !== state.videoTexture) mesh.material.map = state.videoTexture;
53
- });
54
- five.needsRender = true;
55
- };
56
- state.videoTexture.image.addEventListener('timeupdate', _timeupdate);
57
- if (state.videoTexture && state.videoMeshes.length) {
58
- state.videoTexture.image.play();
59
- }
106
+ var _timeupdate = function timeupdate() {
107
+ element.removeEventListener('timeupdate', _timeupdate);
108
+ if (!valid()) return;
109
+ state.videoTextureEnabled = true;
110
+ state.videoMeshes.forEach(function (mesh) {
111
+ mesh.material.map = state.videoTexture;
112
+ });
113
+ five.needsRender = true;
60
114
  };
61
- if (five.model.loaded) play();else {
62
- return five.once('modelLoaded', function () {
63
- return play();
115
+ var _play = function play() {
116
+ five.off('modelLoaded', _play);
117
+ if (!valid()) return;
118
+ element.addEventListener('timeupdate', _timeupdate);
119
+ void media.play().catch(function (error) {
120
+ if (valid()) {
121
+ disable();
122
+ console.error(error);
123
+ }
64
124
  });
65
- }
125
+ };
126
+ removeReady = function removeReady() {
127
+ five.off('modelLoaded', _play);
128
+ element.removeEventListener('timeupdate', _timeupdate);
129
+ };
130
+ if (five.model.loaded) _play();else five.on('modelLoaded', _play);
66
131
  };
67
132
  var disable = function disable() {
68
- if (state.videoTexture) {
69
- state.videoTexture.image.muted = true;
70
- state.videoTexture.image.pause();
71
- }
72
- if (!state.enabled) return;
73
- state.enabled = false;
74
- state.videoMeshes.forEach(function (mesh) {
75
- mesh.geometry.dispose();
76
- mesh.material.dispose();
77
- five.scene.remove(mesh);
78
- if (state.videoTexture) state.videoTexture.image.pause();
79
- });
80
- state.videoMeshes = [];
81
- five.needsRender = true;
133
+ controller === null || controller === void 0 || controller.cancel();
134
+ stop();
82
135
  };
83
136
  var createPanoVideoMeshes = function createPanoVideoMeshes() {
84
137
  return state.rectPoints.map(function (points, index) {
@@ -131,15 +184,22 @@ export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
131
184
  return texture;
132
185
  };
133
186
  var getVideoTexture = function getVideoTexture(source, video) {
187
+ var valid = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {
188
+ return true;
189
+ };
134
190
  return new Promise(function (resolve, reject) {
135
191
  var xhr = new XMLHttpRequest();
136
192
  xhr.onreadystatechange = function () {
137
193
  if (xhr.readyState == 4) {
194
+ if (!valid()) {
195
+ reject(new DOMException('Playback cancelled', 'AbortError'));
196
+ return;
197
+ }
138
198
  if (xhr.status == 200) {
139
199
  var url = window.URL || window.webkitURL;
140
200
  video = video || document.createElement('video');
141
201
  video.crossOrigin = 'anonymous';
142
- video.autoplay = true;
202
+ video.autoplay = false;
143
203
  video.muted = true;
144
204
  video.loop = true;
145
205
  video.playsInline = true;
@@ -186,7 +246,9 @@ export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
186
246
  state.videoElement = videoElement;
187
247
  }
188
248
  _context.n = 1;
189
- return getVideoTexture(state.videoSource, state.videoElement);
249
+ return getVideoTexture(state.videoSource, state.videoElement, function () {
250
+ return !disposed && current === generation;
251
+ });
190
252
  case 1:
191
253
  texture = _context.v;
192
254
  if (!(disposed || current !== generation)) {
@@ -224,7 +286,7 @@ export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
224
286
  _raycaster$intersectO2 = _slicedToArray(_raycaster$intersectO, 1),
225
287
  intersect = _raycaster$intersectO2[0];
226
288
  if (!!intersect && /^video/.test(intersect.object.name)) {
227
- if (state.videoTexture) setMuted(!state.videoTexture.image.muted);
289
+ if (state.videoTexture) setMuted(!state.videoTexture.image.muted, true);
228
290
  return false;
229
291
  }
230
292
  });
@@ -266,6 +328,7 @@ export var ModelTVVideoPlugin = function ModelTVVideoPlugin(five, _ref) {
266
328
  disposed = true;
267
329
  ++generation;
268
330
  disable();
331
+ controller === null || controller === void 0 || controller.dispose();
269
332
  listeners.splice(0).forEach(function (remove) {
270
333
  return remove();
271
334
  });
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Player } from './Player';
2
- export type { AudioIntent, AudioStopReason, AudioLease, AudioSource, AudioFocusHost } from './Player/AudioFocus';
2
+ export type { PlaybackManager, PlaybackController, PlaybackSession, MediaOperations } from './Player/playback-types';
@@ -107,8 +107,9 @@ var IAudio = /*#__PURE__*/function (_Audio) {
107
107
  _defineProperty(_this, "realSrc", '');
108
108
  _defineProperty(_this, "inited", false);
109
109
  _this.realSrc = src !== null && src !== void 0 ? src : '';
110
+ _this.muted = true;
110
111
  _superPropGet((_this, IAudio), "addEventListener", _this, 3)(['ended', function () {
111
- _this.src = '';
112
+ if (_this.src === blankAudioSrc) _this.src = '';
112
113
  }]);
113
114
  var init = function init() {
114
115
  return initAudio(_this);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realsee/vreo",
3
- "version": "2.6.4-alpha.2",
3
+ "version": "2.6.4-alpha.4",
4
4
  "type": "module",
5
5
  "description": "Vreo (VR Video 缩写) 是基于如视三维渲染引擎 Five 和 用户界面构建库 React 实现的如视 3D 空间剧本播放器。",
6
6
  "keywords": [
@@ -79,7 +79,7 @@
79
79
  "test:audio-focus": "node --test test/audio-focus.test.mjs"
80
80
  },
81
81
  "peerDependencies": {
82
- "@realsee/dnalogel": "3.81.10-alpha.0",
82
+ "@realsee/dnalogel": "3.81.10-alpha.2",
83
83
  "@realsee/five": "^6.4.0-alpha.1",
84
84
  "react": "^18.0.0",
85
85
  "react-dom": "^18.0.0",
@@ -92,7 +92,7 @@
92
92
  "@babel/preset-env": "^7.16.4",
93
93
  "@babel/preset-react": "^7.16.0",
94
94
  "@babel/preset-typescript": "^7.16.0",
95
- "@realsee/dnalogel": "3.81.10-alpha.0",
95
+ "@realsee/dnalogel": "3.81.10-alpha.2",
96
96
  "@realsee/five": "^6.4.0-alpha.38",
97
97
  "@tweenjs/tween.js": "18.6.4",
98
98
  "@types/node": "^18.11.17",
@@ -1,36 +0,0 @@
1
- export type AudioIntent = 'user' | 'auto';
2
- export type AudioStopReason = 'preempted' | 'paused' | 'closed' | 'replaced' | 'disposed';
3
- export interface AudioLease {
4
- readonly signal: AbortSignal;
5
- isCurrent(): boolean;
6
- release(): void;
7
- }
8
- export interface AudioSource {
9
- acquire(intent: AudioIntent): AudioLease | null;
10
- cancel(reason: AudioStopReason): void;
11
- dispose(): void;
12
- }
13
- export interface AudioFocusHost {
14
- register(options: {
15
- label: string;
16
- stop(reason: AudioStopReason): void;
17
- }): AudioSource;
18
- }
19
- /** One narration owns the outer lease; member tracks never compete with it. */
20
- export declare class NarrationAudioFocus {
21
- private onStop;
22
- private disposed;
23
- private source?;
24
- private lease?;
25
- private task?;
26
- private members;
27
- constructor(host: AudioFocusHost | undefined, onStop: () => void);
28
- get active(): boolean;
29
- capture(): () => boolean;
30
- acquire(intent: AudioIntent): boolean;
31
- add(stop: (reason: AudioStopReason) => void): () => void;
32
- stop(reason: AudioStopReason): void;
33
- cancel(reason: AudioStopReason): void;
34
- dispose(): void;
35
- readonly host: AudioFocusHost;
36
- }
@@ -1,139 +0,0 @@
1
- import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
2
- import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
3
- import _createClass from "@babel/runtime/helpers/esm/createClass";
4
- import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5
- /** One narration owns the outer lease; member tracks never compete with it. */
6
- export var NarrationAudioFocus = /*#__PURE__*/function () {
7
- function NarrationAudioFocus(host, onStop) {
8
- var _this = this;
9
- _classCallCheck(this, NarrationAudioFocus);
10
- _defineProperty(this, "disposed", false);
11
- _defineProperty(this, "members", new Set());
12
- _defineProperty(this, "host", {
13
- register: function register(_ref) {
14
- var stop = _ref.stop;
15
- var disposed = false;
16
- var child;
17
- var cancel = function cancel(reason) {
18
- var _child;
19
- (_child = child) === null || _child === void 0 || _child.abort();
20
- child = undefined;
21
- stop(reason);
22
- };
23
- var remove = _this.add(cancel);
24
- return {
25
- acquire: function acquire() {
26
- var _child2;
27
- if (disposed || !_this.active) return null;
28
- (_child2 = child) === null || _child2 === void 0 || _child2.abort();
29
- var current = child = new AbortController();
30
- var valid = _this.capture();
31
- return {
32
- signal: current.signal,
33
- isCurrent: function isCurrent() {
34
- return valid() && child === current && !current.signal.aborted;
35
- },
36
- release: function release() {
37
- if (child === current) {
38
- current.abort();
39
- child = undefined;
40
- }
41
- }
42
- };
43
- },
44
- cancel: cancel,
45
- dispose: function dispose() {
46
- if (disposed) return;
47
- disposed = true;
48
- cancel('disposed');
49
- remove();
50
- }
51
- };
52
- }
53
- });
54
- this.onStop = onStop;
55
- this.source = host === null || host === void 0 ? void 0 : host.register({
56
- label: 'vreo',
57
- stop: function stop(reason) {
58
- return _this.stop(reason);
59
- }
60
- });
61
- }
62
- return _createClass(NarrationAudioFocus, [{
63
- key: "active",
64
- get: function get() {
65
- var _this$lease;
66
- return !!this.task && !this.task.signal.aborted && (!this.source || !!((_this$lease = this.lease) !== null && _this$lease !== void 0 && _this$lease.isCurrent()));
67
- }
68
- }, {
69
- key: "capture",
70
- value: function capture() {
71
- var _this2 = this;
72
- var task = this.task;
73
- return function () {
74
- return !!task && task === _this2.task && _this2.active;
75
- };
76
- }
77
- }, {
78
- key: "acquire",
79
- value: function acquire(intent) {
80
- var _this$source;
81
- if (this.disposed) return false;
82
- if (this.active) return true;
83
- var lease = (_this$source = this.source) === null || _this$source === void 0 ? void 0 : _this$source.acquire(intent);
84
- if (this.source && !lease) return false;
85
- this.lease = lease !== null && lease !== void 0 ? lease : undefined;
86
- this.task = new AbortController();
87
- return true;
88
- }
89
- }, {
90
- key: "add",
91
- value: function add(stop) {
92
- var _this3 = this;
93
- this.members.add(stop);
94
- return function () {
95
- _this3.members.delete(stop);
96
- };
97
- }
98
- }, {
99
- key: "stop",
100
- value: function stop(reason) {
101
- var _this$task;
102
- (_this$task = this.task) === null || _this$task === void 0 || _this$task.abort();
103
- this.task = undefined;
104
- var errors = [];
105
- try {
106
- this.onStop();
107
- } catch (error) {
108
- errors.push(error);
109
- }
110
- for (var _i = 0, _arr = _toConsumableArray(this.members); _i < _arr.length; _i++) {
111
- var _stop = _arr[_i];
112
- try {
113
- _stop(reason);
114
- } catch (error) {
115
- errors.push(error);
116
- }
117
- }
118
- if (errors.length) throw errors[0];
119
- }
120
- }, {
121
- key: "cancel",
122
- value: function cancel(reason) {
123
- var _this$source2;
124
- this.stop(reason);
125
- (_this$source2 = this.source) === null || _this$source2 === void 0 || _this$source2.cancel(reason);
126
- this.lease = undefined;
127
- }
128
- }, {
129
- key: "dispose",
130
- value: function dispose() {
131
- var _this$source3;
132
- if (this.disposed) return;
133
- this.disposed = true;
134
- this.cancel('disposed');
135
- (_this$source3 = this.source) === null || _this$source3 === void 0 || _this$source3.dispose();
136
- this.members.clear();
137
- }
138
- }]);
139
- }();