|
@@ -5,7 +5,7 @@
|
5
|
5
|
* https://github.com/alemart/martins-js
|
6
|
6
|
*
|
7
|
7
|
* @license AGPL-3.0-only
|
8
|
|
- * Date: 2024-01-10T13:47:03.478Z
|
|
8
|
+ * Date: 2024-01-23T23:03:16.650Z
|
9
|
9
|
*/
|
10
|
10
|
(function webpackUniversalModuleDefinition(root, factory) {
|
11
|
11
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
@@ -26913,7 +26913,7 @@ class TrackerFactory {
|
26913
|
26913
|
}
|
26914
|
26914
|
}
|
26915
|
26915
|
|
26916
|
|
-;// CONCATENATED MODULE: ./src/sources/media-source.ts
|
|
26916
|
+;// CONCATENATED MODULE: ./src/sources/video-source.ts
|
26917
|
26917
|
/*
|
26918
|
26918
|
* MARTINS.js Free Edition
|
26919
|
26919
|
* GPU-accelerated Augmented Reality for the web
|
|
@@ -26932,22 +26932,23 @@ class TrackerFactory {
|
26932
|
26932
|
* You should have received a copy of the GNU Affero General Public License
|
26933
|
26933
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
26934
|
26934
|
*
|
26935
|
|
- * media-source.ts
|
26936
|
|
- * SpeedyMedia-based source of data
|
|
26935
|
+ * video-source.ts
|
|
26936
|
+ * HTMLVideoElement-based source of data
|
26937
|
26937
|
*/
|
26938
|
26938
|
|
26939
|
26939
|
|
26940
|
26940
|
|
26941
|
26941
|
/**
|
26942
|
|
- * SpeedyMedia-based source of data
|
|
26942
|
+ * HTMLVideoElement-based source of data
|
26943
|
26943
|
*/
|
26944
|
|
-class MediaSource {
|
|
26944
|
+class VideoSource {
|
26945
|
26945
|
/**
|
26946
|
26946
|
* Constructor
|
26947
|
26947
|
*/
|
26948
|
|
- constructor(source) {
|
|
26948
|
+ constructor(video) {
|
|
26949
|
+ Utils.assert(video instanceof HTMLVideoElement, 'Expected a video element');
|
|
26950
|
+ this._video = video;
|
26949
|
26951
|
this._media = null;
|
26950
|
|
- this._source = source;
|
26951
|
26952
|
}
|
26952
|
26953
|
/**
|
26953
|
26954
|
* A type-identifier of the source of data
|
|
@@ -26966,13 +26967,25 @@ class MediaSource {
|
26966
|
26967
|
return this._media;
|
26967
|
26968
|
}
|
26968
|
26969
|
/**
|
|
26970
|
+ * Stats related to this source of data
|
|
26971
|
+ * @internal
|
|
26972
|
+ */
|
|
26973
|
+ get _stats() {
|
|
26974
|
+ const media = this._media;
|
|
26975
|
+ if (media != null)
|
|
26976
|
+ return `${media.width}x${media.height} video`;
|
|
26977
|
+ else
|
|
26978
|
+ return 'uninitialized video';
|
|
26979
|
+ }
|
|
26980
|
+ /**
|
26969
|
26981
|
* Initialize this source of data
|
26970
|
26982
|
* @returns a promise that resolves as soon as this source of data is initialized
|
26971
|
26983
|
* @internal
|
26972
|
26984
|
*/
|
26973
|
26985
|
_init() {
|
26974
|
|
- return speedy_vision_default().load(this._source).then(media => {
|
26975
|
|
- Utils.log(`Source of data is ${media.width}x${media.height}`);
|
|
26986
|
+ this._video.setAttribute('playsinline', '');
|
|
26987
|
+ return speedy_vision_default().load(this._video).then(media => {
|
|
26988
|
+ Utils.log(`Source of data is a ${media.width}x${media.height} ${this._type}`);
|
26976
|
26989
|
this._media = media;
|
26977
|
26990
|
});
|
26978
|
26991
|
}
|
|
@@ -26987,19 +27000,9 @@ class MediaSource {
|
26987
|
27000
|
this._media = null;
|
26988
|
27001
|
return speedy_vision_default().Promise.resolve();
|
26989
|
27002
|
}
|
26990
|
|
- /**
|
26991
|
|
- * A string featuring the size of the media, in pixels
|
26992
|
|
- */
|
26993
|
|
- get _size() {
|
26994
|
|
- const media = this._media;
|
26995
|
|
- if (media != null)
|
26996
|
|
- return `${media.width}x${media.height}`;
|
26997
|
|
- else
|
26998
|
|
- return '-';
|
26999
|
|
- }
|
27000
|
27003
|
}
|
27001
|
27004
|
|
27002
|
|
-;// CONCATENATED MODULE: ./src/sources/video-source.ts
|
|
27005
|
+;// CONCATENATED MODULE: ./src/sources/canvas-source.ts
|
27003
|
27006
|
/*
|
27004
|
27007
|
* MARTINS.js Free Edition
|
27005
|
27008
|
* GPU-accelerated Augmented Reality for the web
|
|
@@ -27018,72 +27021,72 @@ class MediaSource {
|
27018
|
27021
|
* You should have received a copy of the GNU Affero General Public License
|
27019
|
27022
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
27020
|
27023
|
*
|
27021
|
|
- * video-source.ts
|
27022
|
|
- * <video>-based source of data
|
|
27024
|
+ * canvas-source.ts
|
|
27025
|
+ * HTMLCanvasElement-based source of data
|
27023
|
27026
|
*/
|
27024
|
27027
|
|
27025
|
27028
|
|
|
27029
|
+
|
27026
|
27030
|
/**
|
27027
|
|
- * <video>-based source of data
|
|
27031
|
+ * HTMLCanvasElement-based source of data
|
27028
|
27032
|
*/
|
27029
|
|
-class VideoSource extends MediaSource {
|
|
27033
|
+class CanvasSource {
|
27030
|
27034
|
/**
|
27031
|
27035
|
* Constructor
|
27032
|
27036
|
*/
|
27033
|
|
- constructor(video) {
|
27034
|
|
- Utils.assert(video instanceof HTMLVideoElement, 'Expected a video element');
|
27035
|
|
- super(video);
|
|
27037
|
+ constructor(canvas) {
|
|
27038
|
+ Utils.assert(canvas instanceof HTMLCanvasElement, 'Expected a canvas element');
|
|
27039
|
+ this._canvas = canvas;
|
|
27040
|
+ this._media = null;
|
27036
|
27041
|
}
|
27037
|
27042
|
/**
|
27038
|
|
- * Stats related to this source of data
|
|
27043
|
+ * A type-identifier of the source of data
|
27039
|
27044
|
* @internal
|
27040
|
27045
|
*/
|
27041
|
|
- get _stats() {
|
27042
|
|
- return `${this._size} video`;
|
|
27046
|
+ get _type() {
|
|
27047
|
+ return 'canvas';
|
27043
|
27048
|
}
|
27044
|
|
-}
|
27045
|
|
-
|
27046
|
|
-;// CONCATENATED MODULE: ./src/sources/canvas-source.ts
|
27047
|
|
-/*
|
27048
|
|
- * MARTINS.js Free Edition
|
27049
|
|
- * GPU-accelerated Augmented Reality for the web
|
27050
|
|
- * Copyright (C) 2022 Alexandre Martins <alemartf(at)gmail.com>
|
27051
|
|
- * https://github.com/alemart/martins-js
|
27052
|
|
- *
|
27053
|
|
- * This program is free software: you can redistribute it and/or modify
|
27054
|
|
- * it under the terms of the GNU Affero General Public License version 3
|
27055
|
|
- * as published by the Free Software Foundation.
|
27056
|
|
- *
|
27057
|
|
- * This program is distributed in the hope that it will be useful,
|
27058
|
|
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
27059
|
|
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
27060
|
|
- * GNU Affero General Public License for more details.
|
27061
|
|
- *
|
27062
|
|
- * You should have received a copy of the GNU Affero General Public License
|
27063
|
|
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
27064
|
|
- *
|
27065
|
|
- * canvas-source.ts
|
27066
|
|
- * <canvas>-based source of data
|
27067
|
|
- */
|
27068
|
|
-
|
27069
|
|
-
|
27070
|
|
-/**
|
27071
|
|
- * <canvas>-based source of data
|
27072
|
|
- */
|
27073
|
|
-class CanvasSource extends MediaSource {
|
27074
|
27049
|
/**
|
27075
|
|
- * Constructor
|
|
27050
|
+ * Get media
|
|
27051
|
+ * @internal
|
27076
|
27052
|
*/
|
27077
|
|
- constructor(canvas) {
|
27078
|
|
- Utils.assert(canvas instanceof HTMLCanvasElement, 'Expected a canvas element');
|
27079
|
|
- super(canvas);
|
|
27053
|
+ get _data() {
|
|
27054
|
+ if (this._media == null)
|
|
27055
|
+ throw new IllegalOperationError(`The media of the source of data isn't loaded`);
|
|
27056
|
+ return this._media;
|
27080
|
27057
|
}
|
27081
|
27058
|
/**
|
27082
|
27059
|
* Stats related to this source of data
|
27083
|
27060
|
* @internal
|
27084
|
27061
|
*/
|
27085
|
27062
|
get _stats() {
|
27086
|
|
- return `${this._size} canvas`;
|
|
27063
|
+ const media = this._media;
|
|
27064
|
+ if (media != null)
|
|
27065
|
+ return `${media.width}x${media.height} canvas`;
|
|
27066
|
+ else
|
|
27067
|
+ return 'uninitialized canvas';
|
|
27068
|
+ }
|
|
27069
|
+ /**
|
|
27070
|
+ * Initialize this source of data
|
|
27071
|
+ * @returns a promise that resolves as soon as this source of data is initialized
|
|
27072
|
+ * @internal
|
|
27073
|
+ */
|
|
27074
|
+ _init() {
|
|
27075
|
+ return speedy_vision_default().load(this._canvas).then(media => {
|
|
27076
|
+ Utils.log(`Source of data is a ${media.width}x${media.height} ${this._type}`);
|
|
27077
|
+ this._media = media;
|
|
27078
|
+ });
|
|
27079
|
+ }
|
|
27080
|
+ /**
|
|
27081
|
+ * Release this source of data
|
|
27082
|
+ * @returns a promise that resolves as soon as this source of data is released
|
|
27083
|
+ * @internal
|
|
27084
|
+ */
|
|
27085
|
+ _release() {
|
|
27086
|
+ if (this._media)
|
|
27087
|
+ this._media.release();
|
|
27088
|
+ this._media = null;
|
|
27089
|
+ return speedy_vision_default().Promise.resolve();
|
27087
|
27090
|
}
|
27088
|
27091
|
}
|
27089
|
27092
|
|
|
@@ -27129,7 +27132,7 @@ class CameraSource extends VideoSource {
|
27129
|
27132
|
constructor(options) {
|
27130
|
27133
|
const video = document.createElement('video');
|
27131
|
27134
|
super(video);
|
27132
|
|
- this._video = video;
|
|
27135
|
+ this._cameraVideo = video;
|
27133
|
27136
|
this._options = Object.assign({}, DEFAULT_CAMERA_OPTIONS, options);
|
27134
|
27137
|
}
|
27135
|
27138
|
/**
|
|
@@ -27139,13 +27142,6 @@ class CameraSource extends VideoSource {
|
27139
|
27142
|
return this._options.resolution;
|
27140
|
27143
|
}
|
27141
|
27144
|
/**
|
27142
|
|
- * Stats related to this source of data
|
27143
|
|
- * @internal
|
27144
|
|
- */
|
27145
|
|
- get _stats() {
|
27146
|
|
- return `${this._size} webcam`;
|
27147
|
|
- }
|
27148
|
|
- /**
|
27149
|
27145
|
* Initialize this source of data
|
27150
|
27146
|
* @returns a promise that resolves as soon as this source of data is initialized
|
27151
|
27147
|
* @internal
|
|
@@ -27165,14 +27161,16 @@ class CameraSource extends VideoSource {
|
27165
|
27161
|
// load camera stream
|
27166
|
27162
|
return new (speedy_vision_default()).Promise((resolve, reject) => {
|
27167
|
27163
|
navigator.mediaDevices.getUserMedia(constraints).then(stream => {
|
27168
|
|
- const video = this._video;
|
|
27164
|
+ const video = this._cameraVideo;
|
27169
|
27165
|
video.onloadedmetadata = () => {
|
27170
|
27166
|
video.play();
|
27171
|
27167
|
Utils.log('Access to the webcam has been granted.');
|
27172
|
27168
|
resolve(video);
|
27173
|
27169
|
};
|
|
27170
|
+ video.setAttribute('playsinline', '');
|
|
27171
|
+ video.setAttribute('autoplay', '');
|
|
27172
|
+ video.setAttribute('muted', '');
|
27174
|
27173
|
video.srcObject = stream;
|
27175
|
|
- video.muted = true;
|
27176
|
27174
|
}).catch(err => {
|
27177
|
27175
|
reject(new AccessDeniedError('Please give access to the webcam and reload the page.', err));
|
27178
|
27176
|
});
|
|
@@ -27184,12 +27182,12 @@ class CameraSource extends VideoSource {
|
27184
|
27182
|
* @internal
|
27185
|
27183
|
*/
|
27186
|
27184
|
_release() {
|
27187
|
|
- const stream = this._video.srcObject;
|
|
27185
|
+ const stream = this._cameraVideo.srcObject;
|
27188
|
27186
|
const tracks = stream.getTracks();
|
27189
|
27187
|
// stop camera feed
|
27190
|
27188
|
tracks.forEach(track => track.stop());
|
27191
|
|
- this._video.onloadedmetadata = null;
|
27192
|
|
- this._video.srcObject = null;
|
|
27189
|
+ this._cameraVideo.onloadedmetadata = null;
|
|
27190
|
+ this._cameraVideo.srcObject = null;
|
27193
|
27191
|
// release the media
|
27194
|
27192
|
return super._release();
|
27195
|
27193
|
}
|