@vouchfor/embeds 0.0.0-experiment.03bde95 → 0.0.0-experiment.08b8fe3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. package/dist/es/embeds.js +983 -1436
  2. package/dist/es/embeds.js.map +1 -1
  3. package/dist/es/src/components/DialogEmbed/DialogOverlay.d.ts +20 -0
  4. package/dist/es/src/components/DialogEmbed/DialogPortal.d.ts +36 -0
  5. package/dist/es/src/components/DialogEmbed/index.d.ts +38 -0
  6. package/dist/es/src/components/PlayerEmbed/controllers/event-forwarder.d.ts +15 -0
  7. package/dist/es/src/components/{Embed → PlayerEmbed}/controllers/fetcher.d.ts +5 -4
  8. package/dist/es/src/components/{Embed/controllers/tracking.d.ts → PlayerEmbed/controllers/tracking/index.d.ts} +14 -11
  9. package/dist/es/src/components/PlayerEmbed/controllers/tracking/utils.d.ts +17 -0
  10. package/dist/es/src/components/PlayerEmbed/index.d.ts +75 -0
  11. package/dist/es/src/components/PlayerEmbed/tests/data.d.ts +4 -0
  12. package/dist/es/src/components/PlayerEmbed/tests/media-data.d.ts +19 -0
  13. package/dist/es/src/index.d.ts +2 -1
  14. package/dist/iife/dialog-embed/embed.iife.js +4042 -0
  15. package/dist/iife/dialog-embed/embed.iife.js.map +1 -0
  16. package/dist/iife/embeds.iife.js +2986 -471
  17. package/dist/iife/embeds.iife.js.map +1 -1
  18. package/dist/iife/player-embed/embed.iife.js +3904 -0
  19. package/dist/iife/player-embed/embed.iife.js.map +1 -0
  20. package/package.json +44 -31
  21. package/src/components/DialogEmbed/Dialog.stories.ts +91 -0
  22. package/src/components/DialogEmbed/DialogOverlay.ts +131 -0
  23. package/src/components/DialogEmbed/DialogPortal.ts +126 -0
  24. package/src/components/DialogEmbed/index.ts +97 -0
  25. package/src/components/PlayerEmbed/MultiEmbed.stories.ts +135 -0
  26. package/src/components/{Embed/Embed.stories.ts → PlayerEmbed/PlayerEmbed.stories.ts} +41 -15
  27. package/src/components/{Embed → PlayerEmbed}/controllers/event-forwarder.ts +6 -5
  28. package/src/components/{Embed → PlayerEmbed}/controllers/fetcher.ts +33 -14
  29. package/src/components/{Embed/controllers/tracking.ts → PlayerEmbed/controllers/tracking/index.ts} +53 -121
  30. package/src/components/PlayerEmbed/controllers/tracking/utils.ts +95 -0
  31. package/src/components/{Embed → PlayerEmbed}/index.ts +99 -43
  32. package/src/components/PlayerEmbed/tests/PlayerEmbed.spec.ts +87 -0
  33. package/src/components/PlayerEmbed/tests/data.ts +227 -0
  34. package/src/components/PlayerEmbed/tests/media-data.ts +22 -0
  35. package/src/index.ts +2 -1
  36. package/dist/es/src/components/Embed/index.d.ts +0 -67
