shiveshnavin commited on
Commit
217d1ce
·
1 Parent(s): f077067

Add hhit color

Browse files
Files changed (1) hide show
  1. server-plugins/generate-captions.js +51 -6
server-plugins/generate-captions.js CHANGED
@@ -63,9 +63,16 @@ export class CaptionPlugin extends Plugin {
63
  fontSize = 72,
64
  wordsPerGroup = 4,
65
  videoWidth = 1920,
66
- videoHeight = 1080
 
 
67
  } = options;
68
 
 
 
 
 
 
69
  // Read and parse JSON file
70
  const jsonData = JSON.parse(readFileSync(captionFilePath, 'utf-8'));
71
  const transcript = jsonData.transcript || '';
@@ -86,7 +93,19 @@ export class CaptionPlugin extends Plugin {
86
  const output = createWriteStream(outputFilePath);
87
 
88
  // Write header with calculated margins
89
- output.write(createASSHeader(videoWidth, videoHeight, fontName, fontSize, translateY, sideMargin, sideMargin));
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  // Process words in groups respecting sentence boundaries
92
  let i = 0;
@@ -135,7 +154,7 @@ export class CaptionPlugin extends Plugin {
135
  const captionParts = wordGroup.map((w, idx) => {
136
  if (idx === wordIdx) {
137
  // Current word - highlighted in green
138
- return `{\\c&H00FF00&}${w.word}{\\c&HFFFFFF&}`;
139
  } else {
140
  // Other words - white
141
  return w.word;
@@ -234,7 +253,17 @@ function assignSentenceToWords(words, transcript) {
234
  * @param {number} marginV
235
  * @returns {string}
236
  */
237
- function createASSHeader(videoWidth = 1920, videoHeight = 1080, fontName = 'Impact', fontSize = 72, marginV = 200, marginL = 10, marginR = 10) {
 
 
 
 
 
 
 
 
 
 
238
  return `[Script Info]
239
  Title: Word-by-Word Captions
240
  ScriptType: v4.00+
@@ -245,11 +274,27 @@ ScaledBorderAndShadow: yes
245
 
246
  [V4+ Styles]
247
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
248
- Style: Default,${fontName},${fontSize},&H00FFFFFF,&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,3,2,2,${marginL},${marginR},${marginV},1
249
- Style: Highlight,${fontName},${fontSize},&H0000FF00,&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,3,2,2,${marginL},${marginR},${marginV},1
250
 
251
  [Events]
252
  Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
253
  `;
254
  }
255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  fontSize = 72,
64
  wordsPerGroup = 4,
65
  videoWidth = 1920,
66
+ videoHeight = 1080,
67
+ fontColor = '#FFFFFF',
68
+ fontHighlightColor = '#00FF00'
69
  } = options;
70
 
71
+ const assFontColor = hexToASSColor(fontColor);
72
+ const assHighlightColor = hexToASSColor(fontHighlightColor);
73
+ const assHighlightColorInline = `${assHighlightColor}&`;
74
+ const assFontColorInline = `${assFontColor}&`;
75
+
76
  // Read and parse JSON file
77
  const jsonData = JSON.parse(readFileSync(captionFilePath, 'utf-8'));
78
  const transcript = jsonData.transcript || '';
 
93
  const output = createWriteStream(outputFilePath);
94
 
95
  // Write header with calculated margins
96
+ output.write(
97
+ createASSHeader(
98
+ videoWidth,
99
+ videoHeight,
100
+ fontName,
101
+ fontSize,
102
+ translateY,
103
+ sideMargin,
104
+ sideMargin,
105
+ assFontColor,
106
+ assHighlightColor
107
+ )
108
+ );
109
 
110
  // Process words in groups respecting sentence boundaries
111
  let i = 0;
 
154
  const captionParts = wordGroup.map((w, idx) => {
155
  if (idx === wordIdx) {
156
  // Current word - highlighted in green
157
+ return `{\\c${assHighlightColorInline}}${w.word}{\\c${assFontColorInline}}`;
158
  } else {
159
  // Other words - white
160
  return w.word;
 
253
  * @param {number} marginV
254
  * @returns {string}
255
  */
256
+ function createASSHeader(
257
+ videoWidth = 1920,
258
+ videoHeight = 1080,
259
+ fontName = 'Impact',
260
+ fontSize = 72,
261
+ marginV = 200,
262
+ marginL = 10,
263
+ marginR = 10,
264
+ primaryColor = '&H00FFFFFF',
265
+ highlightColor = '&H0000FF00'
266
+ ) {
267
  return `[Script Info]
268
  Title: Word-by-Word Captions
269
  ScriptType: v4.00+
 
274
 
275
  [V4+ Styles]
276
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
277
+ Style: Default,${fontName},${fontSize},${primaryColor},&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,3,2,2,${marginL},${marginR},${marginV},1
278
+ Style: Highlight,${fontName},${fontSize},${highlightColor},&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,0,0,1,3,2,2,${marginL},${marginR},${marginV},1
279
 
280
  [Events]
281
  Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
282
  `;
283
  }
284
 
285
+ function hexToASSColor(hexValue) {
286
+ if (typeof hexValue !== 'string') {
287
+ throw new Error('fontColor values must be hex strings like #RRGGBB');
288
+ }
289
+
290
+ const normalized = hexValue.trim().replace('#', '');
291
+ if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {
292
+ throw new Error(`Invalid hex color provided: ${hexValue}`);
293
+ }
294
+
295
+ const r = normalized.slice(0, 2);
296
+ const g = normalized.slice(2, 4);
297
+ const b = normalized.slice(4, 6);
298
+ return `&H00${b}${g}${r}`.toUpperCase();
299
+ }
300
+