@remotion/captions 4.0.517 → 4.0.519

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/dist/caption.d.ts CHANGED
@@ -4,4 +4,5 @@ export type Caption = {
4
4
  endMs: number;
5
5
  timestampMs: number | null;
6
6
  confidence: number | null;
7
+ pageBreakAfter?: boolean;
7
8
  };
@@ -3,6 +3,7 @@ export type TikTokToken = {
3
3
  text: string;
4
4
  fromMs: number;
5
5
  toMs: number;
6
+ pageBreakAfter?: boolean;
6
7
  };
7
8
  export type TikTokPage = {
8
9
  text: string;
@@ -8,8 +8,11 @@ const createTikTokStyleCaptions = ({ captions, combineTokensWithinMilliseconds,
8
8
  let currentFrom = 0;
9
9
  let currentTo = 0;
10
10
  const add = () => {
11
+ const text = currentText.endsWith('\n')
12
+ ? currentText.slice(0, -1)
13
+ : currentText;
11
14
  tikTokStyleCaptions.push({
12
- text: currentText.trimStart(),
15
+ text: text.trimStart(),
13
16
  startMs: currentFrom,
14
17
  tokens: currentTokens,
15
18
  durationMs: Infinity,
@@ -35,7 +38,12 @@ const createTikTokStyleCaptions = ({ captions, combineTokensWithinMilliseconds,
35
38
  // Start a new sentence
36
39
  currentText = text.trimStart();
37
40
  currentTokens = [
38
- { text: currentText, fromMs: item.startMs, toMs: item.endMs },
41
+ {
42
+ text: text.trimStart(),
43
+ fromMs: item.startMs,
44
+ toMs: item.endMs,
45
+ ...(item.pageBreakAfter ? { pageBreakAfter: true } : {}),
46
+ },
39
47
  ].filter((t) => t.text !== '');
40
48
  currentFrom = item.startMs;
41
49
  currentTo = item.endMs;
@@ -46,17 +54,24 @@ const createTikTokStyleCaptions = ({ captions, combineTokensWithinMilliseconds,
46
54
  // It's the start of the document or after a sentence that started with a space
47
55
  currentFrom = item.startMs;
48
56
  }
49
- currentText += text;
57
+ const textToAppend = text;
58
+ currentText += textToAppend;
50
59
  currentText = currentText.trimStart();
51
60
  if (text.trim() !== '') {
52
61
  currentTokens.push({
53
- text: currentTokens.length === 0 ? currentText.trimStart() : text,
62
+ text: currentTokens.length === 0 ? currentText.trimStart() : textToAppend,
54
63
  fromMs: item.startMs,
55
64
  toMs: item.endMs,
65
+ ...(item.pageBreakAfter ? { pageBreakAfter: true } : {}),
56
66
  });
57
67
  }
58
68
  currentTo = item.endMs;
59
69
  }
70
+ if (item.pageBreakAfter && currentText !== '') {
71
+ add();
72
+ currentText = '';
73
+ currentTokens = [];
74
+ }
60
75
  // Ensure the last sentence is added
61
76
  if (index === captions.length - 1 && currentText !== '') {
62
77
  add();
@@ -14,6 +14,9 @@ const splitWords = (inputCaptions) => {
14
14
  endMs: w.endMs,
15
15
  confidence: w.confidence,
16
16
  timestampMs: w.timestampMs,
17
+ ...(j === words.length - 1 && w.pageBreakAfter
18
+ ? { pageBreakAfter: true }
19
+ : {}),
17
20
  });
18
21
  }
19
22
  }
@@ -38,8 +41,14 @@ const ensureMaxCharactersPerLine = ({ captions, maxCharsPerLine, }) => {
38
41
  currentSegment = [];
39
42
  }
40
43
  currentSegment.push(w);
44
+ if (w.pageBreakAfter && i < splitted.length - 1) {
45
+ segments.push(currentSegment);
46
+ currentSegment = [];
47
+ }
48
+ }
49
+ if (currentSegment.length > 0) {
50
+ segments.push(currentSegment);
41
51
  }
42
- segments.push(currentSegment);
43
52
  return { segments };
44
53
  };
45
54
  exports.ensureMaxCharactersPerLine = ensureMaxCharactersPerLine;
@@ -11,7 +11,8 @@ var splitWords = (inputCaptions) => {
11
11
  startMs: w.startMs,
12
12
  endMs: w.endMs,
13
13
  confidence: w.confidence,
14
- timestampMs: w.timestampMs
14
+ timestampMs: w.timestampMs,
15
+ ...j === words.length - 1 && w.pageBreakAfter ? { pageBreakAfter: true } : {}
15
16
  });
16
17
  }
17
18
  }
@@ -34,8 +35,14 @@ var ensureMaxCharactersPerLine = ({
34
35
  currentSegment = [];
35
36
  }
36
37
  currentSegment.push(w);
38
+ if (w.pageBreakAfter && i < splitted.length - 1) {
39
+ segments.push(currentSegment);
40
+ currentSegment = [];
41
+ }
42
+ }
43
+ if (currentSegment.length > 0) {
44
+ segments.push(currentSegment);
37
45
  }
38
- segments.push(currentSegment);
39
46
  return { segments };
40
47
  };
41
48
  // src/create-tiktok-style-captions.ts
