@wix/video 1.72.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/LICENSE +21 -0
- package/README.md +126 -0
- package/dist/cjs/Video.js +121 -0
- package/dist/cjs/Video.js.map +1 -0
- package/dist/cjs/Video.module.scss +27 -0
- package/dist/cjs/Video.stories.js +68 -0
- package/dist/cjs/Video.stories.js.map +1 -0
- package/dist/cjs/custom-element/WowVideo.js +88 -0
- package/dist/cjs/custom-element/WowVideo.js.map +1 -0
- package/dist/cjs/custom-element/registry.js +34 -0
- package/dist/cjs/custom-element/registry.js.map +1 -0
- package/dist/cjs/custom-element/utils.js +138 -0
- package/dist/cjs/custom-element/utils.js.map +1 -0
- package/dist/cjs/custom-element/videoLayout.js +120 -0
- package/dist/cjs/custom-element/videoLayout.js.map +1 -0
- package/dist/cjs/customElementInit.js +10 -0
- package/dist/cjs/customElementInit.js.map +1 -0
- package/dist/cjs/dataManifest.js +53 -0
- package/dist/cjs/dataManifest.js.map +1 -0
- package/dist/cjs/external-types.d.js +2 -0
- package/dist/cjs/external-types.d.js.map +1 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/storybook/Container.js +33 -0
- package/dist/cjs/storybook/Container.js.map +1 -0
- package/dist/cjs/storybook/args.js +178 -0
- package/dist/cjs/storybook/args.js.map +1 -0
- package/dist/cjs/test-types.d.js +2 -0
- package/dist/cjs/test-types.d.js.map +1 -0
- package/dist/cjs/types.js +4 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/Video.js +95 -0
- package/dist/esm/Video.js.map +1 -0
- package/dist/esm/Video.module.scss +27 -0
- package/dist/esm/Video.stories.js +47 -0
- package/dist/esm/Video.stories.js.map +1 -0
- package/dist/esm/custom-element/WowVideo.js +83 -0
- package/dist/esm/custom-element/WowVideo.js.map +1 -0
- package/dist/esm/custom-element/registry.js +29 -0
- package/dist/esm/custom-element/registry.js.map +1 -0
- package/dist/esm/custom-element/utils.js +131 -0
- package/dist/esm/custom-element/utils.js.map +1 -0
- package/dist/esm/custom-element/videoLayout.js +117 -0
- package/dist/esm/custom-element/videoLayout.js.map +1 -0
- package/dist/esm/customElementInit.js +13 -0
- package/dist/esm/customElementInit.js.map +1 -0
- package/dist/esm/dataManifest.js +49 -0
- package/dist/esm/dataManifest.js.map +1 -0
- package/dist/esm/external-types.d.js +2 -0
- package/dist/esm/external-types.d.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/storybook/Container.js +21 -0
- package/dist/esm/storybook/Container.js.map +1 -0
- package/dist/esm/storybook/args.js +174 -0
- package/dist/esm/storybook/args.js.map +1 -0
- package/dist/esm/test-types.d.js +2 -0
- package/dist/esm/test-types.d.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/statics/189.chunk.js +35383 -0
- package/dist/statics/189.chunk.js.map +1 -0
- package/dist/statics/189.chunk.min.js +2 -0
- package/dist/statics/189.chunk.min.js.map +1 -0
- package/dist/statics/janet/110.8a580c2d.iframe.bundle.js +10826 -0
- package/dist/statics/janet/110.8a580c2d.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/134.6007b391.iframe.bundle.js +484 -0
- package/dist/statics/janet/134.6007b391.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/134.d48c36bc94ecd2280c0a.manager.bundle.js +1 -0
- package/dist/statics/janet/317.2df397a1e1f34d5a30fd.manager.bundle.js +1 -0
- package/dist/statics/janet/326.e8fcdb36.iframe.bundle.js +1998 -0
- package/dist/statics/janet/326.e8fcdb36.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/326.ff40cdf1778fd94969c8.manager.bundle.js +2 -0
- package/dist/statics/janet/326.ff40cdf1778fd94969c8.manager.bundle.js.LICENSE.txt +31 -0
- package/dist/statics/janet/470.aab6696c.iframe.bundle.js +35380 -0
- package/dist/statics/janet/470.aab6696c.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/599.37d4aa34.iframe.bundle.js +3294 -0
- package/dist/statics/janet/599.37d4aa34.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/599.47c7dacc8997e4d71eac.manager.bundle.js +1 -0
- package/dist/statics/janet/61.5cb88eb5.iframe.bundle.js +2652 -0
- package/dist/statics/janet/61.5cb88eb5.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/61.a575d4776ab0d42da5c8.manager.bundle.js +1 -0
- package/dist/statics/janet/673.59f2a23a.iframe.bundle.js +173 -0
- package/dist/statics/janet/673.59f2a23a.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/725.0db49c6347dfe44ace2d.manager.bundle.js +2 -0
- package/dist/statics/janet/725.0db49c6347dfe44ace2d.manager.bundle.js.LICENSE.txt +8 -0
- package/dist/statics/janet/725.cbba2e4b.iframe.bundle.js +10451 -0
- package/dist/statics/janet/725.cbba2e4b.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/734.428ea23e9773cd26fb57.manager.bundle.js +2 -0
- package/dist/statics/janet/734.428ea23e9773cd26fb57.manager.bundle.js.LICENSE.txt +94 -0
- package/dist/statics/janet/833.75275036.iframe.bundle.js +6777 -0
- package/dist/statics/janet/833.75275036.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/833.ef639b005d7b76723595.manager.bundle.js +2 -0
- package/dist/statics/janet/833.ef639b005d7b76723595.manager.bundle.js.LICENSE.txt +12 -0
- package/dist/statics/janet/W-06.svg +1 -0
- package/dist/statics/janet/favicon.ico +0 -0
- package/dist/statics/janet/iframe.html +364 -0
- package/dist/statics/janet/index.html +59 -0
- package/dist/statics/janet/janet.json +10 -0
- package/dist/statics/janet/main.666d4853f3d62ab20aa1.manager.bundle.js +1 -0
- package/dist/statics/janet/main.d8a321d6.iframe.bundle.js +73260 -0
- package/dist/statics/janet/main.d8a321d6.iframe.bundle.js.map +1 -0
- package/dist/statics/janet/project.json +1 -0
- package/dist/statics/janet/runtime~main.2195d24e465f19ad9c9a.manager.bundle.js +1 -0
- package/dist/statics/janet/w-06.ico +0 -0
- package/dist/statics/manifest.json +4 -0
- package/dist/statics/manifest.min.json +4 -0
- package/dist/statics/video.css +10 -0
- package/dist/statics/video.css.map +1 -0
- package/dist/statics/video.min.css +1 -0
- package/dist/statics/video.rtl.css +8 -0
- package/dist/statics/video.rtl.min.css +1 -0
- package/dist/statics/video.umd.js +5990 -0
- package/dist/statics/video.umd.js.map +1 -0
- package/dist/statics/video.umd.min.js +2 -0
- package/dist/statics/video.umd.min.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/Video.d.ts +5 -0
- package/dist/types/Video.d.ts.map +1 -0
- package/dist/types/Video.stories.d.ts +20 -0
- package/dist/types/Video.stories.d.ts.map +1 -0
- package/dist/types/custom-element/WowVideo.d.ts +4 -0
- package/dist/types/custom-element/WowVideo.d.ts.map +1 -0
- package/dist/types/custom-element/registry.d.ts +3 -0
- package/dist/types/custom-element/registry.d.ts.map +1 -0
- package/dist/types/custom-element/utils.d.ts +11 -0
- package/dist/types/custom-element/utils.d.ts.map +1 -0
- package/dist/types/custom-element/videoLayout.d.ts +35 -0
- package/dist/types/custom-element/videoLayout.d.ts.map +1 -0
- package/dist/types/customElementInit.d.ts +4 -0
- package/dist/types/customElementInit.d.ts.map +1 -0
- package/dist/types/dataManifest.d.ts +2 -0
- package/dist/types/dataManifest.d.ts.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/storybook/Container.d.ts +5 -0
- package/dist/types/storybook/Container.d.ts.map +1 -0
- package/dist/types/storybook/args.d.ts +174 -0
- package/dist/types/storybook/args.d.ts.map +1 -0
- package/dist/types/types.d.ts +62 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["../../src/test-types.d.ts"],"sourcesContent":["/// <reference types=\"@wix/jest-yoshi-preset/types\" />\n"],"mappings":"AAAA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["../../src/types.ts"],"sourcesContent":["import { ImageMedia } from '@wix/image';\n\nexport type VideoSource = {\n quality: '1080p' | '720p' | '480p' | '360p';\n width: number;\n height: number;\n types: {\n format: 'mp4' | 'mp4-luminance';\n uri: string;\n }[];\n};\n\nexport type AdaptiveVideoSource = {\n format: 'hls' | 'dash';\n uri: string;\n};\n\nexport type VideoMedia = {\n uri: string;\n poster?: ImageMedia;\n name?: string;\n sources?: VideoSource[];\n adaptiveSources?: AdaptiveVideoSource[];\n hasAudio?: boolean;\n fps?: number;\n duration?: number;\n};\n\nexport type QualityPolicy = 'adaptive' | 'highest' | 'proportional';\n\nexport type VideoProps = {\n id: string;\n videoMedia: VideoMedia;\n qualityPolicy: QualityPolicy;\n loop: boolean;\n muted: boolean;\n autoplay: boolean;\n motionPart?: string;\n playbackRate?: number;\n posterEffect?: 'fade';\n videoRef: React.RefObject<HTMLVideoElement>;\n focalPoint?: { x: number; y: number };\n onError?: (error: Error) => void;\n};\n\nexport type VideoData = Omit<VideoProps, 'videoRef' | 'id' | 'onError'>;\n\nexport type Timeout = ReturnType<typeof setTimeout>;\n\nexport type EnvConsts = {\n experiments?: Record<string, string | boolean>;\n};\n\nexport type CustomElementServices = {\n isExperimentOpen?: (experiment: string) => boolean;\n mutationService?: any;\n};\n\nexport type WowVideoServices = CustomElementServices & {\n resizeService?: ResizeObserver;\n intersectionService?: IntersectionObserver;\n};\n\nexport type WowVideo = Element & {\n reLayout: () => void;\n observeResize: () => void;\n unobserveIntersect: () => void;\n};\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import styles from './Video.module.scss';
|
|
4
|
+
import { sortQualities } from './custom-element/utils';
|
|
5
|
+
import { initCustomElement } from './customElementInit';
|
|
6
|
+
import { Image, initCustomElement as initImageCustomElement } from '@wix/image';
|
|
7
|
+
if (typeof window !== 'undefined') {
|
|
8
|
+
if (document.readyState === 'loading') {
|
|
9
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
10
|
+
initCustomElement();
|
|
11
|
+
initImageCustomElement();
|
|
12
|
+
}, {
|
|
13
|
+
once: true
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
initCustomElement();
|
|
17
|
+
initImageCustomElement();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const Video = props => {
|
|
21
|
+
const {
|
|
22
|
+
motionPart,
|
|
23
|
+
videoRef,
|
|
24
|
+
videoMedia,
|
|
25
|
+
muted,
|
|
26
|
+
loop,
|
|
27
|
+
autoplay,
|
|
28
|
+
playbackRate = 1,
|
|
29
|
+
posterEffect,
|
|
30
|
+
id,
|
|
31
|
+
qualityPolicy = 'proportional',
|
|
32
|
+
focalPoint,
|
|
33
|
+
onError
|
|
34
|
+
} = props;
|
|
35
|
+
const wowVideoRef = React.useRef(null);
|
|
36
|
+
const videoInfoString = React.useMemo(() => {
|
|
37
|
+
const sortedQualities = sortQualities(videoMedia.sources || []);
|
|
38
|
+
return JSON.stringify({
|
|
39
|
+
...videoMedia,
|
|
40
|
+
playbackRate,
|
|
41
|
+
posterEffect,
|
|
42
|
+
sources: sortedQualities,
|
|
43
|
+
autoplay,
|
|
44
|
+
qualityPolicy,
|
|
45
|
+
focalPoint
|
|
46
|
+
});
|
|
47
|
+
}, [videoMedia, playbackRate, posterEffect, autoplay, qualityPolicy, focalPoint]);
|
|
48
|
+
const VideoPosterImage = videoMedia.poster && /*#__PURE__*/React.createElement(Image, _extends({}, videoMedia.poster, {
|
|
49
|
+
focalPoint: focalPoint,
|
|
50
|
+
id: `videoPoster_${id}`,
|
|
51
|
+
displayMode: "fill",
|
|
52
|
+
alt: videoMedia.name || videoMedia.poster.alt || "",
|
|
53
|
+
quality: videoMedia.poster.quality ? {
|
|
54
|
+
quality: videoMedia.poster.quality
|
|
55
|
+
} : undefined
|
|
56
|
+
}));
|
|
57
|
+
const handleVideoElementError = React.useCallback(event => {
|
|
58
|
+
if (onError) {
|
|
59
|
+
var _videoElement$error;
|
|
60
|
+
const videoElement = event.currentTarget;
|
|
61
|
+
const error = new Error(`Video playback error: ${((_videoElement$error = videoElement.error) == null ? void 0 : _videoElement$error.message) || "Unknown error"}`);
|
|
62
|
+
onError(error);
|
|
63
|
+
}
|
|
64
|
+
}, [onError]);
|
|
65
|
+
const handleAdaptiveVideoError = React.useCallback(event => {
|
|
66
|
+
var _event$detail;
|
|
67
|
+
if (onError && (_event$detail = event.detail) != null && _event$detail.error) {
|
|
68
|
+
onError(event.detail.error);
|
|
69
|
+
}
|
|
70
|
+
}, [onError]);
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
const element = wowVideoRef.current;
|
|
73
|
+
element == null || element.addEventListener("videoerror", handleAdaptiveVideoError);
|
|
74
|
+
return () => {
|
|
75
|
+
element == null || element.removeEventListener("videoerror", handleAdaptiveVideoError);
|
|
76
|
+
};
|
|
77
|
+
}, [onError, handleAdaptiveVideoError]);
|
|
78
|
+
return /*#__PURE__*/React.createElement("wow-video", {
|
|
79
|
+
ref: wowVideoRef,
|
|
80
|
+
"data-video-info": videoInfoString,
|
|
81
|
+
"data-motion-part": motionPart || '',
|
|
82
|
+
class: styles.videoContainer
|
|
83
|
+
}, /*#__PURE__*/React.createElement("video", {
|
|
84
|
+
ref: videoRef,
|
|
85
|
+
className: styles.video,
|
|
86
|
+
crossOrigin: "anonymous",
|
|
87
|
+
playsInline: true,
|
|
88
|
+
muted: muted,
|
|
89
|
+
loop: loop,
|
|
90
|
+
preload: "none",
|
|
91
|
+
onError: handleVideoElementError
|
|
92
|
+
}), VideoPosterImage);
|
|
93
|
+
};
|
|
94
|
+
export default Video;
|
|
95
|
+
//# sourceMappingURL=Video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","styles","sortQualities","initCustomElement","Image","initImageCustomElement","window","document","readyState","addEventListener","once","Video","props","motionPart","videoRef","videoMedia","muted","loop","autoplay","playbackRate","posterEffect","id","qualityPolicy","focalPoint","onError","wowVideoRef","useRef","videoInfoString","useMemo","sortedQualities","sources","JSON","stringify","VideoPosterImage","poster","createElement","_extends","displayMode","alt","name","quality","undefined","handleVideoElementError","useCallback","event","_videoElement$error","videoElement","currentTarget","error","Error","message","handleAdaptiveVideoError","_event$detail","detail","useEffect","element","current","removeEventListener","ref","class","videoContainer","className","video","crossOrigin","playsInline","preload"],"sources":["../../src/Video.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { VideoProps } from './types';\nimport styles from './Video.module.scss';\nimport { sortQualities } from './custom-element/utils';\nimport { initCustomElement } from './customElementInit';\nimport { Image, initCustomElement as initImageCustomElement } from '@wix/image';\n\nif (typeof window !== 'undefined') {\n if (document.readyState === 'loading') {\n document.addEventListener(\n 'DOMContentLoaded',\n () => {\n initCustomElement();\n initImageCustomElement();\n },\n {\n once: true,\n },\n );\n } else {\n initCustomElement();\n initImageCustomElement();\n }\n}\n\nconst Video: React.FC<VideoProps> = (props) => {\n const {\n motionPart,\n videoRef,\n videoMedia,\n muted,\n loop,\n autoplay,\n playbackRate = 1,\n posterEffect,\n id,\n qualityPolicy = 'proportional',\n focalPoint,\n onError,\n } = props;\n\n const wowVideoRef = React.useRef<HTMLElement>(null);\n\n const videoInfoString = React.useMemo(() => {\n const sortedQualities = sortQualities(videoMedia.sources || []);\n return JSON.stringify({\n ...videoMedia,\n playbackRate,\n posterEffect,\n sources: sortedQualities,\n autoplay,\n qualityPolicy,\n focalPoint,\n });\n }, [\n videoMedia,\n playbackRate,\n posterEffect,\n autoplay,\n qualityPolicy,\n focalPoint,\n ]);\n\n const VideoPosterImage = videoMedia.poster && (\n <Image\n {...videoMedia.poster}\n focalPoint={focalPoint}\n id={`videoPoster_${id}`}\n displayMode=\"fill\"\n alt={videoMedia.name || videoMedia.poster.alt || \"\"}\n quality={\n videoMedia.poster.quality\n ? { quality: videoMedia.poster.quality }\n : undefined\n }\n />\n );\n\n const handleVideoElementError = React.useCallback(\n (event: React.SyntheticEvent<HTMLVideoElement, Event>) => {\n if (onError) {\n const videoElement = event.currentTarget;\n const error = new Error(\n `Video playback error: ${\n videoElement.error?.message || \"Unknown error\"\n }`\n );\n onError(error);\n }\n },\n [onError]\n );\n\n const handleAdaptiveVideoError = React.useCallback(\n (event: any) => {\n if (onError && event.detail?.error) {\n onError(event.detail.error);\n }\n },\n [onError]\n );\n\n React.useEffect(() => {\n const element = wowVideoRef.current;\n element?.addEventListener(\"videoerror\", handleAdaptiveVideoError);\n return () => {\n element?.removeEventListener(\"videoerror\", handleAdaptiveVideoError);\n };\n }, [onError, handleAdaptiveVideoError]);\n\n return (\n <wow-video\n ref={wowVideoRef}\n data-video-info={videoInfoString}\n data-motion-part={motionPart || ''}\n class={styles.videoContainer}\n >\n <video\n ref={videoRef}\n className={styles.video}\n crossOrigin=\"anonymous\"\n playsInline={true}\n muted={muted}\n loop={loop}\n preload=\"none\"\n onError={handleVideoElementError}\n />\n {VideoPosterImage}\n </wow-video>\n );\n};\n\nexport default Video;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
.video-container {
|
|
2
|
+
width: 100%;
|
|
3
|
+
height: 100%;
|
|
4
|
+
display: block;
|
|
5
|
+
position: relative;
|
|
6
|
+
container-type: size;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.video-poster-img {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
object-fit: var(--poster-fit, cover);
|
|
13
|
+
object-position: var(--poster-align, center);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.video {
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
top: 0;
|
|
20
|
+
left: 0;
|
|
21
|
+
position: absolute;
|
|
22
|
+
object-fit: var(--video-fit, cover);
|
|
23
|
+
opacity: 0;
|
|
24
|
+
--position-left: calc(50cqw - 1cqh * var(--focal-x, 50) * var(--aspect-ratio, 1));
|
|
25
|
+
--position-top: calc(50cqh - 1cqw * var(--focal-y, 50) / var(--aspect-ratio, 1));
|
|
26
|
+
object-position: clamp(100%, var(--position-left), 0%) clamp(100%, var(--position-top), 0%);
|
|
27
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Video } from './index';
|
|
3
|
+
import { Container } from './storybook/Container';
|
|
4
|
+
import { argTypes, sampleVideo } from './storybook/args';
|
|
5
|
+
const openExperiments = [];
|
|
6
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
7
|
+
const experimentsParam = urlParams.get('experiments');
|
|
8
|
+
((experimentsParam == null ? void 0 : experimentsParam.split(',')) || []).forEach(experiment => {
|
|
9
|
+
openExperiments.push(experiment);
|
|
10
|
+
});
|
|
11
|
+
export default {
|
|
12
|
+
title: 'Video',
|
|
13
|
+
component: Video,
|
|
14
|
+
argTypes
|
|
15
|
+
};
|
|
16
|
+
export const Default = args => {
|
|
17
|
+
const id = 'comp_12345';
|
|
18
|
+
const videoRef = React.useRef(null);
|
|
19
|
+
React.useEffect(() => {
|
|
20
|
+
if (videoRef.current) {
|
|
21
|
+
videoRef.current.load();
|
|
22
|
+
}
|
|
23
|
+
}, [args.autoplay, args.qualityPolicy]);
|
|
24
|
+
const videoProps = {
|
|
25
|
+
loop: Boolean(args.loop),
|
|
26
|
+
muted: Boolean(args.muted),
|
|
27
|
+
playbackRate: args.playbackRate,
|
|
28
|
+
posterEffect: args.posterEffect,
|
|
29
|
+
autoplay: Boolean(args.autoplay),
|
|
30
|
+
videoMedia: sampleVideo.videoMedia,
|
|
31
|
+
id,
|
|
32
|
+
videoRef,
|
|
33
|
+
qualityPolicy: args.qualityPolicy,
|
|
34
|
+
focalPoint: {
|
|
35
|
+
x: args.focalPointX,
|
|
36
|
+
y: args.focalPointY
|
|
37
|
+
},
|
|
38
|
+
onError: error => {
|
|
39
|
+
console.log('Video error:', error);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return /*#__PURE__*/React.createElement(Container, {
|
|
43
|
+
width: args.containerWidth,
|
|
44
|
+
height: args.containerHeight
|
|
45
|
+
}, /*#__PURE__*/React.createElement(Video, videoProps));
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=Video.stories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","Video","Container","argTypes","sampleVideo","openExperiments","urlParams","URLSearchParams","window","location","search","experimentsParam","get","split","forEach","experiment","push","title","component","Default","args","id","videoRef","useRef","useEffect","current","load","autoplay","qualityPolicy","videoProps","loop","Boolean","muted","playbackRate","posterEffect","videoMedia","focalPoint","x","focalPointX","y","focalPointY","onError","error","console","log","createElement","width","containerWidth","height","containerHeight"],"sources":["../../src/Video.stories.tsx"],"sourcesContent":["import React from 'react';\nimport { Meta } from '@wix/yoshi-storybook-dependencies';\nimport { Video } from './index';\nimport { Container } from './storybook/Container';\nimport { argTypes, sampleVideo } from './storybook/args';\nimport type { QualityPolicy, VideoProps } from './types';\n\nconst openExperiments: string[] = [];\n\nconst urlParams = new URLSearchParams(window.location.search);\nconst experimentsParam = urlParams.get('experiments');\n(experimentsParam?.split(',') || []).forEach((experiment) => {\n openExperiments.push(experiment);\n});\n\nexport default {\n title: 'Video',\n component: Video,\n argTypes,\n} as Meta;\n\ntype StoryArgs = {\n qualityPolicy: QualityPolicy;\n uri: string;\n containerHeight: number;\n containerWidth: number;\n loop: boolean;\n muted: boolean;\n autoplay: boolean;\n playbackRate: number;\n posterEffect: 'fade';\n focalPointX: number;\n focalPointY: number;\n};\n\nexport const Default: React.VFC<StoryArgs> = (args) => {\n const id = 'comp_12345';\n const videoRef = React.useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n if (videoRef.current) {\n videoRef.current.load();\n }\n }, [args.autoplay, args.qualityPolicy]);\n\n const videoProps: VideoProps = {\n loop: Boolean(args.loop),\n muted: Boolean(args.muted),\n playbackRate: args.playbackRate,\n posterEffect: args.posterEffect,\n autoplay: Boolean(args.autoplay),\n videoMedia: sampleVideo.videoMedia,\n id,\n videoRef,\n qualityPolicy: args.qualityPolicy,\n focalPoint: { x: args.focalPointX, y: args.focalPointY },\n onError: (error) => {\n console.log('Video error:', error);\n },\n };\n\n return (\n <Container width={args.containerWidth} height={args.containerHeight}>\n <Video {...videoProps} />\n </Container>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AAEzB,SAASC,KAAK,QAAQ,SAAS;AAC/B,SAASC,SAAS,QAAQ,uBAAuB;AACjD,SAASC,QAAQ,EAAEC,WAAW,QAAQ,kBAAkB;AAGxD,MAAMC,eAAyB,GAAG,EAAE;AAEpC,MAAMC,SAAS,GAAG,IAAIC,eAAe,CAACC,MAAM,CAACC,QAAQ,CAACC,MAAM,CAAC;AAC7D,MAAMC,gBAAgB,GAAGL,SAAS,CAACM,GAAG,CAAC,aAAa,CAAC;AACrD,CAAC,CAAAD,gBAAgB,oBAAhBA,gBAAgB,CAAEE,KAAK,CAAC,GAAG,CAAC,KAAI,EAAE,EAAEC,OAAO,CAAEC,UAAU,IAAK;EAC3DV,eAAe,CAACW,IAAI,CAACD,UAAU,CAAC;AAClC,CAAC,CAAC;AAEF,eAAe;EACbE,KAAK,EAAE,OAAO;EACdC,SAAS,EAAEjB,KAAK;EAChBE;AACF,CAAC;AAgBD,OAAO,MAAMgB,OAA6B,GAAIC,IAAI,IAAK;EACrD,MAAMC,EAAE,GAAG,YAAY;EACvB,MAAMC,QAAQ,GAAGtB,KAAK,CAACuB,MAAM,CAAmB,IAAI,CAAC;EAErDvB,KAAK,CAACwB,SAAS,CAAC,MAAM;IACpB,IAAIF,QAAQ,CAACG,OAAO,EAAE;MACpBH,QAAQ,CAACG,OAAO,CAACC,IAAI,CAAC,CAAC;IACzB;EACF,CAAC,EAAE,CAACN,IAAI,CAACO,QAAQ,EAAEP,IAAI,CAACQ,aAAa,CAAC,CAAC;EAEvC,MAAMC,UAAsB,GAAG;IAC7BC,IAAI,EAAEC,OAAO,CAACX,IAAI,CAACU,IAAI,CAAC;IACxBE,KAAK,EAAED,OAAO,CAACX,IAAI,CAACY,KAAK,CAAC;IAC1BC,YAAY,EAAEb,IAAI,CAACa,YAAY;IAC/BC,YAAY,EAAEd,IAAI,CAACc,YAAY;IAC/BP,QAAQ,EAAEI,OAAO,CAACX,IAAI,CAACO,QAAQ,CAAC;IAChCQ,UAAU,EAAE/B,WAAW,CAAC+B,UAAU;IAClCd,EAAE;IACFC,QAAQ;IACRM,aAAa,EAAER,IAAI,CAACQ,aAAa;IACjCQ,UAAU,EAAE;MAAEC,CAAC,EAAEjB,IAAI,CAACkB,WAAW;MAAEC,CAAC,EAAEnB,IAAI,CAACoB;IAAY,CAAC;IACxDC,OAAO,EAAGC,KAAK,IAAK;MAClBC,OAAO,CAACC,GAAG,CAAC,cAAc,EAAEF,KAAK,CAAC;IACpC;EACF,CAAC;EAED,oBACE1C,KAAA,CAAA6C,aAAA,CAAC3C,SAAS;IAAC4C,KAAK,EAAE1B,IAAI,CAAC2B,cAAe;IAACC,MAAM,EAAE5B,IAAI,CAAC6B;EAAgB,gBAClEjD,KAAA,CAAA6C,aAAA,CAAC5C,KAAK,EAAK4B,UAAa,CACf,CAAC;AAEhB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import videoLayout from './videoLayout';
|
|
3
|
+
function wowVideoFactory(services, contextWindow) {
|
|
4
|
+
return class WowVideo extends contextWindow.HTMLElement {
|
|
5
|
+
constructor() {
|
|
6
|
+
super();
|
|
7
|
+
_defineProperty(this, "timeoutId", void 0);
|
|
8
|
+
this.timeoutId = null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Dispatch a custom error event that bubbles up
|
|
13
|
+
*/
|
|
14
|
+
dispatchVideoError(error) {
|
|
15
|
+
this.dispatchEvent(new CustomEvent('videoerror', {
|
|
16
|
+
detail: {
|
|
17
|
+
error
|
|
18
|
+
},
|
|
19
|
+
bubbles: true
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
attributeChangedCallback(_, oldValue) {
|
|
23
|
+
if (oldValue) {
|
|
24
|
+
this.reLayout();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
connectedCallback() {
|
|
28
|
+
var _services$intersectio;
|
|
29
|
+
(_services$intersectio = services.intersectionService) == null || _services$intersectio.observe(this);
|
|
30
|
+
}
|
|
31
|
+
disconnectedCallback() {
|
|
32
|
+
this.unobserveIntersect();
|
|
33
|
+
}
|
|
34
|
+
unobserveIntersect() {
|
|
35
|
+
var _services$intersectio2;
|
|
36
|
+
(_services$intersectio2 = services.intersectionService) == null || _services$intersectio2.unobserve(this);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Check if the user prefers reduced motion
|
|
41
|
+
*
|
|
42
|
+
* @returns {boolean} True if reduced motion is preferred
|
|
43
|
+
*/
|
|
44
|
+
isPrefersReducedMotion() {
|
|
45
|
+
return contextWindow.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
46
|
+
}
|
|
47
|
+
reLayout() {
|
|
48
|
+
if (!this.dataset.videoInfo) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const {
|
|
52
|
+
uri,
|
|
53
|
+
sources,
|
|
54
|
+
adaptiveSources,
|
|
55
|
+
autoplay,
|
|
56
|
+
playbackRate,
|
|
57
|
+
posterEffect,
|
|
58
|
+
qualityPolicy,
|
|
59
|
+
focalPoint,
|
|
60
|
+
duration
|
|
61
|
+
} = JSON.parse(this.dataset.videoInfo);
|
|
62
|
+
const prefersReducedMotion = this.isPrefersReducedMotion();
|
|
63
|
+
const autoPlayAllowed = !prefersReducedMotion && autoplay;
|
|
64
|
+
const videoNode = this.querySelector('video');
|
|
65
|
+
const poster = this.querySelector('img');
|
|
66
|
+
services.mutationService.measure(async () => {
|
|
67
|
+
const measures = await videoLayout.measure(videoNode, this, qualityPolicy, uri, sources, adaptiveSources, duration, error => this.dispatchVideoError(error));
|
|
68
|
+
const {
|
|
69
|
+
needsSrcUpdate,
|
|
70
|
+
patchVideoSource
|
|
71
|
+
} = measures;
|
|
72
|
+
services.mutationService.mutate(() => {
|
|
73
|
+
videoLayout.mutate(poster, videoNode, autoPlayAllowed, needsSrcUpdate, posterEffect, playbackRate, patchVideoSource, sources, focalPoint);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
static get observedAttributes() {
|
|
78
|
+
return ['data-video-info'];
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export default wowVideoFactory;
|
|
83
|
+
//# sourceMappingURL=WowVideo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["videoLayout","wowVideoFactory","services","contextWindow","WowVideo","HTMLElement","constructor","_defineProperty","timeoutId","dispatchVideoError","error","dispatchEvent","CustomEvent","detail","bubbles","attributeChangedCallback","_","oldValue","reLayout","connectedCallback","_services$intersectio","intersectionService","observe","disconnectedCallback","unobserveIntersect","_services$intersectio2","unobserve","isPrefersReducedMotion","matchMedia","matches","dataset","videoInfo","uri","sources","adaptiveSources","autoplay","playbackRate","posterEffect","qualityPolicy","focalPoint","duration","JSON","parse","prefersReducedMotion","autoPlayAllowed","videoNode","querySelector","poster","mutationService","measure","measures","needsSrcUpdate","patchVideoSource","mutate","observedAttributes"],"sources":["../../../src/custom-element/WowVideo.ts"],"sourcesContent":["import videoLayout from './videoLayout';\nimport type { WowVideoServices, Timeout } from '../types';\n\nfunction wowVideoFactory(\n services: WowVideoServices,\n contextWindow: Window & typeof globalThis,\n): any {\n return class WowVideo extends contextWindow.HTMLElement {\n timeoutId: Timeout | null;\n\n constructor() {\n super();\n this.timeoutId = null;\n }\n\n /**\n * Dispatch a custom error event that bubbles up\n */\n dispatchVideoError(error: Error) {\n this.dispatchEvent(\n new CustomEvent('videoerror', {\n detail: { error },\n bubbles: true,\n }),\n );\n }\n\n attributeChangedCallback(_: string, oldValue: string) {\n if (oldValue) {\n this.reLayout();\n }\n }\n\n connectedCallback() {\n services.intersectionService?.observe(this);\n }\n\n disconnectedCallback() {\n this.unobserveIntersect();\n }\n\n unobserveIntersect() {\n services.intersectionService?.unobserve(this);\n }\n\n /**\n * Check if the user prefers reduced motion\n *\n * @returns {boolean} True if reduced motion is preferred\n */\n isPrefersReducedMotion(): boolean {\n return contextWindow.matchMedia('(prefers-reduced-motion: reduce)')\n .matches;\n }\n\n reLayout() {\n if (!this.dataset.videoInfo) {\n return;\n }\n\n const {\n uri,\n sources,\n adaptiveSources,\n autoplay,\n playbackRate,\n posterEffect,\n qualityPolicy,\n focalPoint,\n duration,\n } = JSON.parse(this.dataset.videoInfo);\n\n const prefersReducedMotion = this.isPrefersReducedMotion();\n const autoPlayAllowed = !prefersReducedMotion && autoplay;\n\n const videoNode = this.querySelector('video') as HTMLVideoElement;\n const poster = this.querySelector('img') as HTMLImageElement;\n\n services.mutationService.measure(async () => {\n const measures = await videoLayout.measure(\n videoNode,\n this,\n qualityPolicy,\n uri,\n sources,\n adaptiveSources,\n duration,\n (error: Error) => this.dispatchVideoError(error),\n );\n\n const { needsSrcUpdate, patchVideoSource } = measures;\n services.mutationService.mutate(() => {\n videoLayout.mutate(\n poster,\n videoNode,\n autoPlayAllowed,\n needsSrcUpdate,\n posterEffect,\n playbackRate,\n patchVideoSource,\n sources,\n focalPoint,\n );\n });\n });\n }\n\n static get observedAttributes() {\n return ['data-video-info'];\n }\n };\n}\n\nexport default wowVideoFactory;\n"],"mappings":";AAAA,OAAOA,WAAW,MAAM,eAAe;AAGvC,SAASC,eAAeA,CACtBC,QAA0B,EAC1BC,aAAyC,EACpC;EACL,OAAO,MAAMC,QAAQ,SAASD,aAAa,CAACE,WAAW,CAAC;IAGtDC,WAAWA,CAAA,EAAG;MACZ,KAAK,CAAC,CAAC;MAACC,eAAA;MACR,IAAI,CAACC,SAAS,GAAG,IAAI;IACvB;;IAEA;AACJ;AACA;IACIC,kBAAkBA,CAACC,KAAY,EAAE;MAC/B,IAAI,CAACC,aAAa,CAChB,IAAIC,WAAW,CAAC,YAAY,EAAE;QAC5BC,MAAM,EAAE;UAAEH;QAAM,CAAC;QACjBI,OAAO,EAAE;MACX,CAAC,CACH,CAAC;IACH;IAEAC,wBAAwBA,CAACC,CAAS,EAAEC,QAAgB,EAAE;MACpD,IAAIA,QAAQ,EAAE;QACZ,IAAI,CAACC,QAAQ,CAAC,CAAC;MACjB;IACF;IAEAC,iBAAiBA,CAAA,EAAG;MAAA,IAAAC,qBAAA;MAClB,CAAAA,qBAAA,GAAAlB,QAAQ,CAACmB,mBAAmB,aAA5BD,qBAAA,CAA8BE,OAAO,CAAC,IAAI,CAAC;IAC7C;IAEAC,oBAAoBA,CAAA,EAAG;MACrB,IAAI,CAACC,kBAAkB,CAAC,CAAC;IAC3B;IAEAA,kBAAkBA,CAAA,EAAG;MAAA,IAAAC,sBAAA;MACnB,CAAAA,sBAAA,GAAAvB,QAAQ,CAACmB,mBAAmB,aAA5BI,sBAAA,CAA8BC,SAAS,CAAC,IAAI,CAAC;IAC/C;;IAEA;AACJ;AACA;AACA;AACA;IACIC,sBAAsBA,CAAA,EAAY;MAChC,OAAOxB,aAAa,CAACyB,UAAU,CAAC,kCAAkC,CAAC,CAChEC,OAAO;IACZ;IAEAX,QAAQA,CAAA,EAAG;MACT,IAAI,CAAC,IAAI,CAACY,OAAO,CAACC,SAAS,EAAE;QAC3B;MACF;MAEA,MAAM;QACJC,GAAG;QACHC,OAAO;QACPC,eAAe;QACfC,QAAQ;QACRC,YAAY;QACZC,YAAY;QACZC,aAAa;QACbC,UAAU;QACVC;MACF,CAAC,GAAGC,IAAI,CAACC,KAAK,CAAC,IAAI,CAACZ,OAAO,CAACC,SAAS,CAAC;MAEtC,MAAMY,oBAAoB,GAAG,IAAI,CAAChB,sBAAsB,CAAC,CAAC;MAC1D,MAAMiB,eAAe,GAAG,CAACD,oBAAoB,IAAIR,QAAQ;MAEzD,MAAMU,SAAS,GAAG,IAAI,CAACC,aAAa,CAAC,OAAO,CAAqB;MACjE,MAAMC,MAAM,GAAG,IAAI,CAACD,aAAa,CAAC,KAAK,CAAqB;MAE5D5C,QAAQ,CAAC8C,eAAe,CAACC,OAAO,CAAC,YAAY;QAC3C,MAAMC,QAAQ,GAAG,MAAMlD,WAAW,CAACiD,OAAO,CACxCJ,SAAS,EACT,IAAI,EACJP,aAAa,EACbN,GAAG,EACHC,OAAO,EACPC,eAAe,EACfM,QAAQ,EACP9B,KAAY,IAAK,IAAI,CAACD,kBAAkB,CAACC,KAAK,CACjD,CAAC;QAED,MAAM;UAAEyC,cAAc;UAAEC;QAAiB,CAAC,GAAGF,QAAQ;QACrDhD,QAAQ,CAAC8C,eAAe,CAACK,MAAM,CAAC,MAAM;UACpCrD,WAAW,CAACqD,MAAM,CAChBN,MAAM,EACNF,SAAS,EACTD,eAAe,EACfO,cAAc,EACdd,YAAY,EACZD,YAAY,EACZgB,gBAAgB,EAChBnB,OAAO,EACPM,UACF,CAAC;QACH,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ;IAEA,WAAWe,kBAAkBA,CAAA,EAAG;MAC9B,OAAO,CAAC,iBAAiB,CAAC;IAC5B;EACF,CAAC;AACH;AAEA,eAAerD,eAAe","ignoreList":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import wowVideoFactory from './WowVideo';
|
|
2
|
+
import fastdom from 'fastdom';
|
|
3
|
+
export function init(contextWindow, services) {
|
|
4
|
+
contextWindow = contextWindow || window;
|
|
5
|
+
const elementName = 'wow-video';
|
|
6
|
+
if (contextWindow.customElements.get(elementName) === undefined) {
|
|
7
|
+
let intersectionObserver;
|
|
8
|
+
if (contextWindow.IntersectionObserver) {
|
|
9
|
+
intersectionObserver = new IntersectionObserver(entries => entries.map(entry => {
|
|
10
|
+
if (entry.isIntersecting) {
|
|
11
|
+
const target = entry.target;
|
|
12
|
+
target.unobserveIntersect();
|
|
13
|
+
target.reLayout();
|
|
14
|
+
}
|
|
15
|
+
return entry;
|
|
16
|
+
}), {
|
|
17
|
+
rootMargin: '50% 100%'
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const WowVideo = wowVideoFactory({
|
|
21
|
+
mutationService: fastdom,
|
|
22
|
+
intersectionService: intersectionObserver,
|
|
23
|
+
...services
|
|
24
|
+
}, contextWindow);
|
|
25
|
+
contextWindow.customElements.define(elementName, WowVideo);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["wowVideoFactory","fastdom","init","contextWindow","services","window","elementName","customElements","get","undefined","intersectionObserver","IntersectionObserver","entries","map","entry","isIntersecting","target","unobserveIntersect","reLayout","rootMargin","WowVideo","mutationService","intersectionService","define"],"sources":["../../../src/custom-element/registry.ts"],"sourcesContent":["import wowVideoFactory from './WowVideo';\nimport fastdom from 'fastdom';\n\nimport type {\n CustomElementServices,\n WowVideo,\n WowVideoServices,\n} from '../types';\n\nexport function init(\n contextWindow: Window & typeof globalThis,\n services: CustomElementServices,\n) {\n contextWindow = contextWindow || window;\n const elementName = 'wow-video';\n\n if (contextWindow.customElements.get(elementName) === undefined) {\n let intersectionObserver: IntersectionObserver | undefined;\n\n if (contextWindow.IntersectionObserver) {\n intersectionObserver = new IntersectionObserver(\n (entries: IntersectionObserverEntry[]) =>\n entries.map((entry) => {\n if (entry.isIntersecting) {\n const target = entry.target as WowVideo;\n target.unobserveIntersect();\n target.reLayout();\n }\n return entry;\n }),\n {\n rootMargin: '50% 100%',\n },\n );\n }\n\n const WowVideo = wowVideoFactory(\n {\n mutationService: fastdom,\n intersectionService: intersectionObserver,\n ...services,\n } as WowVideoServices,\n contextWindow!,\n );\n contextWindow!.customElements.define(elementName, WowVideo);\n }\n\n return;\n}\n"],"mappings":"AAAA,OAAOA,eAAe,MAAM,YAAY;AACxC,OAAOC,OAAO,MAAM,SAAS;AAQ7B,OAAO,SAASC,IAAIA,CAClBC,aAAyC,EACzCC,QAA+B,EAC/B;EACAD,aAAa,GAAGA,aAAa,IAAIE,MAAM;EACvC,MAAMC,WAAW,GAAG,WAAW;EAE/B,IAAIH,aAAa,CAACI,cAAc,CAACC,GAAG,CAACF,WAAW,CAAC,KAAKG,SAAS,EAAE;IAC/D,IAAIC,oBAAsD;IAE1D,IAAIP,aAAa,CAACQ,oBAAoB,EAAE;MACtCD,oBAAoB,GAAG,IAAIC,oBAAoB,CAC5CC,OAAoC,IACnCA,OAAO,CAACC,GAAG,CAAEC,KAAK,IAAK;QACrB,IAAIA,KAAK,CAACC,cAAc,EAAE;UACxB,MAAMC,MAAM,GAAGF,KAAK,CAACE,MAAkB;UACvCA,MAAM,CAACC,kBAAkB,CAAC,CAAC;UAC3BD,MAAM,CAACE,QAAQ,CAAC,CAAC;QACnB;QACA,OAAOJ,KAAK;MACd,CAAC,CAAC,EACJ;QACEK,UAAU,EAAE;MACd,CACF,CAAC;IACH;IAEA,MAAMC,QAAQ,GAAGpB,eAAe,CAC9B;MACEqB,eAAe,EAAEpB,OAAO;MACxBqB,mBAAmB,EAAEZ,oBAAoB;MACzC,GAAGN;IACL,CAAC,EACDD,aACF,CAAC;IACDA,aAAa,CAAEI,cAAc,CAACgB,MAAM,CAACjB,WAAW,EAAEc,QAAQ,CAAC;EAC7D;EAEA;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const STATIC_VIDEO_URL = 'https://video.wixstatic.com/';
|
|
2
|
+
const STATIC_ADAPTIVE_VIDEO_URL = 'https://files.wix.com/';
|
|
3
|
+
const isAbsoluteUrl = url => url.startsWith('http://') || url.startsWith('https://');
|
|
4
|
+
export function sortQualities(sources) {
|
|
5
|
+
return sources.sort((a, b) => a.width * a.height - b.width * b.height);
|
|
6
|
+
}
|
|
7
|
+
function getCompleteUrl(url, staticVideoUrl) {
|
|
8
|
+
const completeUrl = isAbsoluteUrl(url) ? new URL(url) : new URL(url, staticVideoUrl);
|
|
9
|
+
return completeUrl.href;
|
|
10
|
+
}
|
|
11
|
+
function getVideoQualityBySize(sources, _ref) {
|
|
12
|
+
let {
|
|
13
|
+
width,
|
|
14
|
+
height
|
|
15
|
+
} = _ref;
|
|
16
|
+
const targetQuality = sources.find(value => value.width * value.height > width * height);
|
|
17
|
+
return targetQuality || sources[sources.length - 1];
|
|
18
|
+
}
|
|
19
|
+
function getScaleFactor(containerWidth, containerHeight, videoWidth, videoHeight) {
|
|
20
|
+
return {
|
|
21
|
+
wScale: containerWidth / videoWidth,
|
|
22
|
+
hScale: containerHeight / videoHeight
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getVideoDimension(videoScale, videoWidth, videoHeight) {
|
|
26
|
+
const scale = Math.min(videoScale.wScale, videoScale.hScale);
|
|
27
|
+
return {
|
|
28
|
+
width: Math.round(videoWidth * scale),
|
|
29
|
+
height: Math.round(videoHeight * scale)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function setVideoFocalPoint(videoNode, focalPoint) {
|
|
33
|
+
const focalX = (focalPoint == null ? void 0 : focalPoint.x) ?? 50;
|
|
34
|
+
const focalY = (focalPoint == null ? void 0 : focalPoint.y) ?? 50;
|
|
35
|
+
videoNode.style.setProperty('--focal-x', focalX.toString());
|
|
36
|
+
videoNode.style.setProperty('--focal-y', focalY.toString());
|
|
37
|
+
}
|
|
38
|
+
export async function getVideoSource(width, height, uri, qualityPolicy, sources, adaptiveSources, duration, onError) {
|
|
39
|
+
const hasProgressiveSources = sources && sources.length > 0;
|
|
40
|
+
const hasAbsoluteUri = uri && isAbsoluteUrl(uri);
|
|
41
|
+
const shouldSkipAdaptiveShortVideo = duration && duration < 40;
|
|
42
|
+
if (qualityPolicy === 'adaptive' && adaptiveSources && adaptiveSources.length > 0 && !shouldSkipAdaptiveShortVideo) {
|
|
43
|
+
const hlsSource = adaptiveSources.find(s => s.format === 'hls');
|
|
44
|
+
const Hls = await import('hls.js');
|
|
45
|
+
if (hlsSource && Hls && Hls.default.isSupported()) {
|
|
46
|
+
const videoSourceUrl = getCompleteUrl(hlsSource.uri, STATIC_ADAPTIVE_VIDEO_URL);
|
|
47
|
+
const patchVideoSource = videoNode => {
|
|
48
|
+
const hls = new Hls.default();
|
|
49
|
+
hls.loadSource(videoSourceUrl);
|
|
50
|
+
hls.attachMedia(videoNode);
|
|
51
|
+
hls.on(Hls.default.Events.ERROR, (_, data) => {
|
|
52
|
+
if (data.fatal) {
|
|
53
|
+
switch (data.type) {
|
|
54
|
+
case Hls.default.ErrorTypes.NETWORK_ERROR:
|
|
55
|
+
hls.startLoad();
|
|
56
|
+
if (onError) {
|
|
57
|
+
onError(new Error(`HLS Network Error: ${data.details}.\nAttempting to reconnect...`));
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case Hls.default.ErrorTypes.MEDIA_ERROR:
|
|
61
|
+
hls.recoverMediaError();
|
|
62
|
+
if (onError) {
|
|
63
|
+
onError(new Error(`HLS Media Error: ${data.details}.\nAttempting to recover...`));
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
hls.destroy();
|
|
68
|
+
if (onError) {
|
|
69
|
+
onError(new Error(`HLS Unknown Error: ${data.details}.\nUnrecoverable playback error`));
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
videoSourceUrl,
|
|
78
|
+
patchVideoSource
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (hasProgressiveSources) {
|
|
83
|
+
const highestQuality = sources[sources.length - 1];
|
|
84
|
+
if (qualityPolicy === 'highest') {
|
|
85
|
+
var _highestQuality$types;
|
|
86
|
+
const url = (_highestQuality$types = highestQuality.types.find(type => type.format === 'mp4')) == null ? void 0 : _highestQuality$types.uri;
|
|
87
|
+
if (url) {
|
|
88
|
+
const videoSourceUrl = getCompleteUrl(url, STATIC_VIDEO_URL);
|
|
89
|
+
return {
|
|
90
|
+
videoSourceUrl,
|
|
91
|
+
patchVideoSource: videoNode => {
|
|
92
|
+
videoNode.src = videoSourceUrl;
|
|
93
|
+
videoNode.load();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
var _targetQuality$types$;
|
|
99
|
+
const videoWidth = parseInt(highestQuality.width.toString(), 10);
|
|
100
|
+
const videoHeight = parseInt(highestQuality.height.toString(), 10);
|
|
101
|
+
const scaleFactor = getScaleFactor(width, height, videoWidth, videoHeight);
|
|
102
|
+
const videoScaledDimensions = getVideoDimension(scaleFactor, videoWidth, videoHeight);
|
|
103
|
+
const targetQuality = getVideoQualityBySize(sources, videoScaledDimensions);
|
|
104
|
+
const url = (_targetQuality$types$ = targetQuality.types.find(type => type.format === 'mp4')) == null ? void 0 : _targetQuality$types$.uri;
|
|
105
|
+
if (url) {
|
|
106
|
+
const videoSourceUrl = getCompleteUrl(url, STATIC_VIDEO_URL);
|
|
107
|
+
return {
|
|
108
|
+
videoSourceUrl,
|
|
109
|
+
patchVideoSource: videoNode => {
|
|
110
|
+
videoNode.src = videoSourceUrl;
|
|
111
|
+
videoNode.load();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (hasAbsoluteUri) {
|
|
118
|
+
return {
|
|
119
|
+
videoSourceUrl: uri,
|
|
120
|
+
patchVideoSource: videoNode => {
|
|
121
|
+
videoNode.src = uri;
|
|
122
|
+
videoNode.load();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
videoSourceUrl: '',
|
|
128
|
+
patchVideoSource: () => {}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["STATIC_VIDEO_URL","STATIC_ADAPTIVE_VIDEO_URL","isAbsoluteUrl","url","startsWith","sortQualities","sources","sort","a","b","width","height","getCompleteUrl","staticVideoUrl","completeUrl","URL","href","getVideoQualityBySize","_ref","targetQuality","find","value","length","getScaleFactor","containerWidth","containerHeight","videoWidth","videoHeight","wScale","hScale","getVideoDimension","videoScale","scale","Math","min","round","setVideoFocalPoint","videoNode","focalPoint","focalX","x","focalY","y","style","setProperty","toString","getVideoSource","uri","qualityPolicy","adaptiveSources","duration","onError","hasProgressiveSources","hasAbsoluteUri","shouldSkipAdaptiveShortVideo","hlsSource","s","format","Hls","default","isSupported","videoSourceUrl","patchVideoSource","hls","loadSource","attachMedia","on","Events","ERROR","_","data","fatal","type","ErrorTypes","NETWORK_ERROR","startLoad","Error","details","MEDIA_ERROR","recoverMediaError","destroy","highestQuality","_highestQuality$types","types","src","load","_targetQuality$types$","parseInt","scaleFactor","videoScaledDimensions"],"sources":["../../../src/custom-element/utils.ts"],"sourcesContent":["import { AdaptiveVideoSource, QualityPolicy, VideoSource } from '../types';\n\nconst STATIC_VIDEO_URL = 'https://video.wixstatic.com/';\nconst STATIC_ADAPTIVE_VIDEO_URL = 'https://files.wix.com/';\n\nconst isAbsoluteUrl = (url: string) =>\n url.startsWith('http://') || url.startsWith('https://');\n\nexport function sortQualities(sources: VideoSource[]) {\n return sources.sort((a, b) => a.width * a.height - b.width * b.height);\n}\n\nfunction getCompleteUrl(url: string, staticVideoUrl?: string): string {\n const completeUrl = isAbsoluteUrl(url)\n ? new URL(url)\n : new URL(url, staticVideoUrl);\n return completeUrl.href;\n}\n\nfunction getVideoQualityBySize(\n sources: VideoSource[],\n { width, height }: { width: number; height: number },\n): VideoSource {\n const targetQuality = sources.find(\n (value) => value.width * value.height > width * height,\n );\n\n return targetQuality || sources[sources.length - 1];\n}\n\nfunction getScaleFactor(\n containerWidth: number,\n containerHeight: number,\n videoWidth: number,\n videoHeight: number,\n): { wScale: number; hScale: number } {\n return {\n wScale: containerWidth / videoWidth,\n hScale: containerHeight / videoHeight,\n };\n}\n\nfunction getVideoDimension(\n videoScale: { wScale: number; hScale: number },\n videoWidth: number,\n videoHeight: number,\n): { width: number; height: number } {\n const scale: number = Math.min(videoScale.wScale, videoScale.hScale);\n\n return {\n width: Math.round(videoWidth * scale),\n height: Math.round(videoHeight * scale),\n };\n}\n\nexport function setVideoFocalPoint(\n videoNode: HTMLVideoElement,\n focalPoint: { x: number; y: number },\n) {\n const focalX = focalPoint?.x ?? 50;\n const focalY = focalPoint?.y ?? 50;\n videoNode.style.setProperty('--focal-x', focalX.toString());\n videoNode.style.setProperty('--focal-y', focalY.toString());\n}\n\nexport async function getVideoSource(\n width: number,\n height: number,\n uri: string,\n qualityPolicy: QualityPolicy,\n sources?: VideoSource[],\n adaptiveSources?: AdaptiveVideoSource[],\n duration?: number,\n onError?: (error: Error) => void,\n): Promise<{\n videoSourceUrl: string;\n patchVideoSource: (videoNode: HTMLVideoElement) => void;\n}> {\n const hasProgressiveSources = sources && sources.length > 0;\n const hasAbsoluteUri = uri && isAbsoluteUrl(uri);\n const shouldSkipAdaptiveShortVideo = duration && duration < 40;\n\n if (\n qualityPolicy === 'adaptive' &&\n adaptiveSources &&\n adaptiveSources.length > 0 &&\n !shouldSkipAdaptiveShortVideo\n ) {\n const hlsSource = adaptiveSources.find((s) => s.format === 'hls');\n const Hls = await import('hls.js');\n if (hlsSource && Hls && Hls.default.isSupported()) {\n const videoSourceUrl = getCompleteUrl(\n hlsSource.uri,\n STATIC_ADAPTIVE_VIDEO_URL,\n );\n const patchVideoSource = (videoNode: HTMLVideoElement) => {\n const hls = new Hls.default();\n hls.loadSource(videoSourceUrl);\n hls.attachMedia(videoNode);\n\n hls.on(Hls.default.Events.ERROR, (_, data) => {\n if (data.fatal) {\n switch (data.type) {\n case Hls.default.ErrorTypes.NETWORK_ERROR:\n hls.startLoad();\n if (onError) {\n onError(\n new Error(\n `HLS Network Error: ${data.details}.\\nAttempting to reconnect...`,\n ),\n );\n }\n break;\n case Hls.default.ErrorTypes.MEDIA_ERROR:\n hls.recoverMediaError();\n if (onError) {\n onError(\n new Error(\n `HLS Media Error: ${data.details}.\\nAttempting to recover...`,\n ),\n );\n }\n break;\n default:\n hls.destroy();\n if (onError) {\n onError(\n new Error(\n `HLS Unknown Error: ${data.details}.\\nUnrecoverable playback error`,\n ),\n );\n }\n break;\n }\n }\n });\n };\n return { videoSourceUrl, patchVideoSource };\n }\n }\n if (hasProgressiveSources) {\n const highestQuality = sources[sources.length - 1];\n if (qualityPolicy === 'highest') {\n const url = highestQuality.types.find(\n (type) => type.format === 'mp4',\n )?.uri;\n if (url) {\n const videoSourceUrl = getCompleteUrl(url, STATIC_VIDEO_URL);\n return {\n videoSourceUrl,\n patchVideoSource: (videoNode: HTMLVideoElement) => {\n videoNode.src = videoSourceUrl;\n videoNode.load();\n },\n };\n }\n } else {\n const videoWidth = parseInt(highestQuality.width.toString(), 10);\n const videoHeight = parseInt(highestQuality.height.toString(), 10);\n const scaleFactor = getScaleFactor(\n width,\n height,\n videoWidth,\n videoHeight,\n );\n const videoScaledDimensions = getVideoDimension(\n scaleFactor,\n videoWidth,\n videoHeight,\n );\n const targetQuality = getVideoQualityBySize(\n sources,\n videoScaledDimensions,\n );\n const url = targetQuality.types.find(\n (type) => type.format === 'mp4',\n )?.uri;\n if (url) {\n const videoSourceUrl = getCompleteUrl(url, STATIC_VIDEO_URL);\n return {\n videoSourceUrl,\n patchVideoSource: (videoNode: HTMLVideoElement) => {\n videoNode.src = videoSourceUrl;\n videoNode.load();\n },\n };\n }\n }\n }\n if (hasAbsoluteUri) {\n return {\n videoSourceUrl: uri,\n patchVideoSource: (videoNode: HTMLVideoElement) => {\n videoNode.src = uri;\n videoNode.load();\n },\n };\n }\n return {\n videoSourceUrl: '',\n patchVideoSource: () => {},\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { getVideoSource, setVideoFocalPoint } from './utils';
|
|
2
|
+
export default {
|
|
3
|
+
/**
|
|
4
|
+
* @param {HTMLVideoElement} videoNode
|
|
5
|
+
* @param {HTMLElement} container
|
|
6
|
+
* @param {QualityPolicy} quality
|
|
7
|
+
* @param {string} uri
|
|
8
|
+
* @param {Object[]} sources
|
|
9
|
+
* @param {Object[]} adaptiveSources
|
|
10
|
+
* @param {number} duration
|
|
11
|
+
* @param {(error: Error) => void} onError
|
|
12
|
+
* @return {{currentSrc: string, videoSourceUrl: string}}
|
|
13
|
+
*/
|
|
14
|
+
async measure(videoNode, container, quality, uri, sources, adaptiveSources, duration, onError) {
|
|
15
|
+
const {
|
|
16
|
+
videoSourceUrl,
|
|
17
|
+
patchVideoSource
|
|
18
|
+
} = await getVideoSource(container.offsetWidth, container.offsetHeight, uri, quality, sources, adaptiveSources, duration, onError);
|
|
19
|
+
const needsSrcUpdate = shouldUpdateSrc(videoNode, videoSourceUrl);
|
|
20
|
+
return {
|
|
21
|
+
needsSrcUpdate,
|
|
22
|
+
patchVideoSource
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* @param {HTMLDivElement} poster
|
|
27
|
+
* @param {HTMLVideoElement} videoNode
|
|
28
|
+
* @param {boolean} autoplay
|
|
29
|
+
* @param {boolean} needsSrcUpdate
|
|
30
|
+
* @param {string} posterEffect
|
|
31
|
+
* @param {number} playbackRate
|
|
32
|
+
* @param {(videoNode: HTMLVideoElement) => void} patchVideoSource
|
|
33
|
+
* @param {Object[]} sources
|
|
34
|
+
* @param {Object} focalPoint
|
|
35
|
+
*/
|
|
36
|
+
mutate(poster, videoNode, autoplay, needsSrcUpdate, posterEffect, playbackRate, patchVideoSource, sources, focalPoint) {
|
|
37
|
+
videoNode.toggleAttribute('autoplay', autoplay);
|
|
38
|
+
if (sources != null && sources[0]) {
|
|
39
|
+
const videoWidth = sources[0].width;
|
|
40
|
+
const videoHeight = sources[0].height;
|
|
41
|
+
const aspectRatio = videoWidth / videoHeight;
|
|
42
|
+
videoNode.style.setProperty('--aspect-ratio', aspectRatio.toString());
|
|
43
|
+
}
|
|
44
|
+
if (focalPoint) {
|
|
45
|
+
setVideoFocalPoint(videoNode, focalPoint);
|
|
46
|
+
}
|
|
47
|
+
handlePosterVisibility(needsSrcUpdate, videoNode, poster, posterEffect, autoplay);
|
|
48
|
+
if (needsSrcUpdate) {
|
|
49
|
+
patchVideoSource(videoNode);
|
|
50
|
+
}
|
|
51
|
+
videoNode.playbackRate = playbackRate;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param videoNode
|
|
58
|
+
* @param newSrcUrl
|
|
59
|
+
* @returns {*|boolean}
|
|
60
|
+
*/
|
|
61
|
+
function shouldUpdateSrc(videoNode, newSrcUrl) {
|
|
62
|
+
const hasError = videoNode.networkState === videoNode.NETWORK_NO_SOURCE;
|
|
63
|
+
const hasDiff = !videoNode.currentSrc.endsWith(newSrcUrl);
|
|
64
|
+
return Boolean(newSrcUrl && (hasDiff || hasError));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @param {boolean} needsEventUpdate
|
|
70
|
+
* @param {HTMLVideoElement} videoNode
|
|
71
|
+
* @param {HTMLDivElement} posterNode
|
|
72
|
+
* @param {string} posterEffect
|
|
73
|
+
* @param {boolean} autoplay
|
|
74
|
+
*/
|
|
75
|
+
function handlePosterVisibility(needsEventUpdate, videoNode, posterNode, posterEffect, autoplay) {
|
|
76
|
+
const isPausedOrEmpty = videoNode.paused || videoNode.currentSrc === '';
|
|
77
|
+
if (needsEventUpdate && isPausedOrEmpty) {
|
|
78
|
+
videoNode.ontimeupdate = null;
|
|
79
|
+
videoNode.onseeked = null;
|
|
80
|
+
videoNode.onplay = null;
|
|
81
|
+
if (autoplay) {
|
|
82
|
+
const muteState = videoNode.muted;
|
|
83
|
+
videoNode.ontimeupdate = () => {
|
|
84
|
+
if (videoNode.currentTime > 0) {
|
|
85
|
+
videoNode.ontimeupdate = null;
|
|
86
|
+
videoNode.onseeked = () => {
|
|
87
|
+
videoNode.onseeked = null;
|
|
88
|
+
videoNode.muted = muteState;
|
|
89
|
+
removePoster(videoNode, posterNode, posterEffect);
|
|
90
|
+
};
|
|
91
|
+
videoNode.currentTime = 0;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
} else {
|
|
95
|
+
videoNode.onplay = () => {
|
|
96
|
+
videoNode.onplay = null;
|
|
97
|
+
removePoster(videoNode, posterNode, posterEffect);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Show video , hide poster
|
|
105
|
+
*
|
|
106
|
+
* @param videoNode
|
|
107
|
+
* @param posterNode
|
|
108
|
+
* @param posterEffect
|
|
109
|
+
*/
|
|
110
|
+
function removePoster(videoNode, posterNode, posterEffect) {
|
|
111
|
+
if (posterEffect === 'fade') {
|
|
112
|
+
posterNode.style.transition = 'opacity 1.6s ease-out';
|
|
113
|
+
}
|
|
114
|
+
posterNode.style.opacity = '0';
|
|
115
|
+
videoNode.style.opacity = '1';
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=videoLayout.js.map
|