Bladeren bron

Refactor sources of data

customisations
alemart 1 jaar geleden
bovenliggende
commit
7321139796
6 gewijzigde bestanden met toevoegingen van 239 en 233 verwijderingen
  1. 77
    79
      dist/martins.js
  2. 2
    2
      dist/martins.min.js
  3. 9
    17
      src/sources/camera-source.ts
  4. 74
    7
      src/sources/canvas-source.ts
  5. 0
    121
      src/sources/media-source.ts
  6. 77
    7
      src/sources/video-source.ts

+ 77
- 79
dist/martins.js Bestand weergeven

5
  * https://github.com/alemart/martins-js
5
  * https://github.com/alemart/martins-js
6
  *
6
  *
7
  * @license AGPL-3.0-only
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
 (function webpackUniversalModuleDefinition(root, factory) {
10
 (function webpackUniversalModuleDefinition(root, factory) {
11
 	if(typeof exports === 'object' && typeof module === 'object')
11
 	if(typeof exports === 'object' && typeof module === 'object')
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
  * MARTINS.js Free Edition
26918
  * MARTINS.js Free Edition
26919
  * GPU-accelerated Augmented Reality for the web
26919
  * GPU-accelerated Augmented Reality for the web
26932
  * You should have received a copy of the GNU Affero General Public License
26932
  * You should have received a copy of the GNU Affero General Public License
26933
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
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
      * Constructor
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
         this._media = null;
26951
         this._media = null;
26950
-        this._source = source;
26951
     }
26952
     }
26952
     /**
26953
     /**
26953
      * A type-identifier of the source of data
26954
      * A type-identifier of the source of data
26966
         return this._media;
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
      * Initialize this source of data
26981
      * Initialize this source of data
26970
      * @returns a promise that resolves as soon as this source of data is initialized
26982
      * @returns a promise that resolves as soon as this source of data is initialized
26971
      * @internal
26983
      * @internal
26972
      */
26984
      */
26973
     _init() {
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
             this._media = media;
26989
             this._media = media;
26977
         });
26990
         });
26978
     }
26991
     }
26987
         this._media = null;
27000
         this._media = null;
26988
         return speedy_vision_default().Promise.resolve();
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
  * MARTINS.js Free Edition
27007
  * MARTINS.js Free Edition
27005
  * GPU-accelerated Augmented Reality for the web
27008
  * GPU-accelerated Augmented Reality for the web
27018
  * You should have received a copy of the GNU Affero General Public License
27021
  * You should have received a copy of the GNU Affero General Public License
27019
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
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
      * Constructor
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
      * @internal
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
      * Stats related to this source of data
27059
      * Stats related to this source of data
27083
      * @internal
27060
      * @internal
27084
      */
27061
      */
