@capgo/capacitor-video-player 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapgoCapacitorVideoPlayer.podspec +17 -0
- package/Package.swift +28 -0
- package/README.md +431 -0
- package/android/build.gradle +72 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/com/capgo/videoplayer/FullscreenExoPlayerFragment.java +1406 -0
- package/android/src/main/java/com/capgo/videoplayer/Notifications/MyRunnable.java +21 -0
- package/android/src/main/java/com/capgo/videoplayer/Notifications/NotificationCenter.java +61 -0
- package/android/src/main/java/com/capgo/videoplayer/PickerVideo/AdapterVideoList.java +47 -0
- package/android/src/main/java/com/capgo/videoplayer/PickerVideo/ModelVideo.java +49 -0
- package/android/src/main/java/com/capgo/videoplayer/PickerVideo/PickerVideoFragment.java +116 -0
- package/android/src/main/java/com/capgo/videoplayer/PickerVideo/VideoRecyclerViewHolder.java +65 -0
- package/android/src/main/java/com/capgo/videoplayer/Utilities/FilesUtils.java +38 -0
- package/android/src/main/java/com/capgo/videoplayer/Utilities/FragmentUtils.java +32 -0
- package/android/src/main/java/com/capgo/videoplayer/VideoPlayer.java +71 -0
- package/android/src/main/java/com/capgo/videoplayer/VideoPlayerPlugin.java +1239 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/bg_round_rect_white_50.xml +9 -0
- package/android/src/main/res/drawable/bg_rounded_rectangle_white_corner_rounded.xml +10 -0
- package/android/src/main/res/drawable/exo_close_btn.xml +12 -0
- package/android/src/main/res/drawable/gradient_transparent_middle.xml +12 -0
- package/android/src/main/res/drawable/ic_arrow_left.xml +5 -0
- package/android/src/main/res/drawable/ic_baseline_lq.xml +7 -0
- package/android/src/main/res/drawable/ic_exo_icon_fastforward.xml +35 -0
- package/android/src/main/res/drawable/ic_exo_icon_pause.xml +26 -0
- package/android/src/main/res/drawable/ic_exo_icon_play.xml +36 -0
- package/android/src/main/res/drawable/ic_exo_icon_rewind.xml +35 -0
- package/android/src/main/res/drawable/ic_expand.xml +5 -0
- package/android/src/main/res/drawable/ic_fit.xml +5 -0
- package/android/src/main/res/drawable/ic_image_background.xml +12 -0
- package/android/src/main/res/drawable/ic_img_16_9_background.xml +10 -0
- package/android/src/main/res/drawable/ic_img_9_16_background.xml +10 -0
- package/android/src/main/res/drawable/ic_outline_lock.xml +5 -0
- package/android/src/main/res/drawable/ic_outline_lock_open.xml +5 -0
- package/android/src/main/res/drawable/ic_pip_white.xml +5 -0
- package/android/src/main/res/drawable/ic_views.xml +18 -0
- package/android/src/main/res/drawable/ic_zoom.xml +5 -0
- package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
- package/android/src/main/res/layout/exo_playback_control_view.xml +287 -0
- package/android/src/main/res/layout/exoplayer_layout_youtube.xml +361 -0
- package/android/src/main/res/layout/fragment_fs_exoplayer.xml +50 -0
- package/android/src/main/res/layout/fragment_picker_video.xml +21 -0
- package/android/src/main/res/layout/row_video.xml +76 -0
- package/android/src/main/res/values/colors.xml +14 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/android/src/main/res/values/styles.xml +3 -0
- package/dist/docs.json +686 -0
- package/dist/esm/definitions.d.ts +307 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web-utils/video-types.d.ts +4 -0
- package/dist/esm/web-utils/video-types.js +9 -0
- package/dist/esm/web-utils/video-types.js.map +1 -0
- package/dist/esm/web-utils/videoplayer.d.ts +30 -0
- package/dist/esm/web-utils/videoplayer.js +323 -0
- package/dist/esm/web-utils/videoplayer.js.map +1 -0
- package/dist/esm/web.d.ts +121 -0
- package/dist/esm/web.js +675 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +1019 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +1021 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/VideoPlayerPlugin/VideoPlayer.swift +8 -0
- package/ios/Sources/VideoPlayerPlugin/VideoPlayerPlugin.swift +23 -0
- package/ios/Tests/VideoPlayerPluginTests/VideoPlayerPluginTests.swift +15 -0
- package/package.json +85 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import Hls from 'hls.js';
|
|
2
|
+
import { videoTypes, possibleQueryParameterExtensions } from './video-types';
|
|
3
|
+
export class VideoPlayer {
|
|
4
|
+
constructor(mode, url, playerId, rate, exitOnEnd, loopOnEnd, container, zIndex, width, height) {
|
|
5
|
+
this.pipMode = false;
|
|
6
|
+
this._videoType = null;
|
|
7
|
+
this._videoContainer = null;
|
|
8
|
+
this._firstReadyToPlay = true;
|
|
9
|
+
this._isEnded = false;
|
|
10
|
+
this._videoRate = 1.0;
|
|
11
|
+
this._videoExitOnEnd = true;
|
|
12
|
+
this._videoLoopOnEnd = false;
|
|
13
|
+
this._url = url;
|
|
14
|
+
this._container = container;
|
|
15
|
+
this._mode = mode;
|
|
16
|
+
this._width = width ? width : 320;
|
|
17
|
+
this._height = height ? height : 180;
|
|
18
|
+
this._mode = mode;
|
|
19
|
+
this._videoRate = rate;
|
|
20
|
+
this._zIndex = zIndex ? zIndex : 1;
|
|
21
|
+
this._playerId = playerId;
|
|
22
|
+
this._videoExitOnEnd = exitOnEnd;
|
|
23
|
+
this._videoLoopOnEnd = loopOnEnd;
|
|
24
|
+
}
|
|
25
|
+
async initialize() {
|
|
26
|
+
// get the video type
|
|
27
|
+
const urlVideoType = this._getVideoType();
|
|
28
|
+
if (urlVideoType) {
|
|
29
|
+
// style the container
|
|
30
|
+
if (this._mode === 'fullscreen') {
|
|
31
|
+
this._container.style.position = 'absolute';
|
|
32
|
+
this._container.style.width = '100vw';
|
|
33
|
+
this._container.style.height = '100vh';
|
|
34
|
+
}
|
|
35
|
+
if (this._mode === 'embedded') {
|
|
36
|
+
this._container.style.position = 'relative';
|
|
37
|
+
this._container.style.width = this._width.toString() + 'px';
|
|
38
|
+
this._container.style.height = this._height.toString() + 'px';
|
|
39
|
+
}
|
|
40
|
+
this._container.style.left = '0';
|
|
41
|
+
this._container.style.top = '0';
|
|
42
|
+
this._container.style.display = 'flex';
|
|
43
|
+
this._container.style.alignItems = 'center';
|
|
44
|
+
this._container.style.justifyContent = 'center';
|
|
45
|
+
this._container.style.backgroundColor = '#000000';
|
|
46
|
+
this._container.style.zIndex = this._zIndex.toString();
|
|
47
|
+
const width = this._mode === 'fullscreen' ? window.innerWidth /*this._container.offsetWidth*/ : this._width;
|
|
48
|
+
const height = this._mode === 'fullscreen' ? window.innerHeight /*this._container.offsetHeight*/ : this._height;
|
|
49
|
+
const xmlns = 'http://www.w3.org/2000/svg';
|
|
50
|
+
const svg = document.createElementNS(xmlns, 'svg');
|
|
51
|
+
svg.setAttributeNS(null, 'width', width.toString());
|
|
52
|
+
svg.setAttributeNS(null, 'height', height.toString());
|
|
53
|
+
const viewbox = '0 0 ' + width.toString() + ' ' + height.toString();
|
|
54
|
+
svg.setAttributeNS(null, 'viewBox', viewbox);
|
|
55
|
+
svg.style.zIndex = (this._zIndex + 1).toString();
|
|
56
|
+
const rect = document.createElementNS(xmlns, 'rect');
|
|
57
|
+
rect.setAttributeNS(null, 'x', '0');
|
|
58
|
+
rect.setAttributeNS(null, 'y', '0');
|
|
59
|
+
rect.setAttributeNS(null, 'width', width.toString());
|
|
60
|
+
rect.setAttributeNS(null, 'height', height.toString());
|
|
61
|
+
rect.setAttributeNS(null, 'fill', '#000000');
|
|
62
|
+
svg.appendChild(rect);
|
|
63
|
+
this._container.appendChild(svg);
|
|
64
|
+
const heightVideo = (width * this._height) / this._width;
|
|
65
|
+
this._videoContainer = document.createElement('div');
|
|
66
|
+
this._videoContainer.style.position = 'absolute';
|
|
67
|
+
this._videoContainer.style.left = '0';
|
|
68
|
+
this._videoContainer.style.width = width.toString() + 'px';
|
|
69
|
+
this._videoContainer.style.height = heightVideo.toString() + 'px';
|
|
70
|
+
this._videoContainer.style.zIndex = (this._zIndex + 2).toString();
|
|
71
|
+
this._container.appendChild(this._videoContainer);
|
|
72
|
+
/* Create Video Element */
|
|
73
|
+
const isCreated = await this.createVideoElement(width, heightVideo);
|
|
74
|
+
if (!isCreated) {
|
|
75
|
+
this._createEvent('Exit', this._playerId, 'Video Error: failed to create the Video Element');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this._createEvent('Exit', this._playerId, 'Url Error: type not supported');
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
async createVideoElement(width, height) {
|
|
84
|
+
this.videoEl = document.createElement('video');
|
|
85
|
+
this.videoEl.controls = true;
|
|
86
|
+
this.videoEl.style.zIndex = (this._zIndex + 3).toString();
|
|
87
|
+
this.videoEl.style.width = `${width.toString()}px`;
|
|
88
|
+
this.videoEl.style.height = `${height.toString()}px`;
|
|
89
|
+
this.videoEl.playbackRate = this._videoRate;
|
|
90
|
+
this._videoContainer.appendChild(this.videoEl);
|
|
91
|
+
// set the player
|
|
92
|
+
const isSet = await this._setPlayer();
|
|
93
|
+
if (isSet) {
|
|
94
|
+
this.videoEl.onended = async () => {
|
|
95
|
+
this._isEnded = true;
|
|
96
|
+
this.isPlaying = false;
|
|
97
|
+
if (this.videoEl) {
|
|
98
|
+
this.videoEl.currentTime = 0;
|
|
99
|
+
}
|
|
100
|
+
if (this._videoExitOnEnd) {
|
|
101
|
+
if (this._mode === 'fullscreen') {
|
|
102
|
+
this._closeFullscreen();
|
|
103
|
+
}
|
|
104
|
+
this._createEvent('Ended', this._playerId);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
if (this._videoLoopOnEnd && this.videoEl != null) {
|
|
108
|
+
await this.videoEl.play();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
this.videoEl.oncanplay = async () => {
|
|
113
|
+
if (this._firstReadyToPlay) {
|
|
114
|
+
this._createEvent('Ready', this._playerId);
|
|
115
|
+
if (this.videoEl != null) {
|
|
116
|
+
this.videoEl.muted = false;
|
|
117
|
+
if (this._mode === 'fullscreen')
|
|
118
|
+
await this.videoEl.play();
|
|
119
|
+
this._firstReadyToPlay = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
this.videoEl.onplay = () => {
|
|
124
|
+
this.isPlaying = true;
|
|
125
|
+
if (this._firstReadyToPlay)
|
|
126
|
+
this._firstReadyToPlay = false;
|
|
127
|
+
this._createEvent('Play', this._playerId);
|
|
128
|
+
};
|
|
129
|
+
this.videoEl.onplaying = () => {
|
|
130
|
+
this._createEvent('Playing', this._playerId);
|
|
131
|
+
};
|
|
132
|
+
this.videoEl.onpause = () => {
|
|
133
|
+
this.isPlaying = false;
|
|
134
|
+
this._createEvent('Pause', this._playerId);
|
|
135
|
+
};
|
|
136
|
+
if (this._mode === 'fullscreen') {
|
|
137
|
+
// create the video player exit button
|
|
138
|
+
const exitEl = document.createElement('button');
|
|
139
|
+
exitEl.textContent = 'X';
|
|
140
|
+
exitEl.style.position = 'absolute';
|
|
141
|
+
exitEl.style.left = '1%';
|
|
142
|
+
exitEl.style.top = '5%';
|
|
143
|
+
exitEl.style.width = '5vmin';
|
|
144
|
+
exitEl.style.padding = '0.5%';
|
|
145
|
+
exitEl.style.fontSize = '1.2rem';
|
|
146
|
+
exitEl.style.background = 'rgba(51,51,51,.4)';
|
|
147
|
+
exitEl.style.color = '#fff';
|
|
148
|
+
exitEl.style.visibility = 'hidden';
|
|
149
|
+
exitEl.style.zIndex = (this._zIndex + 4).toString();
|
|
150
|
+
exitEl.style.border = '1px solid rgba(51,51,51,.4)';
|
|
151
|
+
exitEl.style.borderRadius = '20px';
|
|
152
|
+
this._videoContainer.onclick = async () => {
|
|
153
|
+
this._initial = await this._doHide(exitEl, 3000);
|
|
154
|
+
};
|
|
155
|
+
this._videoContainer.ontouchstart = async () => {
|
|
156
|
+
this._initial = await this._doHide(exitEl, 3000);
|
|
157
|
+
};
|
|
158
|
+
this._videoContainer.onmousemove = async () => {
|
|
159
|
+
this._initial = await this._doHide(exitEl, 3000);
|
|
160
|
+
};
|
|
161
|
+
exitEl.onclick = () => {
|
|
162
|
+
this._createEvent('Exit', this._playerId);
|
|
163
|
+
};
|
|
164
|
+
exitEl.ontouchstart = () => {
|
|
165
|
+
this._createEvent('Exit', this._playerId);
|
|
166
|
+
};
|
|
167
|
+
this._videoContainer.appendChild(exitEl);
|
|
168
|
+
this._initial = await this._doHide(exitEl, 3000);
|
|
169
|
+
this._goFullscreen();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return isSet;
|
|
173
|
+
}
|
|
174
|
+
async _goFullscreen() {
|
|
175
|
+
if (this._container.mozRequestFullScreen) {
|
|
176
|
+
/* Firefox */
|
|
177
|
+
this._container.mozRequestFullScreen();
|
|
178
|
+
}
|
|
179
|
+
else if (this._container.webkitRequestFullscreen) {
|
|
180
|
+
/* Chrome, Safari & Opera */
|
|
181
|
+
this._container.webkitRequestFullscreen();
|
|
182
|
+
}
|
|
183
|
+
else if (this._container.msRequestFullscreen) {
|
|
184
|
+
/* IE/Edge */
|
|
185
|
+
this._container.msRequestFullscreen();
|
|
186
|
+
}
|
|
187
|
+
else if (this._container.requestFullscreen) {
|
|
188
|
+
this._container.requestFullscreen();
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
async _setPlayer() {
|
|
193
|
+
return new Promise((resolve) => {
|
|
194
|
+
if (this.videoEl != null) {
|
|
195
|
+
if (Hls.isSupported() && this._videoType === 'application/x-mpegURL') {
|
|
196
|
+
const hls = new Hls();
|
|
197
|
+
hls.loadSource(this._url);
|
|
198
|
+
hls.attachMedia(this.videoEl);
|
|
199
|
+
hls.once(Hls.Events.FRAG_PARSED, () => {
|
|
200
|
+
if (this.videoEl != null) {
|
|
201
|
+
this.videoEl.muted = true;
|
|
202
|
+
this.videoEl.crossOrigin = 'anonymous';
|
|
203
|
+
resolve(true);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
resolve(false);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
else if (this._videoType === 'video/mp4') {
|
|
211
|
+
// CMAF (fMP4) && MP4
|
|
212
|
+
this.videoEl.src = this._url;
|
|
213
|
+
if (this._url.substring(0, 5) != 'https' && this._url.substring(0, 4) === 'http')
|
|
214
|
+
this.videoEl.crossOrigin = 'anonymous';
|
|
215
|
+
if (this._url.substring(0, 5) === 'https' || this._url.substring(0, 4) === 'http')
|
|
216
|
+
this.videoEl.muted = true;
|
|
217
|
+
resolve(true);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// Not Supported
|
|
221
|
+
resolve(false);
|
|
222
|
+
}
|
|
223
|
+
this.videoEl.addEventListener('enterpictureinpicture', (event) => {
|
|
224
|
+
this.pipWindow = event.pictureInPictureWindow;
|
|
225
|
+
this.pipMode = true;
|
|
226
|
+
this._closeFullscreen();
|
|
227
|
+
});
|
|
228
|
+
this.videoEl.addEventListener('leavepictureinpicture', () => {
|
|
229
|
+
this.pipMode = false;
|
|
230
|
+
if (!this._isEnded) {
|
|
231
|
+
this._goFullscreen();
|
|
232
|
+
if (this.videoEl != null)
|
|
233
|
+
this.videoEl.play();
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
resolve(false);
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
_getVideoType() {
|
|
243
|
+
const sUrl = this._url ? this._url : '';
|
|
244
|
+
if (sUrl != null && sUrl.length > 0) {
|
|
245
|
+
Object.entries(videoTypes).forEach(([extension, mimeType]) => {
|
|
246
|
+
// we search for dot + extension (e.g. `.mp4`) for URLs that have the extension in the filename
|
|
247
|
+
// e.g. https://vimeo.com/?file=my-video.mp4
|
|
248
|
+
const hasDotExtension = sUrl.match(new RegExp(`.(${extension})`, 'i'));
|
|
249
|
+
if (hasDotExtension) {
|
|
250
|
+
return (this._videoType = mimeType);
|
|
251
|
+
}
|
|
252
|
+
// we search for the extension (e.g. `m3u8`) for URLs that might have the extension as a query parameter
|
|
253
|
+
// e.g. https://youtube.com/?v=7894289374&type=m3u8
|
|
254
|
+
const hasExtensionInUrl = sUrl.match(new RegExp(`(${extension})`, 'i'));
|
|
255
|
+
if (hasExtensionInUrl) {
|
|
256
|
+
return (this._videoType = mimeType);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
// we check for not supported extensions for URLs that have the extension in the filename
|
|
260
|
+
// e.g. https://vimeo.com/?file=not-supported-extension-video.mkv
|
|
261
|
+
const hasNotSupportedDotExtension = sUrl.match(/\.(.*)/i);
|
|
262
|
+
if (hasNotSupportedDotExtension) {
|
|
263
|
+
return (this._videoType = null);
|
|
264
|
+
}
|
|
265
|
+
// we check for not supported extensions for URLs that might have the extension as a query parameter
|
|
266
|
+
// e.g. https://youtube.com/?v=3982748927&filetype=mkv
|
|
267
|
+
const hasNotSupportedExtensionInUrl = sUrl.match(new RegExp(`(${possibleQueryParameterExtensions.join('|')})=+(.*)&?(?=&|$))`, 'i'));
|
|
268
|
+
if (hasNotSupportedExtensionInUrl) {
|
|
269
|
+
return (this._videoType = null);
|
|
270
|
+
}
|
|
271
|
+
// No extension found, then we assume it's 'mp4' (Match case for '')
|
|
272
|
+
return 'video/mp4';
|
|
273
|
+
}
|
|
274
|
+
// URL was not defined, we return null
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
async _doHide(exitEl, duration) {
|
|
278
|
+
clearTimeout(this._initial);
|
|
279
|
+
exitEl.style.visibility = 'visible';
|
|
280
|
+
const initial = setTimeout(() => {
|
|
281
|
+
exitEl.style.visibility = 'hidden';
|
|
282
|
+
}, duration);
|
|
283
|
+
return initial;
|
|
284
|
+
}
|
|
285
|
+
_createEvent(ev, playerId, msg) {
|
|
286
|
+
const message = msg ? msg : null;
|
|
287
|
+
let event;
|
|
288
|
+
if (message != null) {
|
|
289
|
+
event = new CustomEvent(`videoPlayer${ev}`, {
|
|
290
|
+
detail: { fromPlayerId: playerId, message: message },
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
const currentTime = this.videoEl ? this.videoEl.currentTime : 0;
|
|
295
|
+
event = new CustomEvent(`videoPlayer${ev}`, {
|
|
296
|
+
detail: { fromPlayerId: playerId, currentTime: currentTime },
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
document.dispatchEvent(event);
|
|
300
|
+
}
|
|
301
|
+
_closeFullscreen() {
|
|
302
|
+
const mydoc = document;
|
|
303
|
+
const isInFullScreen = (mydoc.fullscreenElement && mydoc.fullscreenElement !== null) ||
|
|
304
|
+
(mydoc.webkitFullscreenElement && mydoc.webkitFullscreenElement !== null) ||
|
|
305
|
+
(mydoc.mozFullScreenElement && mydoc.mozFullScreenElement !== null) ||
|
|
306
|
+
(mydoc.msFullscreenElement && mydoc.msFullscreenElement !== null);
|
|
307
|
+
if (isInFullScreen) {
|
|
308
|
+
if (mydoc.mozCancelFullScreen) {
|
|
309
|
+
mydoc.mozCancelFullScreen();
|
|
310
|
+
}
|
|
311
|
+
else if (mydoc.webkitExitFullscreen) {
|
|
312
|
+
mydoc.webkitExitFullscreen();
|
|
313
|
+
}
|
|
314
|
+
else if (mydoc.msExitFullscreen) {
|
|
315
|
+
mydoc.msExitFullscreen();
|
|
316
|
+
}
|
|
317
|
+
else if (mydoc.exitFullscreen) {
|
|
318
|
+
mydoc.exitFullscreen();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=videoplayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"videoplayer.js","sourceRoot":"","sources":["../../../src/web-utils/videoplayer.ts"],"names":[],"mappings":"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","sourcesContent":["import Hls from 'hls.js';\n\nimport type { videoMimeType } from './video-types';\nimport { videoTypes, possibleQueryParameterExtensions } from './video-types';\n\nexport class VideoPlayer {\n public videoEl: HTMLVideoElement | undefined;\n public pipMode = false;\n public pipWindow: Window | undefined;\n public isPlaying: boolean | undefined;\n\n private _url: string;\n private _playerId: string;\n private _container: any;\n private _mode: string;\n private _width: number;\n private _height: number;\n private _zIndex: number;\n private _initial: any;\n private _videoType: videoMimeType | null = null;\n private _videoContainer: any = null;\n private _firstReadyToPlay = true;\n private _isEnded = false;\n private _videoRate = 1.0;\n private _videoExitOnEnd = true;\n private _videoLoopOnEnd = false;\n\n constructor(\n mode: string,\n url: string,\n playerId: string,\n rate: number,\n exitOnEnd: boolean,\n loopOnEnd: boolean,\n container: any,\n zIndex: number,\n width?: number,\n height?: number,\n ) {\n this._url = url;\n this._container = container;\n this._mode = mode;\n this._width = width ? width : 320;\n this._height = height ? height : 180;\n this._mode = mode;\n this._videoRate = rate;\n this._zIndex = zIndex ? zIndex : 1;\n this._playerId = playerId;\n this._videoExitOnEnd = exitOnEnd;\n this._videoLoopOnEnd = loopOnEnd;\n }\n\n public async initialize(): Promise<void> {\n // get the video type\n const urlVideoType: videoMimeType | null = this._getVideoType();\n if (urlVideoType) {\n // style the container\n if (this._mode === 'fullscreen') {\n this._container.style.position = 'absolute';\n this._container.style.width = '100vw';\n this._container.style.height = '100vh';\n }\n if (this._mode === 'embedded') {\n this._container.style.position = 'relative';\n this._container.style.width = this._width.toString() + 'px';\n this._container.style.height = this._height.toString() + 'px';\n }\n this._container.style.left = '0';\n this._container.style.top = '0';\n this._container.style.display = 'flex';\n this._container.style.alignItems = 'center';\n this._container.style.justifyContent = 'center';\n this._container.style.backgroundColor = '#000000';\n this._container.style.zIndex = this._zIndex.toString();\n const width: number =\n this._mode === 'fullscreen' ? window.innerWidth /*this._container.offsetWidth*/ : this._width;\n const height: number =\n this._mode === 'fullscreen' ? window.innerHeight /*this._container.offsetHeight*/ : this._height;\n const xmlns = 'http://www.w3.org/2000/svg';\n\n const svg = document.createElementNS(xmlns, 'svg');\n svg.setAttributeNS(null, 'width', width.toString());\n svg.setAttributeNS(null, 'height', height.toString());\n const viewbox = '0 0 ' + width.toString() + ' ' + height.toString();\n svg.setAttributeNS(null, 'viewBox', viewbox);\n svg.style.zIndex = (this._zIndex + 1).toString();\n const rect = document.createElementNS(xmlns, 'rect');\n rect.setAttributeNS(null, 'x', '0');\n rect.setAttributeNS(null, 'y', '0');\n rect.setAttributeNS(null, 'width', width.toString());\n rect.setAttributeNS(null, 'height', height.toString());\n rect.setAttributeNS(null, 'fill', '#000000');\n svg.appendChild(rect);\n this._container.appendChild(svg);\n\n const heightVideo: number = (width * this._height) / this._width;\n this._videoContainer = document.createElement('div');\n this._videoContainer.style.position = 'absolute';\n this._videoContainer.style.left = '0';\n this._videoContainer.style.width = width.toString() + 'px';\n this._videoContainer.style.height = heightVideo.toString() + 'px';\n this._videoContainer.style.zIndex = (this._zIndex + 2).toString();\n this._container.appendChild(this._videoContainer);\n /* Create Video Element */\n const isCreated = await this.createVideoElement(width, heightVideo);\n if (!isCreated) {\n this._createEvent('Exit', this._playerId, 'Video Error: failed to create the Video Element');\n }\n } else {\n this._createEvent('Exit', this._playerId, 'Url Error: type not supported');\n }\n return;\n }\n\n private async createVideoElement(width: number, height: number): Promise<boolean> {\n this.videoEl = document.createElement('video');\n this.videoEl.controls = true;\n this.videoEl.style.zIndex = (this._zIndex + 3).toString();\n this.videoEl.style.width = `${width.toString()}px`;\n this.videoEl.style.height = `${height.toString()}px`;\n this.videoEl.playbackRate = this._videoRate;\n this._videoContainer.appendChild(this.videoEl);\n // set the player\n const isSet: boolean = await this._setPlayer();\n if (isSet) {\n this.videoEl.onended = async () => {\n this._isEnded = true;\n this.isPlaying = false;\n if (this.videoEl) {\n this.videoEl.currentTime = 0;\n }\n if (this._videoExitOnEnd) {\n if (this._mode === 'fullscreen') {\n this._closeFullscreen();\n }\n this._createEvent('Ended', this._playerId);\n } else {\n if (this._videoLoopOnEnd && this.videoEl != null) {\n await this.videoEl.play();\n }\n }\n };\n this.videoEl.oncanplay = async () => {\n if (this._firstReadyToPlay) {\n this._createEvent('Ready', this._playerId);\n if (this.videoEl != null) {\n this.videoEl.muted = false;\n if (this._mode === 'fullscreen') await this.videoEl.play();\n this._firstReadyToPlay = false;\n }\n }\n };\n this.videoEl.onplay = () => {\n this.isPlaying = true;\n if (this._firstReadyToPlay) this._firstReadyToPlay = false;\n this._createEvent('Play', this._playerId);\n };\n this.videoEl.onplaying = () => {\n this._createEvent('Playing', this._playerId);\n };\n this.videoEl.onpause = () => {\n this.isPlaying = false;\n this._createEvent('Pause', this._playerId);\n };\n if (this._mode === 'fullscreen') {\n // create the video player exit button\n const exitEl: HTMLButtonElement = document.createElement('button');\n exitEl.textContent = 'X';\n exitEl.style.position = 'absolute';\n exitEl.style.left = '1%';\n exitEl.style.top = '5%';\n exitEl.style.width = '5vmin';\n exitEl.style.padding = '0.5%';\n exitEl.style.fontSize = '1.2rem';\n exitEl.style.background = 'rgba(51,51,51,.4)';\n exitEl.style.color = '#fff';\n exitEl.style.visibility = 'hidden';\n exitEl.style.zIndex = (this._zIndex + 4).toString();\n exitEl.style.border = '1px solid rgba(51,51,51,.4)';\n exitEl.style.borderRadius = '20px';\n this._videoContainer.onclick = async () => {\n this._initial = await this._doHide(exitEl, 3000);\n };\n this._videoContainer.ontouchstart = async () => {\n this._initial = await this._doHide(exitEl, 3000);\n };\n\n this._videoContainer.onmousemove = async () => {\n this._initial = await this._doHide(exitEl, 3000);\n };\n\n exitEl.onclick = () => {\n this._createEvent('Exit', this._playerId);\n };\n exitEl.ontouchstart = () => {\n this._createEvent('Exit', this._playerId);\n };\n\n this._videoContainer.appendChild(exitEl);\n this._initial = await this._doHide(exitEl, 3000);\n\n this._goFullscreen();\n }\n }\n return isSet;\n }\n\n private async _goFullscreen(): Promise<void> {\n if (this._container.mozRequestFullScreen) {\n /* Firefox */\n this._container.mozRequestFullScreen();\n } else if (this._container.webkitRequestFullscreen) {\n /* Chrome, Safari & Opera */\n this._container.webkitRequestFullscreen();\n } else if (this._container.msRequestFullscreen) {\n /* IE/Edge */\n this._container.msRequestFullscreen();\n } else if (this._container.requestFullscreen) {\n this._container.requestFullscreen();\n }\n return;\n }\n\n private async _setPlayer(): Promise<boolean> {\n return new Promise((resolve) => {\n if (this.videoEl != null) {\n if (Hls.isSupported() && this._videoType === 'application/x-mpegURL') {\n const hls = new Hls();\n hls.loadSource(this._url);\n hls.attachMedia(this.videoEl);\n hls.once(Hls.Events.FRAG_PARSED, () => {\n if (this.videoEl != null) {\n this.videoEl.muted = true;\n this.videoEl.crossOrigin = 'anonymous';\n resolve(true);\n } else {\n resolve(false);\n }\n });\n } else if (this._videoType === 'video/mp4') {\n // CMAF (fMP4) && MP4\n this.videoEl.src = this._url;\n if (this._url.substring(0, 5) != 'https' && this._url.substring(0, 4) === 'http')\n this.videoEl.crossOrigin = 'anonymous';\n if (this._url.substring(0, 5) === 'https' || this._url.substring(0, 4) === 'http') this.videoEl.muted = true;\n resolve(true);\n } else {\n // Not Supported\n resolve(false);\n }\n this.videoEl.addEventListener('enterpictureinpicture', (event: any) => {\n this.pipWindow = event.pictureInPictureWindow;\n this.pipMode = true;\n this._closeFullscreen();\n });\n\n this.videoEl.addEventListener('leavepictureinpicture', () => {\n this.pipMode = false;\n if (!this._isEnded) {\n this._goFullscreen();\n if (this.videoEl != null) this.videoEl.play();\n }\n });\n } else {\n resolve(false);\n }\n });\n }\n\n private _getVideoType(): videoMimeType | null {\n const sUrl: string = this._url ? this._url : '';\n if (sUrl != null && sUrl.length > 0) {\n Object.entries(videoTypes).forEach(([extension, mimeType]) => {\n // we search for dot + extension (e.g. `.mp4`) for URLs that have the extension in the filename\n // e.g. https://vimeo.com/?file=my-video.mp4\n const hasDotExtension = sUrl.match(new RegExp(`.(${extension})`, 'i'));\n if (hasDotExtension) {\n return (this._videoType = mimeType);\n }\n // we search for the extension (e.g. `m3u8`) for URLs that might have the extension as a query parameter\n // e.g. https://youtube.com/?v=7894289374&type=m3u8\n const hasExtensionInUrl = sUrl.match(new RegExp(`(${extension})`, 'i'));\n if (hasExtensionInUrl) {\n return (this._videoType = mimeType);\n }\n });\n // we check for not supported extensions for URLs that have the extension in the filename\n // e.g. https://vimeo.com/?file=not-supported-extension-video.mkv\n const hasNotSupportedDotExtension = sUrl.match(/\\.(.*)/i);\n if (hasNotSupportedDotExtension) {\n return (this._videoType = null);\n }\n // we check for not supported extensions for URLs that might have the extension as a query parameter\n // e.g. https://youtube.com/?v=3982748927&filetype=mkv\n const hasNotSupportedExtensionInUrl = sUrl.match(\n new RegExp(`(${possibleQueryParameterExtensions.join('|')})=+(.*)&?(?=&|$))`, 'i'),\n );\n if (hasNotSupportedExtensionInUrl) {\n return (this._videoType = null);\n }\n // No extension found, then we assume it's 'mp4' (Match case for '')\n return 'video/mp4';\n }\n // URL was not defined, we return null\n return null;\n }\n\n private async _doHide(exitEl: HTMLButtonElement, duration: number) {\n clearTimeout(this._initial);\n exitEl.style.visibility = 'visible';\n const initial = setTimeout(() => {\n exitEl.style.visibility = 'hidden';\n }, duration);\n return initial;\n }\n private _createEvent(ev: string, playerId: string, msg?: string) {\n const message = msg ? msg : null;\n let event: CustomEvent;\n if (message != null) {\n event = new CustomEvent(`videoPlayer${ev}`, {\n detail: { fromPlayerId: playerId, message: message },\n });\n } else {\n const currentTime: number = this.videoEl ? this.videoEl.currentTime : 0;\n event = new CustomEvent(`videoPlayer${ev}`, {\n detail: { fromPlayerId: playerId, currentTime: currentTime },\n });\n }\n document.dispatchEvent(event);\n }\n private _closeFullscreen() {\n const mydoc: any = document;\n const isInFullScreen: boolean =\n (mydoc.fullscreenElement && mydoc.fullscreenElement !== null) ||\n (mydoc.webkitFullscreenElement && mydoc.webkitFullscreenElement !== null) ||\n (mydoc.mozFullScreenElement && mydoc.mozFullScreenElement !== null) ||\n (mydoc.msFullscreenElement && mydoc.msFullscreenElement !== null);\n if (isInFullScreen) {\n if (mydoc.mozCancelFullScreen) {\n mydoc.mozCancelFullScreen();\n } else if (mydoc.webkitExitFullscreen) {\n mydoc.webkitExitFullscreen();\n } else if (mydoc.msExitFullscreen) {\n mydoc.msExitFullscreen();\n } else if (mydoc.exitFullscreen) {\n mydoc.exitFullscreen();\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import type { VideoPlayerPlugin, capEchoOptions, capVideoPlayerOptions, capVideoPlayerIdOptions, capVideoVolumeOptions, capVideoTimeOptions, capVideoMutedOptions, capVideoRateOptions, capVideoPlayerResult } from './definitions';
|
|
3
|
+
export interface IPlayerSize {
|
|
4
|
+
height: number;
|
|
5
|
+
width: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class VideoPlayerWeb extends WebPlugin implements VideoPlayerPlugin {
|
|
8
|
+
private _players;
|
|
9
|
+
private videoContainer;
|
|
10
|
+
private mode;
|
|
11
|
+
constructor();
|
|
12
|
+
echo(options: capEchoOptions): Promise<capVideoPlayerResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Player initialization
|
|
15
|
+
*
|
|
16
|
+
* @param options
|
|
17
|
+
*/
|
|
18
|
+
initPlayer(options: capVideoPlayerOptions): Promise<capVideoPlayerResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Return if a given playerId is playing
|
|
21
|
+
*
|
|
22
|
+
* @param options
|
|
23
|
+
*/
|
|
24
|
+
isPlaying(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Play the current video from a given playerId
|
|
27
|
+
*
|
|
28
|
+
* @param options
|
|
29
|
+
*/
|
|
30
|
+
play(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Pause the current video from a given playerId
|
|
33
|
+
*
|
|
34
|
+
* @param options
|
|
35
|
+
*/
|
|
36
|
+
pause(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the duration of the current video from a given playerId
|
|
39
|
+
*
|
|
40
|
+
* @param options
|
|
41
|
+
*/
|
|
42
|
+
getDuration(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Set the rate of the current video from a given playerId
|
|
45
|
+
*
|
|
46
|
+
* @param options
|
|
47
|
+
*/
|
|
48
|
+
setRate(options: capVideoRateOptions): Promise<capVideoPlayerResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Get the volume of the current video from a given playerId
|
|
51
|
+
*
|
|
52
|
+
* @param options
|
|
53
|
+
*/
|
|
54
|
+
getRate(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Set the volume of the current video from a given playerId
|
|
57
|
+
*
|
|
58
|
+
* @param options
|
|
59
|
+
*/
|
|
60
|
+
setVolume(options: capVideoVolumeOptions): Promise<capVideoPlayerResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Get the volume of the current video from a given playerId
|
|
63
|
+
*
|
|
64
|
+
* @param options
|
|
65
|
+
*/
|
|
66
|
+
getVolume(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
67
|
+
/**
|
|
68
|
+
* Set the muted property of the current video from a given playerId
|
|
69
|
+
*
|
|
70
|
+
* @param options
|
|
71
|
+
*/
|
|
72
|
+
setMuted(options: capVideoMutedOptions): Promise<capVideoPlayerResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Get the muted property of the current video from a given playerId
|
|
75
|
+
*
|
|
76
|
+
* @param options
|
|
77
|
+
*/
|
|
78
|
+
getMuted(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Set the current time of the current video from a given playerId
|
|
81
|
+
*
|
|
82
|
+
* @param options
|
|
83
|
+
*/
|
|
84
|
+
setCurrentTime(options: capVideoTimeOptions): Promise<capVideoPlayerResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Get the current time of the current video from a given playerId
|
|
87
|
+
*
|
|
88
|
+
* @param options
|
|
89
|
+
*/
|
|
90
|
+
getCurrentTime(options: capVideoPlayerIdOptions): Promise<capVideoPlayerResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Get the current time of the current video from a given playerId
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
stopAllPlayers(): Promise<capVideoPlayerResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Show controller
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
showController(): Promise<capVideoPlayerResult>;
|
|
101
|
+
/**
|
|
102
|
+
* isControllerIsFullyVisible
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
105
|
+
isControllerIsFullyVisible(): Promise<capVideoPlayerResult>;
|
|
106
|
+
/**
|
|
107
|
+
* Exit the current player
|
|
108
|
+
*
|
|
109
|
+
*/
|
|
110
|
+
exitPlayer(): Promise<capVideoPlayerResult>;
|
|
111
|
+
private checkSize;
|
|
112
|
+
private _initializeVideoPlayer;
|
|
113
|
+
private _getContainerElement;
|
|
114
|
+
private handlePlayerPlay;
|
|
115
|
+
private handlePlayerPause;
|
|
116
|
+
private handlePlayerEnded;
|
|
117
|
+
private handlePlayerExit;
|
|
118
|
+
private handlePlayerReady;
|
|
119
|
+
private addListeners;
|
|
120
|
+
private removeListeners;
|
|
121
|
+
}
|