@@ -50,8 +57,10 @@ var createTikTokStyleCaptions = ({
50
57
  let currentFrom = 0;
51
58
  let currentTo = 0;
52
59
  const add = () => {
60
+ const text = currentText.endsWith(`
61
+ `) ? currentText.slice(0, -1) : currentText;
53
62
  tikTokStyleCaptions.push({
54
- text: currentText.trimStart(),
63
+ text: text.trimStart(),
55
64
  startMs: currentFrom,
56
65
  tokens: currentTokens,
57
66
  durationMs: Infinity
@@ -70,7 +79,12 @@ var createTikTokStyleCaptions = ({
70
79
  }
71
80
  currentText = text.trimStart();
72
81
  currentTokens = [
73
- { text: currentText, fromMs: item.startMs, toMs: item.endMs }
82
+ {
83
+ text: text.trimStart(),
84
+ fromMs: item.startMs,
85
+ toMs: item.endMs,
86
+ ...item.pageBreakAfter ? { pageBreakAfter: true } : {}
87
+ }
74
88
  ].filter((t) => t.text !== "");
75
89
  currentFrom = item.startMs;
76
90
  currentTo = item.endMs;
@@ -78,17 +92,24 @@ var createTikTokStyleCaptions = ({
78
92
  if (currentText === "") {
79
93
  currentFrom = item.startMs;
80
94
  }
81
- currentText += text;
95
+ const textToAppend = text;
96
+ currentText += textToAppend;
82
97
  currentText = currentText.trimStart();
83
98
  if (text.trim() !== "") {
84
99
  currentTokens.push({
85
- text: currentTokens.length === 0 ? currentText.trimStart() : text,
100
+ text: currentTokens.length === 0 ? currentText.trimStart() : textToAppend,
86
101
  fromMs: item.startMs,
87
- toMs: item.endMs
102
+ toMs: item.endMs,
103
+ ...item.pageBreakAfter ? { pageBreakAfter: true } : {}
88
104
  });
89
105
  }
90
106
  currentTo = item.endMs;
91
107
  }
108
+ if (item.pageBreakAfter && currentText !== "") {
109
+ add();
110
+ currentText = "";
111
+ currentTokens = [];
112
+ }
92
113
  if (index === captions.length - 1 && currentText !== "") {
93
114
  add();
94
115
  tikTokStyleCaptions[tikTokStyleCaptions.length - 1].durationMs = currentTo - tikTokStyleCaptions[tikTokStyleCaptions.length - 1].startMs;
@@ -169,21 +190,30 @@ var formatSrtTimestamp = (startMs, endMs) => {
169
190
  return `${formatSingleSrtTimestamp(startMs)} --> ${formatSingleSrtTimestamp(endMs)}`;
170
191
  };
171
192
  var serializeSrt = ({ lines }) => {
172
- let currentIndex = 0;
173
- return lines.map((s) => {
174
- currentIndex++;
175
- if (s.length === 0) {
176
- return null;
193
+ const cues = [];
194
+ for (const line of lines) {
195
+ let currentCue = [];
196
+ for (const caption of line) {
197
+ currentCue.push(caption);
198
+ if (caption.pageBreakAfter) {
199
+ cues.push(currentCue);
200
+ currentCue = [];
201
+ }
177
202
  }
203
+ if (currentCue.length > 0) {
204
+ cues.push(currentCue);
205
+ }
206
+ }
207
+ return cues.map((s, index) => {
178
208
  const firstTimestamp = s[0].startMs;
179
209
  const lastTimestamp = s[s.length - 1].endMs;
180
210
  return [
181
- currentIndex,
211
+ index + 1,
182
212
  formatSrtTimestamp(firstTimestamp, lastTimestamp),
183
213
  s.map((caption) => caption.text).join("")
184
214
  ].join(`
185
215
  `);
186
- }).filter(Boolean).join(`
216
+ }).join(`
187
217
 
188
218
  `);
189
219
  };
@@ -12,24 +12,32 @@ const formatSrtTimestamp = (startMs, endMs) => {
12
12
  return `${formatSingleSrtTimestamp(startMs)} --> ${formatSingleSrtTimestamp(endMs)}`;
13
13
  };
14
14
  const serializeSrt = ({ lines }) => {
15
- let currentIndex = 0;
16
- return lines
17
- .map((s) => {
18
- currentIndex++;
19
- if (s.length === 0) {
20
- return null;
15
+ const cues = [];
16
+ for (const line of lines) {
17
+ let currentCue = [];
18
+ for (const caption of line) {
19
+ currentCue.push(caption);
20
+ if (caption.pageBreakAfter) {
21
+ cues.push(currentCue);
22
+ currentCue = [];
23
+ }
21
24
  }
25
+ if (currentCue.length > 0) {
26
+ cues.push(currentCue);
27
+ }
28
+ }
29
+ return cues
30
+ .map((s, index) => {
22
31
  const firstTimestamp = s[0].startMs;
23
32
  const lastTimestamp = s[s.length - 1].endMs;
24
33
  return [
25
34
  // Index
26
- currentIndex,
35
+ index + 1,
27
36
  formatSrtTimestamp(firstTimestamp, lastTimestamp),
28
37
  // Text
29
38
  s.map((caption) => caption.text).join(''),
30
39
  ].join('\n');
31
40
  })
32
- .filter(Boolean)
33
41
  .join('\n\n');
34
42
  };
35
43
  exports.serializeSrt = serializeSrt;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/captions"
4
4
  },
5
5
  "name": "@remotion/captions",
6
- "version": "4.0.517",
6
+ "version": "4.0.519",
7
7
  "description": "Primitives for dealing with captions",
8
8
  "main": "dist/index.js",
9
9
  "types": "dist/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "dependencies": {},
24
24
  "peerDependencies": {},
25
25
  "devDependencies": {
26
- "@remotion/eslint-config-internal": "4.0.517",
26
+ "@remotion/eslint-config-internal": "4.0.519",
27
27
  "eslint": "9.19.0",
28
28
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
29
29
  },