27085
     get _stats() {
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
     constructor(options) {
27132
     constructor(options) {
27130
         const video = document.createElement('video');
27133
         const video = document.createElement('video');
27131
         super(video);
27134
         super(video);
27132
-        this._video = video;
27135
+        this._cameraVideo = video;
27133
         this._options = Object.assign({}, DEFAULT_CAMERA_OPTIONS, options);
27136
         this._options = Object.assign({}, DEFAULT_CAMERA_OPTIONS, options);
27134
     }
27137
     }
27135
     /**
27138
     /**
27139
         return this._options.resolution;
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
      * Initialize this source of data
27145
      * Initialize this source of data
27150
      * @returns a promise that resolves as soon as this source of data is initialized
27146
      * @returns a promise that resolves as soon as this source of data is initialized
27151
      * @internal
27147
      * @internal
27165
         // load camera stream
27161
         // load camera stream
27166
         return new (speedy_vision_default()).Promise((resolve, reject) => {
27162
         return new (speedy_vision_default()).Promise((resolve, reject) => {
27167
             navigator.mediaDevices.getUserMedia(constraints).then(stream => {
27163
             navigator.mediaDevices.getUserMedia(constraints).then(stream => {
27168
-                const video = this._video;
27164
+                const video = this._cameraVideo;
27169
                 video.onloadedmetadata = () => {
27165
                 video.onloadedmetadata = () => {
27170
                     video.play();
27166
                     video.play();
27171
                     Utils.log('Access to the webcam has been granted.');
27167
                     Utils.log('Access to the webcam has been granted.');
27172
                     resolve(video);
27168
                     resolve(video);
27173
                 };
27169
                 };
27170
+                video.setAttribute('playsinline', '');
27171
+                video.setAttribute('autoplay', '');
27172
+                video.setAttribute('muted', '');
27174
                 video.srcObject = stream;
27173
                 video.srcObject = stream;
27175
-                video.muted = true;
27176
             }).catch(err => {
27174
             }).catch(err => {
27177
                 reject(new AccessDeniedError('Please give access to the webcam and reload the page.', err));
27175
                 reject(new AccessDeniedError('Please give access to the webcam and reload the page.', err));
27178
             });
27176
             });
27184
      * @internal
27182
      * @internal
27185
      */
27183
      */
27186
     _release() {
27184
     _release() {
27187
-        const stream = this._video.srcObject;
27185
+        const stream = this._cameraVideo.srcObject;
27188
         const tracks = stream.getTracks();
27186
         const tracks = stream.getTracks();
27189
         // stop camera feed
27187
         // stop camera feed
27190
         tracks.forEach(track => track.stop());
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
         // release the media
27191
         // release the media
27194
         return super._release();
27192
         return super._release();
27195
     }
27193
     }

+ 2
- 2
dist/martins.min.js
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


+ 9
- 17
src/sources/camera-source.ts Bestand weergeven

23
 import Speedy from 'speedy-vision';
23
 import Speedy from 'speedy-vision';
24
 import { SpeedyMedia } from 'speedy-vision/types/core/speedy-media';
24
 import { SpeedyMedia } from 'speedy-vision/types/core/speedy-media';
25
 import { SpeedyPromise } from 'speedy-vision/types/core/speedy-promise';
25
 import { SpeedyPromise } from 'speedy-vision/types/core/speedy-promise';
26
-import { SpeedySize } from 'speedy-vision/types/core/speedy-size';
27
 import { Utils } from '../utils/utils';
26
 import { Utils } from '../utils/utils';
28
 import { Resolution } from '../core/resolution';
27
 import { Resolution } from '../core/resolution';
29
 import { NotSupportedError, AccessDeniedError } from '../utils/errors';
28
 import { NotSupportedError, AccessDeniedError } from '../utils/errors';
60
 export class CameraSource extends VideoSource
59
 export class CameraSource extends VideoSource
61
 {
60
 {
62
     /** Video element */
61
     /** Video element */
63
-    private _video: HTMLVideoElement;
62
+    private _cameraVideo: HTMLVideoElement;
64
 
63
 
65
     /** Options of the constructor */
64
     /** Options of the constructor */
66
     private _options: Required<CameraSourceOptions>;
65
     private _options: Required<CameraSourceOptions>;
75
         const video = document.createElement('video');
74
         const video = document.createElement('video');
76
 
75
 
77
         super(video);
76
         super(video);
78
-        this._video = video;
77
+        this._cameraVideo = video;
79
         this._options = Object.assign({}, DEFAULT_CAMERA_OPTIONS, options);
78
         this._options = Object.assign({}, DEFAULT_CAMERA_OPTIONS, options);
80
     }
79
     }
81
 
80
 
88
     }
87
     }
89
 
88
 
