@editframe/elements 0.16.7-beta.0 → 0.17.6-beta.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/README.md +30 -0
- package/dist/DecoderResetFrequency.test.d.ts +1 -0
- package/dist/DecoderResetRecovery.test.d.ts +1 -0
- package/dist/DelayedLoadingState.d.ts +48 -0
- package/dist/DelayedLoadingState.integration.test.d.ts +1 -0
- package/dist/DelayedLoadingState.js +113 -0
- package/dist/DelayedLoadingState.test.d.ts +1 -0
- package/dist/EF_FRAMEGEN.d.ts +10 -1
- package/dist/EF_FRAMEGEN.js +199 -179
- package/dist/EF_INTERACTIVE.js +2 -6
- package/dist/EF_RENDERING.js +1 -3
- package/dist/JitTranscodingClient.browsertest.d.ts +1 -0
- package/dist/JitTranscodingClient.d.ts +167 -0
- package/dist/JitTranscodingClient.js +373 -0
- package/dist/JitTranscodingClient.test.d.ts +1 -0
- package/dist/LoadingDebounce.test.d.ts +1 -0
- package/dist/LoadingIndicator.browsertest.d.ts +0 -0
- package/dist/ManualScrubTest.test.d.ts +1 -0
- package/dist/ScrubResolvedFlashing.test.d.ts +1 -0
- package/dist/ScrubTrackIntegration.test.d.ts +1 -0
- package/dist/ScrubTrackManager.d.ts +96 -0
- package/dist/ScrubTrackManager.js +216 -0
- package/dist/ScrubTrackManager.test.d.ts +1 -0
- package/dist/SegmentSwitchLoading.test.d.ts +1 -0
- package/dist/VideoSeekFlashing.browsertest.d.ts +0 -0
- package/dist/VideoStuckDiagnostic.test.d.ts +1 -0
- package/dist/elements/CrossUpdateController.js +13 -15
- package/dist/elements/EFAudio.browsertest.d.ts +0 -0
- package/dist/elements/EFAudio.d.ts +1 -1
- package/dist/elements/EFAudio.js +30 -43
- package/dist/elements/EFCaptions.js +337 -373
- package/dist/elements/EFImage.js +64 -90
- package/dist/elements/EFMedia.d.ts +98 -33
- package/dist/elements/EFMedia.js +1169 -678
- package/dist/elements/EFSourceMixin.js +31 -48
- package/dist/elements/EFTemporal.d.ts +1 -0
- package/dist/elements/EFTemporal.js +266 -360
- package/dist/elements/EFTimegroup.d.ts +3 -1
- package/dist/elements/EFTimegroup.js +262 -323
- package/dist/elements/EFVideo.browsertest.d.ts +0 -0
- package/dist/elements/EFVideo.d.ts +90 -2
- package/dist/elements/EFVideo.js +408 -111
- package/dist/elements/EFWaveform.js +375 -411
- package/dist/elements/FetchMixin.js +14 -24
- package/dist/elements/MediaController.d.ts +30 -0
- package/dist/elements/TargetController.js +130 -156
- package/dist/elements/TimegroupController.js +17 -19
- package/dist/elements/durationConverter.js +15 -4
- package/dist/elements/parseTimeToMs.js +4 -10
- package/dist/elements/printTaskStatus.d.ts +2 -0
- package/dist/elements/printTaskStatus.js +11 -0
- package/dist/elements/updateAnimations.js +39 -59
- package/dist/getRenderInfo.js +58 -67
- package/dist/gui/ContextMixin.js +203 -288
- package/dist/gui/EFConfiguration.js +27 -43
- package/dist/gui/EFFilmstrip.js +440 -620
- package/dist/gui/EFFitScale.js +112 -135
- package/dist/gui/EFFocusOverlay.js +45 -61
- package/dist/gui/EFPreview.js +30 -49
- package/dist/gui/EFScrubber.js +78 -99
- package/dist/gui/EFTimeDisplay.js +49 -70
- package/dist/gui/EFToggleLoop.js +17 -34
- package/dist/gui/EFTogglePlay.js +37 -58
- package/dist/gui/EFWorkbench.js +66 -88
- package/dist/gui/TWMixin.js +2 -48
- package/dist/gui/TWMixin2.js +31 -0
- package/dist/gui/efContext.js +2 -6
- package/dist/gui/fetchContext.js +1 -3
- package/dist/gui/focusContext.js +1 -3
- package/dist/gui/focusedElementContext.js +2 -6
- package/dist/gui/playingContext.js +1 -4
- package/dist/index.js +5 -30
- package/dist/msToTimeCode.js +11 -13
- package/dist/style.css +2 -1
- package/package.json +3 -3
- package/src/elements/EFAudio.browsertest.ts +569 -0
- package/src/elements/EFAudio.ts +4 -6
- package/src/elements/EFCaptions.browsertest.ts +0 -1
- package/src/elements/EFImage.browsertest.ts +0 -1
- package/src/elements/EFMedia.browsertest.ts +147 -115
- package/src/elements/EFMedia.ts +1339 -307
- package/src/elements/EFTemporal.browsertest.ts +0 -1
- package/src/elements/EFTemporal.ts +11 -0
- package/src/elements/EFTimegroup.ts +73 -10
- package/src/elements/EFVideo.browsertest.ts +680 -0
- package/src/elements/EFVideo.ts +729 -50
- package/src/elements/EFWaveform.ts +4 -4
- package/src/elements/MediaController.ts +108 -0
- package/src/elements/__screenshots__/EFMedia.browsertest.ts/EFMedia-JIT-audio-playback-audioBufferTask-should-work-in-JIT-mode-without-URL-errors-1.png +0 -0
- package/src/elements/printTaskStatus.ts +16 -0
- package/src/elements/updateAnimations.ts +6 -0
- package/src/gui/TWMixin.ts +10 -3
- package/test/EFVideo.frame-tasks.browsertest.ts +524 -0
- package/test/EFVideo.framegen.browsertest.ts +118 -0
- package/test/createJitTestClips.ts +293 -0
- package/test/useAssetMSW.ts +49 -0
- package/test/useMSW.ts +31 -0
- package/types.json +1 -1
- package/dist/gui/TWMixin.css.js +0 -4
- /package/dist/elements/{TargetController.test.d.ts → TargetController.browsertest.d.ts} +0 -0
- /package/src/elements/{TargetController.test.ts → TargetController.browsertest.ts} +0 -0
|
@@ -1,49 +1,31 @@
|
|
|
1
|
-
import { Task } from "@lit/task";
|
|
2
|
-
import { LitElement, html, css } from "lit";
|
|
3
|
-
import { property, customElement } from "lit/decorators.js";
|
|
4
1
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
5
|
-
import { CrossUpdateController } from "./CrossUpdateController.js";
|
|
6
|
-
import { EFAudio } from "./EFAudio.js";
|
|
7
2
|
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
8
3
|
import { EFTemporal } from "./EFTemporal.js";
|
|
9
|
-
import { EFVideo } from "./EFVideo.js";
|
|
10
4
|
import { FetchMixin } from "./FetchMixin.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.hidden = false;
|
|
36
|
-
return html` ${this.wordText.trim()} `;
|
|
37
|
-
}
|
|
38
|
-
get startTimeMs() {
|
|
39
|
-
return this.wordStartMs || 0;
|
|
40
|
-
}
|
|
41
|
-
get durationMs() {
|
|
42
|
-
return this.wordEndMs - this.wordStartMs;
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
EFCaptionsActiveWord.styles = [
|
|
46
|
-
css`
|
|
5
|
+
import { EFAudio } from "./EFAudio.js";
|
|
6
|
+
import { EFVideo } from "./EFVideo.js";
|
|
7
|
+
import { CrossUpdateController } from "./CrossUpdateController.js";
|
|
8
|
+
import { Task } from "@lit/task";
|
|
9
|
+
import { LitElement, css, html } from "lit";
|
|
10
|
+
import { customElement, property } from "lit/decorators.js";
|
|
11
|
+
import _decorate from "@oxc-project/runtime/helpers/decorate";
|
|
12
|
+
const stopWords = new Set([
|
|
13
|
+
"",
|
|
14
|
+
".",
|
|
15
|
+
"!",
|
|
16
|
+
"?",
|
|
17
|
+
","
|
|
18
|
+
]);
|
|
19
|
+
let EFCaptionsActiveWord = class EFCaptionsActiveWord$1 extends EFTemporal(LitElement) {
|
|
20
|
+
constructor(..._args) {
|
|
21
|
+
super(..._args);
|
|
22
|
+
this.wordStartMs = 0;
|
|
23
|
+
this.wordEndMs = 0;
|
|
24
|
+
this.wordText = "";
|
|
25
|
+
this.hidden = false;
|
|
26
|
+
}
|
|
27
|
+
static {
|
|
28
|
+
this.styles = [css`
|
|
47
29
|
:host {
|
|
48
30
|
display: inline-block;
|
|
49
31
|
white-space: pre;
|
|
@@ -51,96 +33,100 @@ EFCaptionsActiveWord.styles = [
|
|
|
51
33
|
:host([hidden]) {
|
|
52
34
|
display: none;
|
|
53
35
|
}
|
|
54
|
-
`
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
], EFCaptionsActiveWord);
|
|
71
|
-
let EFCaptionsSegment = class extends EFTemporal(LitElement) {
|
|
72
|
-
constructor() {
|
|
73
|
-
super(...arguments);
|
|
74
|
-
this.segmentStartMs = 0;
|
|
75
|
-
this.segmentEndMs = 0;
|
|
76
|
-
this.segmentText = "";
|
|
77
|
-
this.hidden = false;
|
|
78
|
-
}
|
|
79
|
-
render() {
|
|
80
|
-
if (stopWords.has(this.segmentText)) {
|
|
81
|
-
this.hidden = true;
|
|
82
|
-
return void 0;
|
|
83
|
-
}
|
|
84
|
-
this.hidden = false;
|
|
85
|
-
return html`${this.segmentText}`;
|
|
86
|
-
}
|
|
87
|
-
get startTimeMs() {
|
|
88
|
-
return this.segmentStartMs || 0;
|
|
89
|
-
}
|
|
90
|
-
get durationMs() {
|
|
91
|
-
return this.segmentEndMs - this.segmentStartMs;
|
|
92
|
-
}
|
|
36
|
+
`];
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
if (stopWords.has(this.wordText)) {
|
|
40
|
+
this.hidden = true;
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
this.hidden = false;
|
|
44
|
+
return html` ${this.wordText.trim()} `;
|
|
45
|
+
}
|
|
46
|
+
get startTimeMs() {
|
|
47
|
+
return this.wordStartMs || 0;
|
|
48
|
+
}
|
|
49
|
+
get durationMs() {
|
|
50
|
+
return this.wordEndMs - this.wordStartMs;
|
|
51
|
+
}
|
|
93
52
|
};
|
|
94
|
-
|
|
95
|
-
|
|
53
|
+
_decorate([property({
|
|
54
|
+
type: Number,
|
|
55
|
+
attribute: false
|
|
56
|
+
})], EFCaptionsActiveWord.prototype, "wordStartMs", void 0);
|
|
57
|
+
_decorate([property({
|
|
58
|
+
type: Number,
|
|
59
|
+
attribute: false
|
|
60
|
+
})], EFCaptionsActiveWord.prototype, "wordEndMs", void 0);
|
|
61
|
+
_decorate([property({
|
|
62
|
+
type: String,
|
|
63
|
+
attribute: false
|
|
64
|
+
})], EFCaptionsActiveWord.prototype, "wordText", void 0);
|
|
65
|
+
_decorate([property({
|
|
66
|
+
type: Boolean,
|
|
67
|
+
reflect: true
|
|
68
|
+
})], EFCaptionsActiveWord.prototype, "hidden", void 0);
|
|
69
|
+
EFCaptionsActiveWord = _decorate([customElement("ef-captions-active-word")], EFCaptionsActiveWord);
|
|
70
|
+
let EFCaptionsSegment = class EFCaptionsSegment$1 extends EFTemporal(LitElement) {
|
|
71
|
+
constructor(..._args2) {
|
|
72
|
+
super(..._args2);
|
|
73
|
+
this.segmentStartMs = 0;
|
|
74
|
+
this.segmentEndMs = 0;
|
|
75
|
+
this.segmentText = "";
|
|
76
|
+
this.hidden = false;
|
|
77
|
+
}
|
|
78
|
+
static {
|
|
79
|
+
this.styles = [css`
|
|
96
80
|
:host {
|
|
97
81
|
display: block;
|
|
98
82
|
}
|
|
99
83
|
:host([hidden]) {
|
|
100
84
|
display: none;
|
|
101
85
|
}
|
|
102
|
-
`
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
], EFCaptionsSegment);
|
|
119
|
-
let EFCaptionsBeforeActiveWord = class extends EFCaptionsSegment {
|
|
120
|
-
constructor() {
|
|
121
|
-
super(...arguments);
|
|
122
|
-
this.hidden = false;
|
|
123
|
-
this.segmentText = "";
|
|
124
|
-
this.segmentStartMs = 0;
|
|
125
|
-
this.segmentEndMs = 0;
|
|
126
|
-
}
|
|
127
|
-
render() {
|
|
128
|
-
if (stopWords.has(this.segmentText)) {
|
|
129
|
-
this.hidden = true;
|
|
130
|
-
return void 0;
|
|
131
|
-
}
|
|
132
|
-
this.hidden = false;
|
|
133
|
-
return html` ${this.segmentText}`;
|
|
134
|
-
}
|
|
135
|
-
get startTimeMs() {
|
|
136
|
-
return this.segmentStartMs || 0;
|
|
137
|
-
}
|
|
138
|
-
get durationMs() {
|
|
139
|
-
return this.segmentEndMs - this.segmentStartMs;
|
|
140
|
-
}
|
|
86
|
+
`];
|
|
87
|
+
}
|
|
88
|
+
render() {
|
|
89
|
+
if (stopWords.has(this.segmentText)) {
|
|
90
|
+
this.hidden = true;
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
this.hidden = false;
|
|
94
|
+
return html`${this.segmentText}`;
|
|
95
|
+
}
|
|
96
|
+
get startTimeMs() {
|
|
97
|
+
return this.segmentStartMs || 0;
|
|
98
|
+
}
|
|
99
|
+
get durationMs() {
|
|
100
|
+
return this.segmentEndMs - this.segmentStartMs;
|
|
101
|
+
}
|
|
141
102
|
};
|
|
142
|
-
|
|
143
|
-
|
|
103
|
+
_decorate([property({
|
|
104
|
+
type: Number,
|
|
105
|
+
attribute: false
|
|
106
|
+
})], EFCaptionsSegment.prototype, "segmentStartMs", void 0);
|
|
107
|
+
_decorate([property({
|
|
108
|
+
type: Number,
|
|
109
|
+
attribute: false
|
|
110
|
+
})], EFCaptionsSegment.prototype, "segmentEndMs", void 0);
|
|
111
|
+
_decorate([property({
|
|
112
|
+
type: String,
|
|
113
|
+
attribute: false
|
|
114
|
+
})], EFCaptionsSegment.prototype, "segmentText", void 0);
|
|
115
|
+
_decorate([property({
|
|
116
|
+
type: Boolean,
|
|
117
|
+
reflect: true
|
|
118
|
+
})], EFCaptionsSegment.prototype, "hidden", void 0);
|
|
119
|
+
EFCaptionsSegment = _decorate([customElement("ef-captions-segment")], EFCaptionsSegment);
|
|
120
|
+
let EFCaptionsBeforeActiveWord = class EFCaptionsBeforeActiveWord$1 extends EFCaptionsSegment {
|
|
121
|
+
constructor(..._args3) {
|
|
122
|
+
super(..._args3);
|
|
123
|
+
this.hidden = false;
|
|
124
|
+
this.segmentText = "";
|
|
125
|
+
this.segmentStartMs = 0;
|
|
126
|
+
this.segmentEndMs = 0;
|
|
127
|
+
}
|
|
128
|
+
static {
|
|
129
|
+
this.styles = [css`
|
|
144
130
|
:host {
|
|
145
131
|
display: inline-block;
|
|
146
132
|
white-space: pre;
|
|
@@ -148,48 +134,50 @@ EFCaptionsBeforeActiveWord.styles = [
|
|
|
148
134
|
:host([hidden]) {
|
|
149
135
|
display: none;
|
|
150
136
|
}
|
|
151
|
-
`
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
], EFCaptionsBeforeActiveWord);
|
|
168
|
-
let EFCaptionsAfterActiveWord = class extends EFCaptionsSegment {
|
|
169
|
-
constructor() {
|
|
170
|
-
super(...arguments);
|
|
171
|
-
this.hidden = false;
|
|
172
|
-
this.segmentText = "";
|
|
173
|
-
this.segmentStartMs = 0;
|
|
174
|
-
this.segmentEndMs = 0;
|
|
175
|
-
}
|
|
176
|
-
render() {
|
|
177
|
-
if (stopWords.has(this.segmentText)) {
|
|
178
|
-
this.hidden = true;
|
|
179
|
-
return void 0;
|
|
180
|
-
}
|
|
181
|
-
this.hidden = false;
|
|
182
|
-
return html`${this.segmentText} `;
|
|
183
|
-
}
|
|
184
|
-
get startTimeMs() {
|
|
185
|
-
return this.segmentStartMs || 0;
|
|
186
|
-
}
|
|
187
|
-
get durationMs() {
|
|
188
|
-
return this.segmentEndMs - this.segmentStartMs;
|
|
189
|
-
}
|
|
137
|
+
`];
|
|
138
|
+
}
|
|
139
|
+
render() {
|
|
140
|
+
if (stopWords.has(this.segmentText)) {
|
|
141
|
+
this.hidden = true;
|
|
142
|
+
return void 0;
|
|
143
|
+
}
|
|
144
|
+
this.hidden = false;
|
|
145
|
+
return html` ${this.segmentText}`;
|
|
146
|
+
}
|
|
147
|
+
get startTimeMs() {
|
|
148
|
+
return this.segmentStartMs || 0;
|
|
149
|
+
}
|
|
150
|
+
get durationMs() {
|
|
151
|
+
return this.segmentEndMs - this.segmentStartMs;
|
|
152
|
+
}
|
|
190
153
|
};
|
|
191
|
-
|
|
192
|
-
|
|
154
|
+
_decorate([property({
|
|
155
|
+
type: Boolean,
|
|
156
|
+
reflect: true
|
|
157
|
+
})], EFCaptionsBeforeActiveWord.prototype, "hidden", void 0);
|
|
158
|
+
_decorate([property({
|
|
159
|
+
type: String,
|
|
160
|
+
attribute: false
|
|
161
|
+
})], EFCaptionsBeforeActiveWord.prototype, "segmentText", void 0);
|
|
162
|
+
_decorate([property({
|
|
163
|
+
type: Number,
|
|
164
|
+
attribute: false
|
|
165
|
+
})], EFCaptionsBeforeActiveWord.prototype, "segmentStartMs", void 0);
|
|
166
|
+
_decorate([property({
|
|
167
|
+
type: Number,
|
|
168
|
+
attribute: false
|
|
169
|
+
})], EFCaptionsBeforeActiveWord.prototype, "segmentEndMs", void 0);
|
|
170
|
+
EFCaptionsBeforeActiveWord = _decorate([customElement("ef-captions-before-active-word")], EFCaptionsBeforeActiveWord);
|
|
171
|
+
let EFCaptionsAfterActiveWord = class EFCaptionsAfterActiveWord$1 extends EFCaptionsSegment {
|
|
172
|
+
constructor(..._args4) {
|
|
173
|
+
super(..._args4);
|
|
174
|
+
this.hidden = false;
|
|
175
|
+
this.segmentText = "";
|
|
176
|
+
this.segmentStartMs = 0;
|
|
177
|
+
this.segmentEndMs = 0;
|
|
178
|
+
}
|
|
179
|
+
static {
|
|
180
|
+
this.styles = [css`
|
|
193
181
|
:host {
|
|
194
182
|
display: inline-block;
|
|
195
183
|
white-space: pre;
|
|
@@ -197,192 +185,105 @@ EFCaptionsAfterActiveWord.styles = [
|
|
|
197
185
|
:host([hidden]) {
|
|
198
186
|
display: none;
|
|
199
187
|
}
|
|
200
|
-
`
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
], EFCaptionsAfterActiveWord);
|
|
217
|
-
let EFCaptions = class extends EFSourceMixin(
|
|
218
|
-
EFTemporal(FetchMixin(LitElement)),
|
|
219
|
-
{ assetType: "caption_files" }
|
|
220
|
-
) {
|
|
221
|
-
constructor() {
|
|
222
|
-
super(...arguments);
|
|
223
|
-
this.displayMode = "segment";
|
|
224
|
-
this.contextWords = 3;
|
|
225
|
-
this.targetSelector = "";
|
|
226
|
-
this.wordStyle = "";
|
|
227
|
-
this.activeWordContainers = this.getElementsByTagName("ef-captions-active-word");
|
|
228
|
-
this.segmentContainers = this.getElementsByTagName("ef-captions-segment");
|
|
229
|
-
this.beforeActiveWordContainers = this.getElementsByTagName(
|
|
230
|
-
"ef-captions-before-active-word"
|
|
231
|
-
);
|
|
232
|
-
this.afterActiveWordContainers = this.getElementsByTagName(
|
|
233
|
-
"ef-captions-after-active-word"
|
|
234
|
-
);
|
|
235
|
-
this.md5SumLoader = new Task(this, {
|
|
236
|
-
autoRun: false,
|
|
237
|
-
args: () => [this.target, this.fetch],
|
|
238
|
-
task: async ([_target, fetch], { signal }) => {
|
|
239
|
-
const md5Path = `/@ef-asset/${this.targetElement.src ?? ""}`;
|
|
240
|
-
const response = await fetch(md5Path, { method: "HEAD", signal });
|
|
241
|
-
return response.headers.get("etag") ?? void 0;
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
this.transcriptionDataTask = new Task(this, {
|
|
245
|
-
autoRun: EF_INTERACTIVE,
|
|
246
|
-
args: () => [this.transcriptionsPath(), this.fetch],
|
|
247
|
-
task: async ([transcriptionsPath, fetch], { signal }) => {
|
|
248
|
-
if (!transcriptionsPath) {
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
const response = await fetch(transcriptionsPath, { signal });
|
|
252
|
-
return response.json();
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
this.fragmentIndexTask = new Task(this, {
|
|
256
|
-
autoRun: EF_INTERACTIVE,
|
|
257
|
-
args: () => [this.transcriptionDataTask.value, this.ownCurrentTimeMs],
|
|
258
|
-
task: async ([transcription, ownCurrentTimeMs]) => {
|
|
259
|
-
if (!transcription) {
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
const fragmentIndex = Math.floor(
|
|
263
|
-
ownCurrentTimeMs / transcription.work_slice_ms
|
|
264
|
-
);
|
|
265
|
-
return fragmentIndex;
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
this.transcriptionFragmentDataTask = new Task(this, {
|
|
269
|
-
autoRun: EF_INTERACTIVE,
|
|
270
|
-
args: () => [
|
|
271
|
-
this.transcriptionDataTask.value,
|
|
272
|
-
this.fragmentIndexTask.value,
|
|
273
|
-
this.fetch
|
|
274
|
-
],
|
|
275
|
-
task: async ([transcription, fragmentIndex, fetch], { signal }) => {
|
|
276
|
-
if (transcription === null || transcription === void 0 || fragmentIndex === null || fragmentIndex === void 0) {
|
|
277
|
-
return null;
|
|
278
|
-
}
|
|
279
|
-
const fragmentPath = this.transcriptionFragmentPath(
|
|
280
|
-
transcription.id,
|
|
281
|
-
fragmentIndex
|
|
282
|
-
);
|
|
283
|
-
const response = await fetch(fragmentPath, { signal });
|
|
284
|
-
return response.json();
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
this.frameTask = new Task(this, {
|
|
288
|
-
autoRun: EF_INTERACTIVE,
|
|
289
|
-
args: () => [this.transcriptionFragmentDataTask.status],
|
|
290
|
-
task: async () => {
|
|
291
|
-
await this.transcriptionFragmentDataTask.taskComplete;
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
set target(value) {
|
|
296
|
-
this.targetSelector = value;
|
|
297
|
-
}
|
|
298
|
-
render() {
|
|
299
|
-
return html`<slot></slot>`;
|
|
300
|
-
}
|
|
301
|
-
transcriptionsPath() {
|
|
302
|
-
if (this.targetElement.assetId) {
|
|
303
|
-
return `${this.apiHost}/api/v1/isobmff_files/${this.targetElement.assetId}/transcription`;
|
|
304
|
-
}
|
|
305
|
-
return null;
|
|
306
|
-
}
|
|
307
|
-
captionsPath() {
|
|
308
|
-
if (this.targetElement.assetId) {
|
|
309
|
-
return `${this.apiHost}/api/v1/caption_files/${this.targetElement.assetId}`;
|
|
310
|
-
}
|
|
311
|
-
const targetSrc = this.targetElement.src;
|
|
312
|
-
return `/@ef-captions/${targetSrc}`;
|
|
313
|
-
}
|
|
314
|
-
transcriptionFragmentPath(transcriptionId, fragmentIndex) {
|
|
315
|
-
return `${this.apiHost}/api/v1/transcriptions/${transcriptionId}/fragments/${fragmentIndex}`;
|
|
316
|
-
}
|
|
317
|
-
connectedCallback() {
|
|
318
|
-
super.connectedCallback();
|
|
319
|
-
if (this.targetElement) {
|
|
320
|
-
new CrossUpdateController(this.targetElement, this);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
updated(_changedProperties) {
|
|
324
|
-
this.updateTextContainers();
|
|
325
|
-
}
|
|
326
|
-
updateTextContainers() {
|
|
327
|
-
const transcriptionFragment = this.transcriptionFragmentDataTask.value;
|
|
328
|
-
if (!transcriptionFragment) {
|
|
329
|
-
return;
|
|
330
|
-
}
|
|
331
|
-
const currentTimeMs = this.targetElement.currentSourceTimeMs;
|
|
332
|
-
const currentTimeSec = currentTimeMs / 1e3;
|
|
333
|
-
const currentWord = transcriptionFragment.word_segments.find(
|
|
334
|
-
(word) => currentTimeSec >= word.start && currentTimeSec <= word.end
|
|
335
|
-
);
|
|
336
|
-
const currentSegment = transcriptionFragment.segments.find(
|
|
337
|
-
(segment) => currentTimeSec >= segment.start && currentTimeSec <= segment.end
|
|
338
|
-
);
|
|
339
|
-
for (const wordContainer of this.activeWordContainers) {
|
|
340
|
-
if (currentWord) {
|
|
341
|
-
wordContainer.wordText = currentWord.text;
|
|
342
|
-
wordContainer.wordStartMs = currentWord.start * 1e3;
|
|
343
|
-
wordContainer.wordEndMs = currentWord.end * 1e3;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
for (const segmentContainer of this.segmentContainers) {
|
|
347
|
-
if (currentSegment) {
|
|
348
|
-
segmentContainer.segmentText = currentSegment.text;
|
|
349
|
-
segmentContainer.segmentStartMs = currentSegment.start * 1e3;
|
|
350
|
-
segmentContainer.segmentEndMs = currentSegment.end * 1e3;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
if (currentWord && currentSegment) {
|
|
354
|
-
const segmentWords = transcriptionFragment.word_segments.filter(
|
|
355
|
-
(word) => word.start >= currentSegment.start && word.end <= currentSegment.end
|
|
356
|
-
);
|
|
357
|
-
const currentWordIndex = segmentWords.findIndex(
|
|
358
|
-
(word) => word.start === currentWord.start && word.end === currentWord.end
|
|
359
|
-
);
|
|
360
|
-
if (currentWordIndex !== -1) {
|
|
361
|
-
const beforeWords = segmentWords.slice(0, currentWordIndex).map((w) => w.text.trim()).join(" ");
|
|
362
|
-
const afterWords = segmentWords.slice(currentWordIndex + 1).map((w) => w.text.trim()).join(" ");
|
|
363
|
-
for (const container of this.beforeActiveWordContainers) {
|
|
364
|
-
container.segmentText = beforeWords;
|
|
365
|
-
container.segmentStartMs = currentSegment.start * 1e3;
|
|
366
|
-
container.segmentEndMs = currentWord.start * 1e3;
|
|
367
|
-
}
|
|
368
|
-
for (const container of this.afterActiveWordContainers) {
|
|
369
|
-
container.segmentText = afterWords;
|
|
370
|
-
container.segmentStartMs = currentWord.end * 1e3;
|
|
371
|
-
container.segmentEndMs = currentSegment.end * 1e3;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
get targetElement() {
|
|
377
|
-
const target = document.getElementById(this.targetSelector ?? "");
|
|
378
|
-
if (target instanceof EFAudio || target instanceof EFVideo) {
|
|
379
|
-
return target;
|
|
380
|
-
}
|
|
381
|
-
throw new Error("Invalid target, must be an EFAudio or EFVideo element");
|
|
382
|
-
}
|
|
188
|
+
`];
|
|
189
|
+
}
|
|
190
|
+
render() {
|
|
191
|
+
if (stopWords.has(this.segmentText)) {
|
|
192
|
+
this.hidden = true;
|
|
193
|
+
return void 0;
|
|
194
|
+
}
|
|
195
|
+
this.hidden = false;
|
|
196
|
+
return html`${this.segmentText} `;
|
|
197
|
+
}
|
|
198
|
+
get startTimeMs() {
|
|
199
|
+
return this.segmentStartMs || 0;
|
|
200
|
+
}
|
|
201
|
+
get durationMs() {
|
|
202
|
+
return this.segmentEndMs - this.segmentStartMs;
|
|
203
|
+
}
|
|
383
204
|
};
|
|
384
|
-
|
|
385
|
-
|
|
205
|
+
_decorate([property({
|
|
206
|
+
type: Boolean,
|
|
207
|
+
reflect: true
|
|
208
|
+
})], EFCaptionsAfterActiveWord.prototype, "hidden", void 0);
|
|
209
|
+
_decorate([property({
|
|
210
|
+
type: String,
|
|
211
|
+
attribute: false
|
|
212
|
+
})], EFCaptionsAfterActiveWord.prototype, "segmentText", void 0);
|
|
213
|
+
_decorate([property({
|
|
214
|
+
type: Number,
|
|
215
|
+
attribute: false
|
|
216
|
+
})], EFCaptionsAfterActiveWord.prototype, "segmentStartMs", void 0);
|
|
217
|
+
_decorate([property({
|
|
218
|
+
type: Number,
|
|
219
|
+
attribute: false
|
|
220
|
+
})], EFCaptionsAfterActiveWord.prototype, "segmentEndMs", void 0);
|
|
221
|
+
EFCaptionsAfterActiveWord = _decorate([customElement("ef-captions-after-active-word")], EFCaptionsAfterActiveWord);
|
|
222
|
+
let EFCaptions = class EFCaptions$1 extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), { assetType: "caption_files" }) {
|
|
223
|
+
constructor(..._args5) {
|
|
224
|
+
super(..._args5);
|
|
225
|
+
this.displayMode = "segment";
|
|
226
|
+
this.contextWords = 3;
|
|
227
|
+
this.targetSelector = "";
|
|
228
|
+
this.wordStyle = "";
|
|
229
|
+
this.activeWordContainers = this.getElementsByTagName("ef-captions-active-word");
|
|
230
|
+
this.segmentContainers = this.getElementsByTagName("ef-captions-segment");
|
|
231
|
+
this.beforeActiveWordContainers = this.getElementsByTagName("ef-captions-before-active-word");
|
|
232
|
+
this.afterActiveWordContainers = this.getElementsByTagName("ef-captions-after-active-word");
|
|
233
|
+
this.md5SumLoader = new Task(this, {
|
|
234
|
+
autoRun: false,
|
|
235
|
+
args: () => [this.target, this.fetch],
|
|
236
|
+
task: async ([_target, fetch], { signal }) => {
|
|
237
|
+
const md5Path = `/@ef-asset/${this.targetElement.src ?? ""}`;
|
|
238
|
+
const response = await fetch(md5Path, {
|
|
239
|
+
method: "HEAD",
|
|
240
|
+
signal
|
|
241
|
+
});
|
|
242
|
+
return response.headers.get("etag") ?? void 0;
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
this.transcriptionDataTask = new Task(this, {
|
|
246
|
+
autoRun: EF_INTERACTIVE,
|
|
247
|
+
args: () => [this.transcriptionsPath(), this.fetch],
|
|
248
|
+
task: async ([transcriptionsPath, fetch], { signal }) => {
|
|
249
|
+
if (!transcriptionsPath) return null;
|
|
250
|
+
const response = await fetch(transcriptionsPath, { signal });
|
|
251
|
+
return response.json();
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
this.fragmentIndexTask = new Task(this, {
|
|
255
|
+
autoRun: EF_INTERACTIVE,
|
|
256
|
+
args: () => [this.transcriptionDataTask.value, this.ownCurrentTimeMs],
|
|
257
|
+
task: async ([transcription, ownCurrentTimeMs]) => {
|
|
258
|
+
if (!transcription) return null;
|
|
259
|
+
const fragmentIndex = Math.floor(ownCurrentTimeMs / transcription.work_slice_ms);
|
|
260
|
+
return fragmentIndex;
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
this.transcriptionFragmentDataTask = new Task(this, {
|
|
264
|
+
autoRun: EF_INTERACTIVE,
|
|
265
|
+
args: () => [
|
|
266
|
+
this.transcriptionDataTask.value,
|
|
267
|
+
this.fragmentIndexTask.value,
|
|
268
|
+
this.fetch
|
|
269
|
+
],
|
|
270
|
+
task: async ([transcription, fragmentIndex, fetch], { signal }) => {
|
|
271
|
+
if (transcription === null || transcription === void 0 || fragmentIndex === null || fragmentIndex === void 0) return null;
|
|
272
|
+
const fragmentPath = this.transcriptionFragmentPath(transcription.id, fragmentIndex);
|
|
273
|
+
const response = await fetch(fragmentPath, { signal });
|
|
274
|
+
return response.json();
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
this.frameTask = new Task(this, {
|
|
278
|
+
autoRun: EF_INTERACTIVE,
|
|
279
|
+
args: () => [this.transcriptionFragmentDataTask.status],
|
|
280
|
+
task: async () => {
|
|
281
|
+
await this.transcriptionFragmentDataTask.taskComplete;
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
static {
|
|
286
|
+
this.styles = [css`
|
|
386
287
|
:host {
|
|
387
288
|
display: flex;
|
|
388
289
|
flex-wrap: wrap;
|
|
@@ -393,27 +294,90 @@ EFCaptions.styles = [
|
|
|
393
294
|
margin: 0;
|
|
394
295
|
padding: 0;
|
|
395
296
|
}
|
|
396
|
-
`
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
297
|
+
`];
|
|
298
|
+
}
|
|
299
|
+
set target(value) {
|
|
300
|
+
this.targetSelector = value;
|
|
301
|
+
}
|
|
302
|
+
render() {
|
|
303
|
+
return html`<slot></slot>`;
|
|
304
|
+
}
|
|
305
|
+
transcriptionsPath() {
|
|
306
|
+
if (this.targetElement.assetId) return `${this.apiHost}/api/v1/isobmff_files/${this.targetElement.assetId}/transcription`;
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
captionsPath() {
|
|
310
|
+
if (this.targetElement.assetId) return `${this.apiHost}/api/v1/caption_files/${this.targetElement.assetId}`;
|
|
311
|
+
const targetSrc = this.targetElement.src;
|
|
312
|
+
return `/@ef-captions/${targetSrc}`;
|
|
313
|
+
}
|
|
314
|
+
transcriptionFragmentPath(transcriptionId, fragmentIndex) {
|
|
315
|
+
return `${this.apiHost}/api/v1/transcriptions/${transcriptionId}/fragments/${fragmentIndex}`;
|
|
316
|
+
}
|
|
317
|
+
connectedCallback() {
|
|
318
|
+
super.connectedCallback();
|
|
319
|
+
if (this.targetElement) new CrossUpdateController(this.targetElement, this);
|
|
320
|
+
}
|
|
321
|
+
updated(_changedProperties) {
|
|
322
|
+
this.updateTextContainers();
|
|
323
|
+
}
|
|
324
|
+
updateTextContainers() {
|
|
325
|
+
const transcriptionFragment = this.transcriptionFragmentDataTask.value;
|
|
326
|
+
if (!transcriptionFragment) return;
|
|
327
|
+
const currentTimeMs = this.targetElement.currentSourceTimeMs;
|
|
328
|
+
const currentTimeSec = currentTimeMs / 1e3;
|
|
329
|
+
const currentWord = transcriptionFragment.word_segments.find((word) => currentTimeSec >= word.start && currentTimeSec <= word.end);
|
|
330
|
+
const currentSegment = transcriptionFragment.segments.find((segment) => currentTimeSec >= segment.start && currentTimeSec <= segment.end);
|
|
331
|
+
for (const wordContainer of this.activeWordContainers) if (currentWord) {
|
|
332
|
+
wordContainer.wordText = currentWord.text;
|
|
333
|
+
wordContainer.wordStartMs = currentWord.start * 1e3;
|
|
334
|
+
wordContainer.wordEndMs = currentWord.end * 1e3;
|
|
335
|
+
}
|
|
336
|
+
for (const segmentContainer of this.segmentContainers) if (currentSegment) {
|
|
337
|
+
segmentContainer.segmentText = currentSegment.text;
|
|
338
|
+
segmentContainer.segmentStartMs = currentSegment.start * 1e3;
|
|
339
|
+
segmentContainer.segmentEndMs = currentSegment.end * 1e3;
|
|
340
|
+
}
|
|
341
|
+
if (currentWord && currentSegment) {
|
|
342
|
+
const segmentWords = transcriptionFragment.word_segments.filter((word) => word.start >= currentSegment.start && word.end <= currentSegment.end);
|
|
343
|
+
const currentWordIndex = segmentWords.findIndex((word) => word.start === currentWord.start && word.end === currentWord.end);
|
|
344
|
+
if (currentWordIndex !== -1) {
|
|
345
|
+
const beforeWords = segmentWords.slice(0, currentWordIndex).map((w) => w.text.trim()).join(" ");
|
|
346
|
+
const afterWords = segmentWords.slice(currentWordIndex + 1).map((w) => w.text.trim()).join(" ");
|
|
347
|
+
for (const container of this.beforeActiveWordContainers) {
|
|
348
|
+
container.segmentText = beforeWords;
|
|
349
|
+
container.segmentStartMs = currentSegment.start * 1e3;
|
|
350
|
+
container.segmentEndMs = currentWord.start * 1e3;
|
|
351
|
+
}
|
|
352
|
+
for (const container of this.afterActiveWordContainers) {
|
|
353
|
+
container.segmentText = afterWords;
|
|
354
|
+
container.segmentStartMs = currentWord.end * 1e3;
|
|
355
|
+
container.segmentEndMs = currentSegment.end * 1e3;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
get targetElement() {
|
|
361
|
+
const target = document.getElementById(this.targetSelector ?? "");
|
|
362
|
+
if (target instanceof EFAudio || target instanceof EFVideo) return target;
|
|
363
|
+
throw new Error("Invalid target, must be an EFAudio or EFVideo element");
|
|
364
|
+
}
|
|
419
365
|
};
|
|
366
|
+
_decorate([property({
|
|
367
|
+
type: String,
|
|
368
|
+
attribute: "display-mode",
|
|
369
|
+
reflect: true
|
|
370
|
+
})], EFCaptions.prototype, "displayMode", void 0);
|
|
371
|
+
_decorate([property({
|
|
372
|
+
type: Number,
|
|
373
|
+
attribute: "context-words",
|
|
374
|
+
reflect: true
|
|
375
|
+
})], EFCaptions.prototype, "contextWords", void 0);
|
|
376
|
+
_decorate([property({
|
|
377
|
+
type: String,
|
|
378
|
+
attribute: "target",
|
|
379
|
+
reflect: true
|
|
380
|
+
})], EFCaptions.prototype, "targetSelector", void 0);
|
|
381
|
+
_decorate([property({ attribute: "word-style" })], EFCaptions.prototype, "wordStyle", void 0);
|
|
382
|
+
EFCaptions = _decorate([customElement("ef-captions")], EFCaptions);
|
|
383
|
+
export { EFCaptions, EFCaptionsActiveWord, EFCaptionsAfterActiveWord, EFCaptionsBeforeActiveWord, EFCaptionsSegment };
|