@@ -0,0 +1,95 @@
1
+ import { TEMPLATE_VERSION } from '@vouchfor/canvas-video';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+
4
+ import type { TrackingPayload } from '.';
5
+ import type { Vouch } from '@vouchfor/video-utils';
6
+ import type { Environment } from '~/utils/env';
7
+
8
+ import packageJson from '~/../package.json';
9
+ import { getEnvUrls } from '~/utils/env';
10
+
11
+ function createVisitor(env: Environment) {
12
+ const { publicApiUrl } = getEnvUrls(env);
13
+ const visitorId = uuidv4();
14
+ navigator.sendBeacon(`${publicApiUrl}/api/visitor`, JSON.stringify({ visitorId }));
15
+ return visitorId;
16
+ }
17
+
18
+ function getUids(env: Environment) {
19
+ if (typeof window === 'undefined') {
20
+ return {
21
+ client: null,
22
+ tab: null,
23
+ request: uuidv4()
24
+ };
25
+ }
26
+
27
+ // Persisted for a user for the same device + browser, so we can e.g. search for all logs related to that browser
28
+ let visitorId = window.localStorage?.getItem?.('vouch-uid-visitor');
29
+ // Persisted for a user for the same device + browser, so we can e.g. search for all logs related to that browser
30
+ let clientId = window.localStorage?.getItem?.('vouch-uid-client');
31
+ // Persisted in session storage, so we can search for everything the user has done in a specific tab
32
+ let tabId = window.sessionStorage?.getItem?.('vouch-uid-tab');
33
+ // Not persisted, allows us to search for any logs related to a single FE request
34
+ // E.g. BE should pass this request ID through all other services to be able to group logs
35
+ const requestId = uuidv4();
36
+
37
+ // Cache uids
38
+ if (!visitorId) {
39
+ visitorId = createVisitor(env);
40
+ window.localStorage?.setItem?.('vouch-uid-visitor', visitorId);
41
+ }
42
+
43
+ if (!clientId) {
44
+ clientId = uuidv4();
45
+ window.localStorage?.setItem?.('vouch-uid-client', clientId);
46
+ }
47
+
48
+ if (!tabId) {
49
+ tabId = uuidv4();
50
+ window.sessionStorage?.setItem?.('vouch-uid-tab', tabId);
51
+ }
52
+
53
+ return {
54
+ client: clientId,
55
+ tab: tabId,
56
+ request: requestId,
57
+ visitor: visitorId
58
+ };
59
+ }
60
+
61
+ function findVouchId(payload?: TrackingPayload, vouch?: Vouch) {
62
+ if (payload && 'vouchId' in payload) {
63
+ return payload.vouchId;
64
+ }
65
+ return vouch?.id ?? null;
66
+ }
67
+
68
+ function getReportingMetadata(source = 'embedded_player') {
69
+ const [country, region] = Intl.DateTimeFormat().resolvedOptions().timeZone?.split?.('/') ?? [];
70
+
71
+ const utmParams: any = {};
72
+ [...new URLSearchParams(location.search).entries()].forEach(([key, value]) => {
73
+ if (/utm/.test(key)) {
74
+ const param = key.toLowerCase().replace(/[-_][a-z0-9]/g, (group) => group.slice(-1).toUpperCase());
75
+ utmParams[param] = value;
76
+ }
77
+ });
78
+
79
+ return {
80
+ source,
81
+ time: new Date(),
82
+ region,
83
+ country,
84
+ screenHeight: window.screen.height,
85
+ screenWidth: window.screen.width,
86
+ referrer: document.referrer,
87
+ currentUrl: location.href,
88
+ embedType: 'media-player-embed',
89
+ embedVersion: packageJson.version,
90
+ templateVersion: TEMPLATE_VERSION,
91
+ ...utmParams
92
+ };
93
+ }
94
+
95
+ export { getUids, findVouchId, getReportingMetadata };
@@ -1,11 +1,12 @@
1
- import { html, LitElement } from 'lit';
1
+ import { css, html, LitElement } from 'lit';
2
2
  import { customElement, property, state } from 'lit/decorators.js';
3
3
  import { ifDefined } from 'lit/directives/if-defined.js';
4
4
  import { createRef, ref } from 'lit/directives/ref.js';
5
5
 
6
- import type { Scene, Scenes, TemplateInstance } from '@vouchfor/canvas-video';
6
+ import type { TemplateInstance } from '@vouchfor/canvas-video';
7
7
  import type { MediaPlayer, MediaPlayerProps } from '@vouchfor/media-player';
8
- import type { Ref } from 'lit/directives/ref.js';
8
+ import type { Vouch } from '@vouchfor/video-utils';
9
+ import type { PropertyValueMap } from 'lit';
9
10
  import type { Environment } from '~/utils/env';
10
11
 
11
12
  import { EventForwardController } from './controllers/event-forwarder';
@@ -14,32 +15,43 @@ import { TrackingController } from './controllers/tracking';
14
15
 
15
16
  import '@vouchfor/media-player';
16
17
 