90
     /**
89
     /**
91
-     * Stats related to this source of data
92
-     * @internal
93
-     */
94
-    get _stats(): string
95
-    {
96
-        return `${this._size} webcam`;
97
-    }
98
-
99
-    /**
100
      * Initialize this source of data
90
      * Initialize this source of data
101
      * @returns a promise that resolves as soon as this source of data is initialized
91
      * @returns a promise that resolves as soon as this source of data is initialized
102
      * @internal
92
      * @internal
124
         // load camera stream
114
         // load camera stream
125
         return new Speedy.Promise<HTMLVideoElement>((resolve, reject) => {
115
         return new Speedy.Promise<HTMLVideoElement>((resolve, reject) => {
126
             navigator.mediaDevices.getUserMedia(constraints).then(stream => {
116
             navigator.mediaDevices.getUserMedia(constraints).then(stream => {
127
-                const video = this._video;
117
+                const video = this._cameraVideo;
128
                 video.onloadedmetadata = () => {
118
                 video.onloadedmetadata = () => {
129
                     video.play();
119
                     video.play();
130
                     Utils.log('Access to the webcam has been granted.');
120
                     Utils.log('Access to the webcam has been granted.');
131
                     resolve(video);
121
                     resolve(video);
132
                 };
122
                 };
123
+                video.setAttribute('playsinline', '');
124
+                video.setAttribute('autoplay', '');
125
+                video.setAttribute('muted', '');
133
                 video.srcObject = stream;
126
                 video.srcObject = stream;
134
-                video.muted = true;
135
             }).catch(err => {
127
             }).catch(err => {
136
                 reject(new AccessDeniedError(
128
                 reject(new AccessDeniedError(
137
                     'Please give access to the webcam and reload the page.',
129
                     'Please give access to the webcam and reload the page.',
148
      */
140
      */
149
     _release(): SpeedyPromise<void>
141
     _release(): SpeedyPromise<void>
