@hopecloud/jetstream-player 0.1.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.
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="JAVA_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="inheritedJdk" />
7
+ <orderEntry type="sourceFolder" forTests="false" />
8
+ </component>
9
+ </module>
package/.idea/misc.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager">
4
+ <output url="file://$PROJECT_DIR$/out" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/hcc-jetstream-player.iml" filepath="$PROJECT_DIR$/.idea/hcc-jetstream-player.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/package.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@hopecloud/jetstream-player",
3
+ "version": "0.1.0",
4
+ "description": "Embeddable player for Jetstream videos",
5
+ "scripts": {
6
+ "build": "tsc"
7
+ },
8
+ "devDependencies": {
9
+ "typescript": "^5.0.2"
10
+ }
11
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './useEmbedPlayerMethods';
2
+ export * from './useEmbedPlayerEvents';
@@ -0,0 +1,47 @@
1
+ type VideoMethod = 'play' | 'pause';
2
+
3
+ interface VideoMessage {
4
+ msg: string;
5
+ src: string;
6
+ }
7
+
8
+ const videoMethods: { [key: string]: string } = {
9
+ play: 'play',
10
+ pause: 'pause',
11
+ };
12
+
13
+ let playerInstance: any;
14
+ let linkHref = '';
15
+
16
+ export const setEmbedPlayerEvents = (player: any, link: string): void => {
17
+ playerInstance = player;
18
+ linkHref = link;
19
+
20
+ playerInstance?.videoJsPlayer?.on('ended', () => {
21
+ const message: VideoMessage = {
22
+ msg: 'onEnded',
23
+ src: linkHref,
24
+ };
25
+ window.parent.postMessage(message, '*');
26
+ });
27
+
28
+ for (const event of ['pause', 'play']) {
29
+ playerInstance?.videoJsPlayer?.on(event, () => {
30
+ const message: VideoMessage = {
31
+ msg: `${event}Video`,
32
+ src: linkHref,
33
+ };
34
+ window.parent.postMessage(message, '*');
35
+ });
36
+ }
37
+ };
38
+
39
+ window.addEventListener('message', ({ data }: MessageEvent<VideoMethod>) => {
40
+ const method = videoMethods[data];
41
+
42
+ if (method) {
43
+ (playerInstance?.videoJsPlayer as any)?.[method]();
44
+ } else {
45
+ console.warn(`Non-available video method: ${data}`);
46
+ }
47
+ });
@@ -0,0 +1,62 @@
1
+ interface IAccumulator {
2
+ iframesWithEmbedVideo: HTMLIFrameElement[];
3
+ allIframes: HTMLIFrameElement[];
4
+ embedVideosSrc: string[];
5
+ }
6
+
7
+ interface IFrameMessage {
8
+ msg: string;
9
+ src: string;
10
+ }
11
+
12
+ let iframesWithEmbedVideo: HTMLIFrameElement[] = [];
13
+ let allIframes: HTMLIFrameElement[] = [];
14
+ let embedVideosSrc: string[] = [];
15
+
16
+ document.addEventListener('DOMContentLoaded', () => {
17
+ ({ iframesWithEmbedVideo, allIframes, embedVideosSrc } = Array.from(document.querySelectorAll('iframe')).reduce<IAccumulator>((acc, iframe) => {
18
+ const { src } = iframe;
19
+ const iframeOrigin = new URL(src).origin;
20
+
21
+ // Check if iframe has embed player origin
22
+ if (iframeOrigin.includes('jstre')) {
23
+ acc.iframesWithEmbedVideo.push(iframe);
24
+ acc.embedVideosSrc.push(src);
25
+ }
26
+ acc.allIframes.push(iframe);
27
+ return acc;
28
+ }, { iframesWithEmbedVideo: [], allIframes: [], embedVideosSrc: [] }));
29
+ });
30
+
31
+ export const embedPlayer = new Proxy({
32
+ play: (index: number) => {},
33
+ pause: (index: number) => {}
34
+ }, {
35
+ get(target, prop) {
36
+ return (index: number) => {
37
+ const method = prop.toString();
38
+ iframesWithEmbedVideo[index].contentWindow?.postMessage(method, '*');
39
+ };
40
+ }
41
+ });
42
+
43
+ type CallbackType = (index: number) => void;
44
+
45
+ const callbacks: { [key: string]: CallbackType } = {};
46
+
47
+ export const onEnded = (callback: CallbackType) => {
48
+ callbacks.onEnded = callback;
49
+ };
50
+ export const playVideo = (callback: CallbackType) => {
51
+ callbacks.playVideo = callback;
52
+ };
53
+ export const pauseVideo = (callback: CallbackType) => {
54
+ callbacks.pauseVideo = callback;
55
+ };
56
+
57
+ window.addEventListener('message', (event: MessageEvent<IFrameMessage>) => {
58
+ const index = embedVideosSrc.findIndex((e) => e === event.data.src);
59
+ if (event.data.msg in callbacks) {
60
+ callbacks[event.data.msg](index);
61
+ }
62
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "module": "esnext",
5
+ "strict": true,
6
+ "esModuleInterop": true,
7
+ "declaration": true,
8
+ "outDir": "./dist",
9
+ },
10
+ "exclude": ["node_modules"],
11
+ "include": [
12
+ "src/**/*.ts"
13
+ ]
14
+ }