17
- type EmbedProps = Pick<MediaPlayerProps, 'data' | 'aspectRatio' | 'preload' | 'autoplay' | 'controls'> & {
18
+ type PlayerEmbedProps = Pick<MediaPlayerProps, 'aspectRatio' | 'language' | 'preload' | 'autoplay' | 'controls'> & {
19
+ data?: Vouch;
18
20
  env: Environment;
19
21
  apiKey: string;
20
22
  disableTracking?: boolean;
21
23
  trackingSource?: string;
22
24
  vouchId?: string;
23
25
  templateId?: string;
26
+ // Index of the questions to include starting from 1
27
+ questions?: number[];
24
28
  };
25
29
 
26
- @customElement('vouch-embed')
27
- class Embed extends LitElement {
28
- private _mediaPlayerRef: Ref<MediaPlayer> = createRef();
29
-
30
- @property({ type: Object, attribute: 'data' }) data: EmbedProps['data'];
31
- @property({ type: String }) vouchId: EmbedProps['vouchId'];
32
- @property({ type: String }) templateId: EmbedProps['templateId'];
33
-
34
- @property({ type: String }) env: EmbedProps['env'] = 'prod';
35
- @property({ type: String }) apiKey: EmbedProps['apiKey'] = '';
36
- @property({ type: Boolean }) disableTracking: EmbedProps['disableTracking'] = false;
37
- @property({ type: String }) trackingSource: EmbedProps['trackingSource'] = 'embed';
38
-
39
- @property({ type: Array }) controls: EmbedProps['controls'];
40
- @property({ type: String }) preload: EmbedProps['preload'] = 'auto';
41
- @property({ type: Boolean }) autoplay: EmbedProps['autoplay'] = false;
42
- @property({ type: Number }) aspectRatio: EmbedProps['aspectRatio'] = 0;
30
+ @customElement('vouch-embed-player')
31
+ class PlayerEmbed extends LitElement {
32
+ static styles = [
33
+ css`
34
+ :host {
35
+ display: flex;
36
+ }
37
+ `
38
+ ];
39
+
40
+ @property({ type: Object }) data: PlayerEmbedProps['data'];
41
+ @property({ type: String }) vouchId: PlayerEmbedProps['vouchId'];
42
+ @property({ type: String }) templateId: PlayerEmbedProps['templateId'];
43
+ @property({ type: Array }) questions: PlayerEmbedProps['questions'];
44
+
45
+ @property({ type: String }) env: PlayerEmbedProps['env'] = 'prod';
46
+ @property({ type: String }) apiKey: PlayerEmbedProps['apiKey'] = '';
47
+ @property({ type: Boolean }) disableTracking: PlayerEmbedProps['disableTracking'] = false;
48
+ @property({ type: String }) trackingSource: PlayerEmbedProps['trackingSource'] = 'embedded_player';
49
+
50
+ @property({ type: Array }) controls: PlayerEmbedProps['controls'];
51
+ @property({ type: String }) preload: PlayerEmbedProps['preload'] = 'auto';
52
+ @property({ type: Boolean }) autoplay: PlayerEmbedProps['autoplay'] = false;
53
+ @property({ type: Number }) aspectRatio: PlayerEmbedProps['aspectRatio'] = 0;
54
+ @property({ type: String }) language?: MediaPlayerProps['language'];
43
55
 
44
56
  private eventController = new EventForwardController(this, [
45
57
  'durationchange',
@@ -52,10 +64,12 @@ class Embed extends LitElement {
52
64
  'playing',
53
65
  'ratechange',
54
66
  'scenechange',
67
+ 'scenesupdate',
55
68
  'seeking',
56
69
  'seeked',
57
70
  'timeupdate',
58
71
  'volumechange',
72
+ 'processing',
59
73
  'waiting',
60
74
 
61
75
  'video:loadeddata',
@@ -74,17 +88,23 @@ class Embed extends LitElement {
74
88
  // @ts-ignore
75
89
  private _trackingController = new TrackingController(this);
76
90
 
77
- @state() vouch: EmbedProps['data'];
91
+ @state() vouch: PlayerEmbedProps['data'];
78
92
  @state() template: TemplateInstance | undefined;
79
93
 
80
94
  get fetching() {
81
95
  return this._fetcherController.fetching;
82
96
  }
83
97
 
98
+ private _mediaPlayerRef = createRef<MediaPlayer>();
99
+
84
100
  get waiting() {
85
101
  return this._mediaPlayerRef.value?.waiting;
86
102
  }
87
103
 
104
+ get initialised() {
105
+ return this._mediaPlayerRef.value?.initialised;
106
+ }
107
+
88
108
  get seeking() {
89
109
  return this._mediaPlayerRef.value?.seeking;
90
110
  }
@@ -141,20 +161,20 @@ class Embed extends LitElement {
141
161
  return this._mediaPlayerRef.value?.muted ?? false;
142
162
  }
143
163
 
144
- get scene(): Scene | null {
145
- return this._mediaPlayerRef.value?.scene ?? null;
146
- }
164
+ // get scene(): Scene | null {
165
+ // return this._mediaPlayerRef.value?.scene ?? null;
166
+ // }
147
167
 
148
- get scenes(): Scene[] {
149
- return this._mediaPlayerRef.value?.scenes ?? [];
150
- }
168
+ // get scenes(): Scene[] {
169
+ // return this._mediaPlayerRef.value?.scenes ?? [];
170
+ // }
151
171
 
152
- get sceneConfig(): Scenes | null {
153
- return this._mediaPlayerRef.value?.sceneConfig ?? null;
154
- }
172
+ // get sceneConfig(): Scenes | null {
173
+ // return this._mediaPlayerRef.value?.sceneConfig ?? null;
174
+ // }
155
175
 
156
- get videoState() {
157
- return this._mediaPlayerRef.value?.videoState;
176
+ get mediaState() {
177
+ return this._mediaPlayerRef.value?.mediaState;
158
178
  }
159
179
 
160
180
  get mediaPlayer() {
@@ -169,38 +189,74 @@ class Embed extends LitElement {
169
189
  this._mediaPlayerRef.value?.pause();
170
190
  }
171
191
 
172
- setScene(index: number) {
173
- this._mediaPlayerRef.value?.setScene(index);
192
+ reset(time = 0, play = false) {
193
+ this._mediaPlayerRef.value?.reset(time, play);
194
+ }
195
+
196
+ // setScene(index: number) {
197
+ // this._mediaPlayerRef.value?.setScene(index);
198
+ // }
199
+
200
+ private _renderStyles() {
201
+ if (!this.aspectRatio) {
202
+ return html`
203
+ <style>
204
+ :host {
205
+ width: 100%;
206
+ height: 100%;
207
+ }
208
+ </style>
209
+ `;
210
+ }
211
+
212
+ if (typeof this.aspectRatio === 'number') {
213
+ return html`
214
+ <style>
215
+ :host {
216
+ aspect-ratio: ${this.aspectRatio};
217
+ }
218
+ </style>
219
+ `;
220
+ }
221
+
222
+ return null;
223
+ }
224
+
225
+ protected willUpdate(changedProperties: PropertyValueMap<PlayerEmbedProps>) {
226
+ // If the vouch this embed is pointing to changes then reset the player
227
+ if (changedProperties.has('vouchId') && this.vouchId !== changedProperties.get('vouchId')) {
228
+ this.reset(0, false);
229
+ }
174
230
  }
175
231
 
176
232
  render() {
177
233
  return html`
178
- <vmp-new-media-player
234
+ ${this._renderStyles()}
235
+ <vmp-media-player
179
236
  ${ref(this._mediaPlayerRef)}
180
237
  ${this.eventController.register()}
181
238
  ?autoplay=${this.autoplay}
182
239
  ?loading=${this.fetching}
183
- .data=${this.vouch}
184
- .template=${this.template}
185
240
  aspectRatio=${ifDefined(this.aspectRatio)}
186
241
  preload=${ifDefined(this.preload)}
242
+ language=${ifDefined(this.language)}
187
243
  .controls=${this.controls}
188
- ></vmp-new-media-player>
244
+ ></vmp-media-player>
189
245
  `;
190
246
  }
191
247
  }
192
248
 
193
249
  declare global {
194
250
  interface HTMLElementTagNameMap {
195
- 'vouch-embed': Embed;
251
+ 'vouch-embed-player': PlayerEmbed;
196
252
  }
197
253
 
198
254
  namespace JSX {
199
255
  interface IntrinsicElements {
200
- 'vouch-embed': Embed;
256
+ 'vouch-embed-player': PlayerEmbed;
201
257
  }
202
258
  }
203
259
  }
204
260
 
205
- export { Embed };
206
- export type { EmbedProps };
261
+ export { PlayerEmbed };
262
+ export type { PlayerEmbedProps };
@@ -0,0 +1,87 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+ import { expect, fixture, waitUntil } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import sinon from 'sinon';
5
+
6
+ import type { PlayerEmbed } from '../index.js';
7
+ import type { MediaMap } from '@vouchfor/media-player';
8
+
9
+ import { data } from './data.js';
10
+
11
+ // Can't use typescript aliases with esbuild file transforms apparently
12
+ // No idea what a good way to actually build before testing is, the examples give nothing
13
+ // https://modern-web.dev/guides/test-runner/typescript/
14
+ import '../../../test/lib/embeds.js';
15
+
16
+ function getVideo(videos: MediaMap) {
17
+ return Object.values(videos)[0];
18
+ }
19
+
20
+ function playerLoaded(player: PlayerEmbed) {
21
+ return waitUntil(
22
+ () => {
23
+ return player.mediaPlayer?.initialised;
24
+ },
25
+ 'Player has not loaded video',
26
+ { timeout: 20000 }
27
+ );
28
+ }
29
+
30
+ describe.skip('Embeds', () => {
31
+ it('Sends correct tracking events', async () => {
32
+ const player = await fixture<PlayerEmbed>(
33
+ html`<vouch-embed-player env="dev" .data=${data} aspectratio=${1}></vouch-embed-player>`
34
+ );
35
+ // @ts-ignore - accessing private property
36
+ const sendTrackingSpy = sinon.spy(player._trackingController, '_sendTrackingEvent');
37
+ // @ts-ignore - accessing private property
38
+ const createTrackingSpy = sinon.spy(player._trackingController, '_createTrackingEvent');
39
+
40
+ await playerLoaded(player);
41
+ // Have to mute the player because we can't programmatically play videos with sound
42
+ player.muted = true;
43
+ player.play();
44
+ expect(player.paused).eq(false);
45
+ await waitUntil(
46
+ () => {
47
+ // Video plays for 3 seconds
48
+ return (getVideo(player.mediaPlayer!.media)?.node?.currentTime ?? 0) > 3;
49
+ },
50
+ 'Video did not play for 3 seconds',
51
+ { timeout: 20000 }
52
+ );
53
+ expect(getVideo(player.mediaPlayer!.media)?.node?.paused).eq(false);
54
+ player.pause();
55
+ expect(getVideo(player.mediaPlayer!.media)?.node?.paused).eq(true);
56
+ expect(sendTrackingSpy.callCount).to.be.eq(0);
57
+ // Destroy node because events are sent when node is removed from the document
58
+ player.remove();
59
+ await waitUntil(
60
+ () => {
61
+ return createTrackingSpy.args[2];
62
+ },
63
+ 'Cleanup event has not fired',
64
+ { timeout: 5000 }
65
+ );
66
+ expect(sendTrackingSpy.callCount).to.be.eq(1);
67
+ expect(createTrackingSpy.args[0]).to.eql([
68
+ 'VIDEO_PLAYED',
69
+ {
70
+ streamStart: 0
71
+ }
72
+ ]);
73
+ expect(createTrackingSpy.args[1]).to.eql([
74
+ 'VOUCH_RESPONSE_VIEWED',
75
+ {
76
+ answerId: '5c66bb3a-ed68-41a0-a601-a49865104418'
77
+ }
78
+ ]);
79
+ expect(createTrackingSpy.args[2][0]).to.eq('VIDEO_STREAMED');
80
+ // Remove streamStart and streamEnd as these are non-deterministic
81
+ expect({ ...createTrackingSpy.args[2][1], streamStart: undefined, streamEnd: undefined }).to.eql({
82
+ answerId: '5c66bb3a-ed68-41a0-a601-a49865104418',
83
+ streamStart: undefined,
84
+ streamEnd: undefined
85
+ });
86
+ });
87
+ });
@@ -0,0 +1,227 @@
1
+ import type { Vouch } from '@vouchfor/video-utils';
2
+
3
+ import { VIDEOA, VIDEOB, VIDEOC } from './media-data';
4
+
5
+ /* eslint-disable max-lines */
6
+ const data: Vouch = {
7
+ id: '85a7f7fb-897c-41a4-be7b-2636cf991f2c',
8
+ hashId: '6JQEIPeStt',
9
+ settings: {
10
+ branding: {
11
+ base: {
12
+ primary: {
13
+ color: '#48aff7',
14
+ text: '#def2ff'
15
+ },
16
+ secondary: {
17
+ color: '#fdbdfa',
18
+ text: '#8b26bf'
19
+ },
20
+ radius: '8px'
21
+ }
22
+ }
23
+ },
24
+ questions: {
25
+ items: [
26
+ {
27
+ id: '5c66bb3a-ed68-41a0-a601-a49865104418',
28
+ title: "What is the business problem you're trying to solve?",
29
+ answer: {
30
+ id: '5c66bb3a-ed68-41a0-a601-a49865104418',
31
+ label: null,
32
+ metadata: {
33
+ duration: VIDEOA.duration
34
+ },
35
+ settings: {
36
+ endOffset: 0,
37
+ startOffset: 0
38
+ },
39
+ media: {
40
+ input: VIDEOA.mp4,
41
+ video: VIDEOA.mp4,
42
+ playlist: VIDEOA.m3u8,
43
+ thumbnail: VIDEOA.jpg,
44
+ videos: {
45
+ xs: VIDEOA.mp4
46
+ }
47
+ },
48
+ contact: {
49
+ id: 'b62f62a3-0cd4-4512-9b52-121cb2f3e72f',
50
+ name: 'Aaron Williams',
51
+ roleTitle: 'Software Engineer',
52
+ client: {
53
+ id: '03540d70-1c75-4867-a235-bac842ed6ce4',
54
+ name: 'Not Supplied',
55
+ logoSrc: 'https://vouch-clients.s3.ap-southeast-2.amazonaws.com/vouch/logos/vouch-logotype-teal.png'
56
+ }
57
+ },
58
+ captions: {
59
+ current:
60
+ "WEBVTT\r\n\r\n1\r\n00:00:01.710 --> 00:00:05.250\r\nwe are trying to solve, uh, world hunger.\r\n\r\n2\r\n00:00:05.420 --> 00:00:08.369\r\nI think it's an important goal. Uh, we\r\n\r\n3\r\n00:00:08.380 --> 00:00:09.489\r\nalso would like to get rid of\r\n\r\n4\r\n00:00:09.500 --> 00:00:12.050\r\ntuberculosis. Um, in general. And\r\n\r\n5\r\n00:00:12.060 --> 00:00:15.329\r\nprobably malaria, too. Uh, it's gonna be\r\n\r\n6\r\n00:00:15.340 --> 00:00:17.180\r\na couple of weeks, but I think we can do\r\n\r\n7\r\n00:00:17.190 --> 00:00:17.319\r\nit.\r\n",
61
+ translation:
62
+ 'WEBVTT\n\n1\n00:00:01.549 --> 00:00:05.920\n🇯🇵 🙏 こんにちは 藤森 章 です 。 え ? 今 日本 の え ? 東京 に 住ん で\n\n2\n00:00:05.929 --> 00:00:11.359\nいる 高校 三 年 生 です 。 えっと 父親 が 日本 人 で 母親 が は\n\n3\n00:00:11.619 --> 00:00:13.130\nえー 中国 人 な ん です けれど も 。\n\n4\n00:00:13.939 --> 00:00:17.889\nえ ? 上海 に 行っ た 時 に 国際 学校 に 通っ て い た の で 。\n\n5\n00:00:17.899 --> 00:00:20.389\nえー 英語 を 日本 語 、 中国 語 、 三 語 を しゃ ます\n\n6\n00:00:21.030 --> 00:00:23.549\nえー で 、 その 中 で 経験 し た こと な ん です けれど も 、\n\n7\n00:00:24.040 --> 00:00:26.700\n日本 語 の 素晴らしい ところ って いう の は 、\n\n8\n00:00:27.260 --> 00:00:27.809\nやっぱり\n\n9\n00:00:28.489 --> 00:00:31.540\n和歌 に も 見 られる よう な 多彩 な 表現 力 と\n\n10\n00:00:32.349 --> 00:00:33.819\nえ 奥深い\n\n11\n00:00:34.770 --> 00:00:38.520\nえー 、 感情 表現 など に ある と 思い ます 。 えー これ を 見 て\n\n12\n00:00:38.759 --> 00:00:41.599\n日本 語 に 興味 を 持っ た 方 は 、 是非 その\n\n13\n00:00:43.180 --> 00:00:43.770\n奥深い\n\n14\n00:00:44.299 --> 00:00:45.630\n表現 など を え 、\n\n15\n00:00:46.299 --> 00:00:49.209\n見 て 、 感じ て えー 、 触れ て み て ください 。 ありがとう\n\n16\n00:00:49.220 --> 00:00:49.599\nござい まし た 。\n'
63
+ },
64
+ transcription: {
65
+ language: 'en',
66
+ translation: {
67
+ language: 'ja'
68
+ },
69
+ items: []
70
+ }
71
+ }
72
+ },
73
+ {
74
+ id: '5c66bb3a-ed68-41a0-a601-a49865104418',
75
+ title: "What is the business problem you're trying to solve?",
76
+ answer: {
77
+ id: '5c66bb3a-ed68-41a0-a601-a49865104418',
78
+ label: null,
79
+ metadata: {
80
+ duration: VIDEOA.duration
81
+ },
82
+ settings: {
83
+ endOffset: 0.385945945945946,
84
+ startOffset: 0.3037837837837838,
85
+ crop: {
86
+ x: 0.4,
87
+ y: 0.4,
88
+ width: 0.4,
89
+ height: 0.4
90
+ }
91
+ },
92
+ media: {
93
+ input: VIDEOA.mp4,
94
+ video: VIDEOA.mp4,
95
+ playlist: VIDEOA.m3u8,
96
+ thumbnail: VIDEOA.jpg,
97
+ videos: {
98
+ xs: VIDEOA.mp4
99
+ }
100
+ },
101
+ contact: {
102
+ id: 'b62f62a3-0cd4-4512-9b52-121cb2f3e72f',
103
+ name: 'Aaron Williams',
104
+ roleTitle: 'Software Engineer',
105
+ client: {
106
+ id: '03540d70-1c75-4867-a235-bac842ed6ce4',
107
+ logoSrc: 'https://vouch-clients.s3.ap-southeast-2.amazonaws.com/vouch/logos/vouch-logotype-teal.png'
108
+ }
109
+ },
110
+ captions: {
111
+ current:
112
+ "WEBVTT\r\n\r\n1\r\n00:00:01.710 --> 00:00:05.250\r\nwe are trying to solve, uh, world hunger.\r\n\r\n2\r\n00:00:05.420 --> 00:00:08.369\r\nI think it's an important goal. Uh, we\r\n\r\n3\r\n00:00:08.380 --> 00:00:09.489\r\nalso would like to get rid of\r\n\r\n4\r\n00:00:09.500 --> 00:00:12.050\r\ntuberculosis. Um, in general. And\r\n\r\n5\r\n00:00:12.060 --> 00:00:15.329\r\nprobably malaria, too. Uh, it's gonna be\r\n\r\n6\r\n00:00:15.340 --> 00:00:17.180\r\na couple of weeks, but I think we can do\r\n\r\n7\r\n00:00:17.190 --> 00:00:17.319\r\nit.\r\n"
113
+ },
114
+ transcription: {
115
+ language: 'en',
116
+ translation: {
117
+ language: 'fr'
118
+ },
119
+ items: []
120
+ }
121
+ }
122
+ },
123
+ {
124
+ id: 'e77c81a7-f6ef-4eae-91fc-b620d092d8d6',
125
+ title: 'What are the priorities for your business/team this quarter?',
126
+ answer: {
127
+ id: 'e77c81a7-f6ef-4eae-91fc-b620d092d8d6',
128
+ label: 'Hello this label is overridden',
129
+ metadata: {
130
+ duration: VIDEOB.duration
131
+ },
132
+ settings: {
133
+ endOffset: 0,
134
+ startOffset: 0
135
+ },
136
+ media: {
137
+ input: VIDEOB.mp4,
138
+ video: VIDEOB.mp4,
139
+ playlist: VIDEOB.m3u8,
140
+ thumbnail: VIDEOB.jpg,
141
+ videos: {
142
+ xs: VIDEOB.mp4
143
+ }
144
+ },
145
+ contact: {
146
+ id: 'b62f62a3-0cd4-4512-9b52-121cb2f3e72f',
147
+ name: 'Aaron Williams',
148
+ roleTitle: 'Software Engineer',
149
+ client: {
150
+ id: '03540d70-1c75-4867-a235-bac842ed6ce4',
151
+ name: 'Vouch',
152
+ logoSrc: 'https://vouch-clients.s3.ap-southeast-2.amazonaws.com/vouch/logos/vouch-logotype-teal.png'
153
+ }
154
+ },
155
+ captions: {
156
+ current:
157
+ 'WEBVTT\r\n\r\n1\r\n00:00:00.709 --> 00:00:03.059\r\npriorities for this business. Uh, for\r\n\r\n2\r\n00:00:03.069 --> 00:00:06.010\r\nthis quarter, uh, to make more money,\r\n\r\n3\r\n00:00:06.019 --> 00:00:09.050\r\nmore profits, Uh, get everything, uh,\r\n\r\n4\r\n00:00:09.069 --> 00:00:13.439\r\nswept away. All our heuristics should be\r\n\r\n5\r\n00:00:13.529 --> 00:00:15.119\r\ntop of the line.\r\n'
158
+ },
159
+ transcription: {
160
+ language: 'en',
161
+ translation: {
162
+ language: 'de'
163
+ },
164
+ items: []
165
+ }
166
+ }
167
+ },
168
+ {
169
+ id: '39fd188d-a4dc-43b9-bac8-32fd71bfbc90',
170
+ title: `"Emoji": 🇯🇵 🙏
171
+ \t\t'Arabic': خَرَجَ الوَلَدُ.
172
+ Chinese: 简化字不讲理\f
173
+ Hebrew: עִבְרִית\r\r
174
+ Japanese Kanji: 漢字\n
175
+ \\\\\\///
176
+ Japanese Hiragana: 平仮名
177
+ Japanese Katakana: 片仮名
178
+ Devangari Hindi: ॳॴॶॷऎऒऔ
179
+ Korean Hangul: 정음/正音
180
+ Cyrillic: АБВГДЕЖЗИКЛМН
181
+ Greek: αβγδ`,
182
+ answer: {
183
+ id: '39fd188d-a4dc-43b9-bac8-32fd71bfbc90',
184
+ label: null,
185
+ metadata: {
186
+ duration: VIDEOC.duration
187
+ },
188
+ settings: {
189
+ endOffset: 0,
190
+ startOffset: 0
191
+ },
192
+ media: {
193
+ input: VIDEOC.mp4,
194
+ video: VIDEOC.mp4,
195
+ playlist: VIDEOC.m3u8,
196
+ thumbnail: VIDEOC.jpg,
197
+ videos: {
198
+ xs: VIDEOC.mp4
199
+ }
200
+ },
201
+ contact: {
202
+ id: 'b62f62a3-0cd4-4512-9b52-121cb2f3e72f',
203
+ name: 'Aaron Williams',
204
+ client: {
205
+ id: '03540d70-1c75-4867-a235-bac842ed6ce4',
206
+ name: 'Vouch',
207
+ logoSrc: 'https://vouch-clients.s3.ap-southeast-2.amazonaws.com/vouch/logos/vouch-logotype-teal.png'
208
+ }
209
+ },
210
+ captions: {
211
+ current:
212
+ "WEBVTT\r\n\r\n1\r\n00:00:00.790 --> 00:00:03.269\r\nuh, the biggest pain points this this\r\n\r\n2\r\n00:00:03.279 --> 00:00:07.170\r\nquarter. Um, Jerry has been doing the\r\n\r\n3\r\n00:00:07.179 --> 00:00:09.180\r\nworst work that he's ever been doing.\r\n\r\n4\r\n00:00:09.390 --> 00:00:11.680\r\nAnd we must fire him, Jerry. Goodbye,\r\n\r\n5\r\n00:00:11.689 --> 00:00:12.149\r\nJerry.\r\n"
213
+ }
214
+ }
215
+ }
216
+ ]
217
+ }
218
+ };
219
+
220
+ const withNullAnswer = {
221
+ ...data,
222
+ questions: {
223
+ items: [...data.questions.items, { id: 'null', answer: null }]
224
+ }
225
+ } as Vouch;
226
+
227
+ export { data, withNullAnswer };
@@ -0,0 +1,22 @@
1
+ const VIDEOA = {
2
+ mp4: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/01/output.mp4',
3
+ m3u8: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/01/master.m3u8',
4
+ jpg: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/01/output.jpg',
5
+ duration: 7.29
6
+ };
7
+
8
+ const VIDEOB = {
9
+ mp4: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/02/output.mp4',
10
+ m3u8: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/02/master.m3u8',
11
+ jpg: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/02/output.jpg',
12
+ duration: 40.4
13
+ };
14
+
15
+ const VIDEOC = {
16
+ mp4: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/03/output.mp4',
17
+ m3u8: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/03/master.m3u8',
18
+ jpg: 'https://media-player-test-videos.s3.ap-southeast-2.amazonaws.com/03/output.jpg',
19
+ duration: 30.33
20
+ };
21
+
22
+ export { VIDEOA, VIDEOB, VIDEOC };
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
- export { Embed } from '~/components/Embed';
1
+ export { PlayerEmbed } from '~/components/PlayerEmbed';
2
+ export { DialogEmbed } from '~/components/DialogEmbed';