150
     {
142
     {
151
-        const stream = this._video.srcObject as MediaStream;
143
+        const stream = this._cameraVideo.srcObject as MediaStream;
152
         const tracks = stream.getTracks();
144
         const tracks = stream.getTracks();
153
 
145
 
154
         // stop camera feed
146
         // stop camera feed
155
         tracks.forEach(track => track.stop());
147
         tracks.forEach(track => track.stop());
156
-        this._video.onloadedmetadata = null;
157
-        this._video.srcObject = null;
148
+        this._cameraVideo.onloadedmetadata = null;
149
+        this._cameraVideo.srcObject = null;
158
 
150
 
159
         // release the media
151
         // release the media
160
         return super._release();
152
         return super._release();

+ 74
- 7
src/sources/canvas-source.ts Bestand weergeven

17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
  *
18
  *
19
  * canvas-source.ts
19
  * canvas-source.ts
20
- * <canvas>-based source of data
20
+ * HTMLCanvasElement-based source of data
21
  */
21
  */
22
 
22
 
23
-import { Utils } from '../utils/utils';
24
-import { MediaSource } from './media-source';
23
+import Speedy from 'speedy-vision';
24
+import { SpeedyMedia } from 'speedy-vision/types/core/speedy-media';
25
+import { SpeedyPromise } from 'speedy-vision/types/core/speedy-promise';
26
+import { Utils, Nullable } from '../utils/utils';
27
+import { IllegalOperationError } from '../utils/errors';
28
+import { Source } from './source';
25
 
29
 
26
 /**
30
 /**
27
- * <canvas>-based source of data
31
+ * HTMLCanvasElement-based source of data
28
  */
32
  */
29
-export class CanvasSource extends MediaSource
33
+export class CanvasSource implements Source
30
 {
34
 {
35
+    /** canvas element */
36
+    private _canvas: HTMLCanvasElement;
37
+
38
+    /** media source */
39
+    protected _media: Nullable<SpeedyMedia>;
40
+
41
+
42
+
31
     /**
43
     /**
32
      * Constructor
44
      * Constructor
33
      */
45
      */
34
     constructor(canvas: HTMLCanvasElement)
46
     constructor(canvas: HTMLCanvasElement)
35
     {
47
     {
36
         Utils.assert(canvas instanceof HTMLCanvasElement, 'Expected a canvas element');
48
         Utils.assert(canvas instanceof HTMLCanvasElement, 'Expected a canvas element');
37
-        super(canvas);
49
+
50
+        this._canvas = canvas;
51
+        this._media = null;
52
+    }
53
+
54
+    /**
55
+     * A type-identifier of the source of data
56
+     * @internal
57
+     */
58
+    get _type(): string
59
+    {
60
+        return 'canvas';
61
+    }
62
+
63
+    /**
64
+     * Get media
65
+     * @internal
66
+     */
67
+    get _data(): SpeedyMedia
68
+    {
69
+        if(this._media == null)
70
+            throw new IllegalOperationError(`The media of the source of data isn't loaded`);
71
+
72
+        return this._media;
38
     }
73
     }
39
 
74
 
40
     /**
75
     /**
43
      */
78
      */
44
     get _stats(): string
79
     get _stats(): string
45
     {
80
     {
46
-        return `${this._size} canvas`;
81
+        const media = this._media;
82
+
83
+        if(media != null)
84
+            return `${media.width}x${media.height} canvas`;
85
+        else
86
+            return 'uninitialized canvas';
87
+    }
88
+
89
+    /**
90
+     * Initialize this source of data
91
+     * @returns a promise that resolves as soon as this source of data is initialized
92
+     * @internal
93
+     */
94
+    _init(): SpeedyPromise<void>
95
+    {
96
+        return Speedy.load(this._canvas).then(media => {
97
+            Utils.log(`Source of data is a ${media.width}x${media.height} ${this._type}`);
98
+            this._media = media;
99
+        });
100
+    }
101
+
102
+    /**
103
+     * Release this source of data
104
+     * @returns a promise that resolves as soon as this source of data is released
105
+     * @internal
106
+     */
107
+    _release(): SpeedyPromise<void>
108
+    {
109
+        if(this._media)
110
+            this._media.release();
111
+
112
+        this._media = null;
113
+        return Speedy.Promise.resolve();
47
     }
114
     }
48
 }
115
 }

+ 0
- 121
src/sources/media-source.ts Bestand weergeven

1
-/*
2
- * MARTINS.js Free Edition
3
- * GPU-accelerated Augmented Reality for the web
4
- * Copyright (C) 2022  Alexandre Martins <alemartf(at)gmail.com>
5
- * https://github.com/alemart/martins-js
6
- *
7
- * This program is free software: you can redistribute it and/or modify
8
- * it under the terms of the GNU Affero General Public License version 3
9
- * as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU Affero General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU Affero General Public License
17
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
- *
19
- * media-source.ts
20
- * SpeedyMedia-based source of data
21
- */
22
-
23
-import Speedy from 'speedy-vision';
24
-import { SpeedyMedia } from 'speedy-vision/types/core/speedy-media';
25
-import { SpeedyPromise } from 'speedy-vision/types/core/speedy-promise';
26
-import { SpeedySize } from 'speedy-vision/types/core/speedy-size';
27
-import { Utils, Nullable } from '../utils/utils';
28
-import { Resolution } from '../core/resolution';
29
-import { IllegalOperationError, NotSupportedError, AccessDeniedError } from '../utils/errors';
30
-import { Source } from './source';
31
-
32
-
33
-/**
34
- * SpeedyMedia-based source of data
35
- */
36
-export abstract class MediaSource implements Source
37
-{
38
-    /** source element */
39
-    private _source: HTMLVideoElement | HTMLCanvasElement;
40
-
41
-    /** media source */
42
-    protected _media: Nullable<SpeedyMedia>;
43
-
44
-
45
-
46
-    /**
47
-     * Constructor
48
-     */
49
-    constructor(source: HTMLVideoElement | HTMLCanvasElement)
50
-    {
51
-        this._media = null;
52
-        this._source = source;
53
-    }
54
-
55
-    /**
56
-     * A type-identifier of the source of data
57
-     * @internal
58
-     */
59
-    get _type(): string
60
-    {
61
-        return 'video';
62
-    }
63
-
64
-    /**
65
-     * Get media
66
-     * @internal
67
-     */
68
-    get _data(): SpeedyMedia
69
-    {
70
-        if(this._media == null)
71
-            throw new IllegalOperationError(`The media of the source of data isn't loaded`);
72
-
73
-        return this._media;
74
-    }
75
-
76
-    /**
77
-     * Stats related to this source of data
78
-     * @internal
79
-     */
80
-    abstract get _stats(): string;
81
-
82
-    /**
83
-     * Initialize this source of data
84
-     * @returns a promise that resolves as soon as this source of data is initialized
85
-     * @internal
86
-     */
87
-    _init(): SpeedyPromise<void>
88
-    {
89
-        return Speedy.load(this._source).then(media => {
90
-            Utils.log(`Source of data is ${media.width}x${media.height}`);
91
-            this._media = media;
92
-        });
93
-    }
94
-
95
-    /**
96
-     * Release this source of data
97
-     * @returns a promise that resolves as soon as this source of data is released
98
-     * @internal
99
-     */
100
-    _release(): SpeedyPromise<void>
101
-    {
102
-        if(this._media)
103
-            this._media.release();
104
-
105
-        this._media = null;
106
-        return Speedy.Promise.resolve();
107
-    }
108
-
109
-    /**
110
-     * A string featuring the size of the media, in pixels
111
-     */
112
-    protected get _size(): string
113
-    {
114
-        const media = this._media;
115
-
116
-        if(media != null)
117
-            return `${media.width}x${media.height}`;
118
-        else
119
-            return '-';
120
-    }
121
-}

+ 77
- 7
src/sources/video-source.ts Bestand weergeven

17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
  *
18
  *
19
  * video-source.ts
19
  * video-source.ts
20
- * <video>-based source of data
20
+ * HTMLVideoElement-based source of data
21
  */
21
  */
22
 
22
 
23
-import { Utils } from '../utils/utils';
24
-import { MediaSource } from './media-source';
23
+import Speedy from 'speedy-vision';
24
+import { SpeedyMedia } from 'speedy-vision/types/core/speedy-media';
25
+import { SpeedyPromise } from 'speedy-vision/types/core/speedy-promise';
26
+import { Utils, Nullable } from '../utils/utils';
27
+import { IllegalOperationError } from '../utils/errors';
28
+import { Source } from './source';
29
+
25
 
30
 
26
 /**
31
 /**
27
- * <video>-based source of data
32
+ * HTMLVideoElement-based source of data
28
  */
33
  */
29
-export class VideoSource extends MediaSource
34
+export class VideoSource implements Source
30
 {
35
 {
36
+    /** video element */
37
+    private _video: HTMLVideoElement;
38
+
39
+    /** media source */
40
+    protected _media: Nullable<SpeedyMedia>;
41
+
42
+
43
+
31
     /**
44
     /**
32
      * Constructor
45
      * Constructor
33
      */
46
      */
34
     constructor(video: HTMLVideoElement)
47
     constructor(video: HTMLVideoElement)
35
     {
48
     {
36
         Utils.assert(video instanceof HTMLVideoElement, 'Expected a video element');
49
         Utils.assert(video instanceof HTMLVideoElement, 'Expected a video element');
37
-        super(video);
50
+
51
+        this._video = video;
52
+        this._media = null;
53
+    }
54
+
55
+    /**
56
+     * A type-identifier of the source of data
57
+     * @internal
58
+     */
59
+    get _type(): string
60
+    {
61
+        return 'video';
62
+    }
63
+
64
+    /**
65
+     * Get media
66
+     * @internal
67
+     */
68
+    get _data(): SpeedyMedia
69
+    {
70
+        if(this._media == null)
71
+            throw new IllegalOperationError(`The media of the source of data isn't loaded`);
72
+
73
+        return this._media;
38
     }
74
     }
39
 
75
 
40
     /**
76
     /**
43
      */
79
      */
44
     get _stats(): string
80
     get _stats(): string
45
     {
81
     {
46
-        return `${this._size} video`;
82
+        const media = this._media;
83
+
84
+        if(media != null)
85
+            return `${media.width}x${media.height} video`;
86
+        else
87
+            return 'uninitialized video';
88
+    }
89
+
90
+    /**
91
+     * Initialize this source of data
92
+     * @returns a promise that resolves as soon as this source of data is initialized
93
+     * @internal
94
+     */
95
+    _init(): SpeedyPromise<void>
96
+    {
97
+        this._video.setAttribute('playsinline', '');
98
+
99
+        return Speedy.load(this._video).then(media => {
100
+            Utils.log(`Source of data is a ${media.width}x${media.height} ${this._type}`);
101
+            this._media = media;
102
+        });
103
+    }
104
+
105
+    /**
106
+     * Release this source of data
107
+     * @returns a promise that resolves as soon as this source of data is released
108
+     * @internal
109
+     */
110
+    _release(): SpeedyPromise<void>
111
+    {
112
+        if(this._media)
113
+            this._media.release();
114
+
115
+        this._media = null;
116
+        return Speedy.Promise.resolve();
47
     }
117
     }
48
 }
118
 }

Laden…
Annuleren
Opslaan