@editframe/assets 0.47.1 → 0.48.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.
Files changed (64) hide show
  1. package/LICENSE-FULL.md +148 -0
  2. package/LICENSE.md +58 -0
  3. package/dist/Probe.cjs +63 -9
  4. package/dist/Probe.cjs.map +1 -1
  5. package/dist/Probe.d.cts +49 -0
  6. package/dist/Probe.d.ts +49 -0
  7. package/dist/Probe.js +59 -3
  8. package/dist/Probe.js.map +1 -1
  9. package/dist/VideoRenderOptions.cjs +2 -4
  10. package/dist/VideoRenderOptions.cjs.map +1 -1
  11. package/dist/VideoRenderOptions.js +1 -2
  12. package/dist/VideoRenderOptions.js.map +1 -1
  13. package/dist/_virtual/{rolldown_runtime.cjs → _rolldown/runtime.cjs} +2 -4
  14. package/dist/generateFragmentIndex.cjs +4 -12
  15. package/dist/generateFragmentIndex.cjs.map +1 -1
  16. package/dist/generateFragmentIndex.d.cts +1 -2
  17. package/dist/generateFragmentIndex.d.ts +1 -2
  18. package/dist/generateFragmentIndex.js +1 -2
  19. package/dist/generateFragmentIndex.js.map +1 -1
  20. package/dist/generateSingleTrack.cjs +7 -10
  21. package/dist/generateSingleTrack.cjs.map +1 -1
  22. package/dist/generateSingleTrack.js +2 -3
  23. package/dist/generateSingleTrack.js.map +1 -1
  24. package/dist/generateWebmSegmentIndex.cjs +346 -0
  25. package/dist/generateWebmSegmentIndex.cjs.map +1 -0
  26. package/dist/generateWebmSegmentIndex.js +343 -0
  27. package/dist/generateWebmSegmentIndex.js.map +1 -0
  28. package/dist/idempotentTask.cjs +5 -10
  29. package/dist/idempotentTask.cjs.map +1 -1
  30. package/dist/idempotentTask.d.cts +0 -1
  31. package/dist/idempotentTask.d.ts +0 -1
  32. package/dist/idempotentTask.js +1 -2
  33. package/dist/idempotentTask.js.map +1 -1
  34. package/dist/index.cjs +11 -11
  35. package/dist/index.js +1 -2
  36. package/dist/md5.cjs +3 -7
  37. package/dist/md5.cjs.map +1 -1
  38. package/dist/md5.js +1 -2
  39. package/dist/md5.js.map +1 -1
  40. package/dist/tasks/cacheImage.cjs +4 -6
  41. package/dist/tasks/cacheImage.cjs.map +1 -1
  42. package/dist/tasks/cacheImage.js +1 -2
  43. package/dist/tasks/cacheImage.js.map +1 -1
  44. package/dist/tasks/findOrCreateCaptions.cjs +5 -10
  45. package/dist/tasks/findOrCreateCaptions.cjs.map +1 -1
  46. package/dist/tasks/findOrCreateCaptions.js +1 -2
  47. package/dist/tasks/findOrCreateCaptions.js.map +1 -1
  48. package/dist/tasks/generateScrubTrack.cjs +6 -9
  49. package/dist/tasks/generateScrubTrack.cjs.map +1 -1
  50. package/dist/tasks/generateScrubTrack.js +1 -2
  51. package/dist/tasks/generateScrubTrack.js.map +1 -1
  52. package/dist/tasks/generateTrack.cjs +21 -9
  53. package/dist/tasks/generateTrack.cjs.map +1 -1
  54. package/dist/tasks/generateTrack.js +17 -4
  55. package/dist/tasks/generateTrack.js.map +1 -1
  56. package/dist/tasks/generateTrackFragmentIndex.cjs +26 -11
  57. package/dist/tasks/generateTrackFragmentIndex.cjs.map +1 -1
  58. package/dist/tasks/generateTrackFragmentIndex.js +21 -5
  59. package/dist/tasks/generateTrackFragmentIndex.js.map +1 -1
  60. package/dist/truncateDecimal.cjs +1 -2
  61. package/dist/truncateDecimal.cjs.map +1 -1
  62. package/dist/truncateDecimal.js +1 -1
  63. package/dist/truncateDecimal.js.map +1 -1
  64. package/package.json +1 -1
@@ -1,10 +1,8 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- const require_idempotentTask = require('../idempotentTask.cjs');
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_idempotentTask = require("../idempotentTask.cjs");
3
3
  let node_fs = require("node:fs");
4
- node_fs = require_rolldown_runtime.__toESM(node_fs);
5
4
  let node_path = require("node:path");
6
- node_path = require_rolldown_runtime.__toESM(node_path);
7
-
5
+ node_path = require_runtime.__toESM(node_path);
8
6
  //#region src/tasks/cacheImage.ts
9
7
  const cacheImageTask = require_idempotentTask.idempotentTask({
10
8
  label: "image",
@@ -22,7 +20,7 @@ const cacheImage = async (cacheRoot, absolutePath) => {
22
20
  throw error;
23
21
  }
24
22
  };
25
-
26
23
  //#endregion
27
24
  exports.cacheImage = cacheImage;
25
+
28
26
  //# sourceMappingURL=cacheImage.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cacheImage.cjs","names":["idempotentTask","path"],"sources":["../../src/tasks/cacheImage.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport { createReadStream } from \"node:fs\";\n\nimport path from \"node:path\";\n\nconst cacheImageTask = idempotentTask({\n label: \"image\",\n filename: (absolutePath: string) => path.basename(absolutePath),\n runner: async (absolutePath) => {\n return createReadStream(absolutePath);\n },\n});\n\nexport const cacheImage = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await cacheImageTask(cacheRoot, absolutePath);\n } catch (error) {\n console.error(error);\n console.trace(\"Error caching image\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;AAKA,MAAM,iBAAiBA,sCAAe;CACpC,OAAO;CACP,WAAW,iBAAyBC,kBAAK,SAAS,aAAa;CAC/D,QAAQ,OAAO,iBAAiB;AAC9B,uCAAwB,aAAa;;CAExC,CAAC;AAEF,MAAa,aAAa,OAAO,WAAmB,iBAAyB;AAC3E,KAAI;AACF,SAAO,MAAM,eAAe,WAAW,aAAa;UAC7C,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,uBAAuB,MAAM;AAC3C,QAAM"}
1
+ {"version":3,"file":"cacheImage.cjs","names":["idempotentTask","path"],"sources":["../../src/tasks/cacheImage.ts"],"mappings":";;;;;;AAKA,MAAM,iBAAiBA,uBAAAA,eAAe;CACpC,OAAO;CACP,WAAW,iBAAyBC,UAAAA,QAAK,SAAS,aAAa;CAC/D,QAAQ,OAAO,iBAAiB;AAC9B,UAAA,GAAA,QAAA,kBAAwB,aAAa;;CAExC,CAAC;AAEF,MAAa,aAAa,OAAO,WAAmB,iBAAyB;AAC3E,KAAI;AACF,SAAO,MAAM,eAAe,WAAW,aAAa;UAC7C,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,uBAAuB,MAAM;AAC3C,QAAM"}
@@ -1,7 +1,6 @@
1
1
  import { idempotentTask } from "../idempotentTask.js";
2
2
  import { createReadStream } from "node:fs";
3
3
  import path from "node:path";
4
-
5
4
  //#region src/tasks/cacheImage.ts
6
5
  const cacheImageTask = idempotentTask({
7
6
  label: "image",
@@ -19,7 +18,7 @@ const cacheImage = async (cacheRoot, absolutePath) => {
19
18
  throw error;
20
19
  }
21
20
  };
22
-
23
21
  //#endregion
24
22
  export { cacheImage };
23
+
25
24
  //# sourceMappingURL=cacheImage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cacheImage.js","names":[],"sources":["../../src/tasks/cacheImage.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport { createReadStream } from \"node:fs\";\n\nimport path from \"node:path\";\n\nconst cacheImageTask = idempotentTask({\n label: \"image\",\n filename: (absolutePath: string) => path.basename(absolutePath),\n runner: async (absolutePath) => {\n return createReadStream(absolutePath);\n },\n});\n\nexport const cacheImage = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await cacheImageTask(cacheRoot, absolutePath);\n } catch (error) {\n console.error(error);\n console.trace(\"Error caching image\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;AAKA,MAAM,iBAAiB,eAAe;CACpC,OAAO;CACP,WAAW,iBAAyB,KAAK,SAAS,aAAa;CAC/D,QAAQ,OAAO,iBAAiB;AAC9B,SAAO,iBAAiB,aAAa;;CAExC,CAAC;AAEF,MAAa,aAAa,OAAO,WAAmB,iBAAyB;AAC3E,KAAI;AACF,SAAO,MAAM,eAAe,WAAW,aAAa;UAC7C,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,uBAAuB,MAAM;AAC3C,QAAM"}
1
+ {"version":3,"file":"cacheImage.js","names":[],"sources":["../../src/tasks/cacheImage.ts"],"mappings":";;;;AAKA,MAAM,iBAAiB,eAAe;CACpC,OAAO;CACP,WAAW,iBAAyB,KAAK,SAAS,aAAa;CAC/D,QAAQ,OAAO,iBAAiB;AAC9B,SAAO,iBAAiB,aAAa;;CAExC,CAAC;AAEF,MAAa,aAAa,OAAO,WAAmB,iBAAyB;AAC3E,KAAI;AACF,SAAO,MAAM,eAAe,WAAW,aAAa;UAC7C,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,uBAAuB,MAAM;AAC3C,QAAM"}
@@ -1,16 +1,11 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- const require_idempotentTask = require('../idempotentTask.cjs');
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_idempotentTask = require("../idempotentTask.cjs");
3
3
  let node_child_process = require("node:child_process");
4
- node_child_process = require_rolldown_runtime.__toESM(node_child_process);
5
4
  let debug = require("debug");
6
- debug = require_rolldown_runtime.__toESM(debug);
5
+ debug = require_runtime.__toESM(debug);
7
6
  let node_path = require("node:path");
8
- node_path = require_rolldown_runtime.__toESM(node_path);
9
- let node_util = require("node:util");
10
- node_util = require_rolldown_runtime.__toESM(node_util);
11
-
12
7
  //#region src/tasks/findOrCreateCaptions.ts
13
- const execFilePromise = (0, node_util.promisify)(node_child_process.execFile);
8
+ const execFilePromise = (0, require("node:util").promisify)(node_child_process.execFile);
14
9
  const log = (0, debug.default)("ef:generateCaptions");
15
10
  const convertWhisperToEditframeFormat = (whisperData) => {
16
11
  return {
@@ -58,8 +53,8 @@ const findOrCreateCaptions = async (cacheRoot, absolutePath) => {
58
53
  throw error;
59
54
  }
60
55
  };
61
-
62
56
  //#endregion
63
57
  exports.findOrCreateCaptions = findOrCreateCaptions;
64
58
  exports.generateCaptionDataFromPath = generateCaptionDataFromPath;
59
+
65
60
  //# sourceMappingURL=findOrCreateCaptions.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"findOrCreateCaptions.cjs","names":["execFile","idempotentTask"],"sources":["../../src/tasks/findOrCreateCaptions.ts"],"sourcesContent":["import { basename } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { execFile } from \"node:child_process\";\n\nimport debug from \"debug\";\n\nimport { idempotentTask } from \"../idempotentTask.js\";\n\nconst execFilePromise = promisify(execFile);\n\nconst log = debug(\"ef:generateCaptions\");\n\ninterface WhisperWord {\n text: string;\n start: number;\n end: number;\n confidence: number;\n}\n\ninterface WhisperSegment {\n text: string;\n start: number;\n end: number;\n words: WhisperWord[];\n}\n\ninterface WhisperOutput {\n segments: WhisperSegment[];\n}\n\ninterface CaptionOutput {\n segments: Array<{\n start: number;\n end: number;\n text: string;\n }>;\n word_segments: Array<{\n text: string;\n start: number;\n end: number;\n }>;\n}\n\nconst convertWhisperToEditframeFormat = (whisperData: WhisperOutput): CaptionOutput => {\n const segments = whisperData.segments.map((segment) => ({\n start: Math.round(segment.start * 1000), // Convert to milliseconds\n end: Math.round(segment.end * 1000),\n text: segment.text.trim(),\n }));\n\n const word_segments = whisperData.segments.flatMap((segment) =>\n segment.words.map((word) => ({\n text: word.text,\n start: Math.round(word.start * 1000), // Convert to milliseconds\n end: Math.round(word.end * 1000),\n })),\n );\n\n return { segments, word_segments };\n};\n\nexport const generateCaptionDataFromPath = async (absolutePath: string) => {\n const args = [\"--language\", \"en\", \"--efficient\", \"--output_format\", \"json\", absolutePath];\n log(\"Running whisper_timestamped\", args);\n const { stdout } = await execFilePromise(\"whisper_timestamped\", args);\n\n try {\n const whisperData = JSON.parse(stdout) as WhisperOutput;\n const captionData = convertWhisperToEditframeFormat(whisperData);\n return JSON.stringify(captionData, null, 2);\n } catch (error) {\n log(`Error parsing whisper output: ${error}`);\n throw new Error(`Failed to parse whisper_timestamped output: ${error}`);\n }\n};\n\nconst generateCaptionDataTask = idempotentTask({\n label: \"captions\",\n filename: (absolutePath) => `${basename(absolutePath)}.captions.json`,\n runner: generateCaptionDataFromPath,\n});\n\nexport const findOrCreateCaptions = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateCaptionDataTask(cacheRoot, absolutePath);\n } catch (error) {\n console.trace(\"Error finding or creating captions\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;;;;;AAQA,MAAM,2CAA4BA,4BAAS;AAE3C,MAAM,yBAAY,sBAAsB;AAiCxC,MAAM,mCAAmC,gBAA8C;AAerF,QAAO;EAAE,UAdQ,YAAY,SAAS,KAAK,aAAa;GACtD,OAAO,KAAK,MAAM,QAAQ,QAAQ,IAAK;GACvC,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAK;GACnC,MAAM,QAAQ,KAAK,MAAM;GAC1B,EAAE;EAUgB,eARG,YAAY,SAAS,SAAS,YAClD,QAAQ,MAAM,KAAK,UAAU;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAK;GACpC,KAAK,KAAK,MAAM,KAAK,MAAM,IAAK;GACjC,EAAE,CACJ;EAEiC;;AAGpC,MAAa,8BAA8B,OAAO,iBAAyB;CACzE,MAAM,OAAO;EAAC;EAAc;EAAM;EAAe;EAAmB;EAAQ;EAAa;AACzF,KAAI,+BAA+B,KAAK;CACxC,MAAM,EAAE,WAAW,MAAM,gBAAgB,uBAAuB,KAAK;AAErE,KAAI;EAEF,MAAM,cAAc,gCADA,KAAK,MAAM,OAAO,CAC0B;AAChE,SAAO,KAAK,UAAU,aAAa,MAAM,EAAE;UACpC,OAAO;AACd,MAAI,iCAAiC,QAAQ;AAC7C,QAAM,IAAI,MAAM,+CAA+C,QAAQ;;;AAI3E,MAAM,0BAA0BC,sCAAe;CAC7C,OAAO;CACP,WAAW,iBAAiB,2BAAY,aAAa,CAAC;CACtD,QAAQ;CACT,CAAC;AAEF,MAAa,uBAAuB,OAAO,WAAmB,iBAAyB;AACrF,KAAI;AACF,SAAO,MAAM,wBAAwB,WAAW,aAAa;UACtD,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,QAAM"}
1
+ {"version":3,"file":"findOrCreateCaptions.cjs","names":["execFile","idempotentTask"],"sources":["../../src/tasks/findOrCreateCaptions.ts"],"mappings":";;;;;;;AAQA,MAAM,mBAAA,wBAAA,WAA4BA,mBAAAA,SAAS;AAE3C,MAAM,OAAA,GAAA,MAAA,SAAY,sBAAsB;AAiCxC,MAAM,mCAAmC,gBAA8C;AAerF,QAAO;EAAE,UAdQ,YAAY,SAAS,KAAK,aAAa;GACtD,OAAO,KAAK,MAAM,QAAQ,QAAQ,IAAK;GACvC,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAK;GACnC,MAAM,QAAQ,KAAK,MAAM;GAC1B,EAAE;EAUgB,eARG,YAAY,SAAS,SAAS,YAClD,QAAQ,MAAM,KAAK,UAAU;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAK;GACpC,KAAK,KAAK,MAAM,KAAK,MAAM,IAAK;GACjC,EAAE,CACJ;EAEiC;;AAGpC,MAAa,8BAA8B,OAAO,iBAAyB;CACzE,MAAM,OAAO;EAAC;EAAc;EAAM;EAAe;EAAmB;EAAQ;EAAa;AACzF,KAAI,+BAA+B,KAAK;CACxC,MAAM,EAAE,WAAW,MAAM,gBAAgB,uBAAuB,KAAK;AAErE,KAAI;EAEF,MAAM,cAAc,gCADA,KAAK,MAAM,OAAO,CAC0B;AAChE,SAAO,KAAK,UAAU,aAAa,MAAM,EAAE;UACpC,OAAO;AACd,MAAI,iCAAiC,QAAQ;AAC7C,QAAM,IAAI,MAAM,+CAA+C,QAAQ;;;AAI3E,MAAM,0BAA0BC,uBAAAA,eAAe;CAC7C,OAAO;CACP,WAAW,iBAAiB,IAAA,GAAA,UAAA,UAAY,aAAa,CAAC;CACtD,QAAQ;CACT,CAAC;AAEF,MAAa,uBAAuB,OAAO,WAAmB,iBAAyB;AACrF,KAAI;AACF,SAAO,MAAM,wBAAwB,WAAW,aAAa;UACtD,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,QAAM"}
@@ -3,7 +3,6 @@ import { execFile } from "node:child_process";
3
3
  import debug from "debug";
4
4
  import { basename } from "node:path";
5
5
  import { promisify } from "node:util";
6
-
7
6
  //#region src/tasks/findOrCreateCaptions.ts
8
7
  const execFilePromise = promisify(execFile);
9
8
  const log = debug("ef:generateCaptions");
@@ -53,7 +52,7 @@ const findOrCreateCaptions = async (cacheRoot, absolutePath) => {
53
52
  throw error;
54
53
  }
55
54
  };
56
-
57
55
  //#endregion
58
56
  export { findOrCreateCaptions, generateCaptionDataFromPath };
57
+
59
58
  //# sourceMappingURL=findOrCreateCaptions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"findOrCreateCaptions.js","names":[],"sources":["../../src/tasks/findOrCreateCaptions.ts"],"sourcesContent":["import { basename } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { execFile } from \"node:child_process\";\n\nimport debug from \"debug\";\n\nimport { idempotentTask } from \"../idempotentTask.js\";\n\nconst execFilePromise = promisify(execFile);\n\nconst log = debug(\"ef:generateCaptions\");\n\ninterface WhisperWord {\n text: string;\n start: number;\n end: number;\n confidence: number;\n}\n\ninterface WhisperSegment {\n text: string;\n start: number;\n end: number;\n words: WhisperWord[];\n}\n\ninterface WhisperOutput {\n segments: WhisperSegment[];\n}\n\ninterface CaptionOutput {\n segments: Array<{\n start: number;\n end: number;\n text: string;\n }>;\n word_segments: Array<{\n text: string;\n start: number;\n end: number;\n }>;\n}\n\nconst convertWhisperToEditframeFormat = (whisperData: WhisperOutput): CaptionOutput => {\n const segments = whisperData.segments.map((segment) => ({\n start: Math.round(segment.start * 1000), // Convert to milliseconds\n end: Math.round(segment.end * 1000),\n text: segment.text.trim(),\n }));\n\n const word_segments = whisperData.segments.flatMap((segment) =>\n segment.words.map((word) => ({\n text: word.text,\n start: Math.round(word.start * 1000), // Convert to milliseconds\n end: Math.round(word.end * 1000),\n })),\n );\n\n return { segments, word_segments };\n};\n\nexport const generateCaptionDataFromPath = async (absolutePath: string) => {\n const args = [\"--language\", \"en\", \"--efficient\", \"--output_format\", \"json\", absolutePath];\n log(\"Running whisper_timestamped\", args);\n const { stdout } = await execFilePromise(\"whisper_timestamped\", args);\n\n try {\n const whisperData = JSON.parse(stdout) as WhisperOutput;\n const captionData = convertWhisperToEditframeFormat(whisperData);\n return JSON.stringify(captionData, null, 2);\n } catch (error) {\n log(`Error parsing whisper output: ${error}`);\n throw new Error(`Failed to parse whisper_timestamped output: ${error}`);\n }\n};\n\nconst generateCaptionDataTask = idempotentTask({\n label: \"captions\",\n filename: (absolutePath) => `${basename(absolutePath)}.captions.json`,\n runner: generateCaptionDataFromPath,\n});\n\nexport const findOrCreateCaptions = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateCaptionDataTask(cacheRoot, absolutePath);\n } catch (error) {\n console.trace(\"Error finding or creating captions\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;AAQA,MAAM,kBAAkB,UAAU,SAAS;AAE3C,MAAM,MAAM,MAAM,sBAAsB;AAiCxC,MAAM,mCAAmC,gBAA8C;AAerF,QAAO;EAAE,UAdQ,YAAY,SAAS,KAAK,aAAa;GACtD,OAAO,KAAK,MAAM,QAAQ,QAAQ,IAAK;GACvC,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAK;GACnC,MAAM,QAAQ,KAAK,MAAM;GAC1B,EAAE;EAUgB,eARG,YAAY,SAAS,SAAS,YAClD,QAAQ,MAAM,KAAK,UAAU;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAK;GACpC,KAAK,KAAK,MAAM,KAAK,MAAM,IAAK;GACjC,EAAE,CACJ;EAEiC;;AAGpC,MAAa,8BAA8B,OAAO,iBAAyB;CACzE,MAAM,OAAO;EAAC;EAAc;EAAM;EAAe;EAAmB;EAAQ;EAAa;AACzF,KAAI,+BAA+B,KAAK;CACxC,MAAM,EAAE,WAAW,MAAM,gBAAgB,uBAAuB,KAAK;AAErE,KAAI;EAEF,MAAM,cAAc,gCADA,KAAK,MAAM,OAAO,CAC0B;AAChE,SAAO,KAAK,UAAU,aAAa,MAAM,EAAE;UACpC,OAAO;AACd,MAAI,iCAAiC,QAAQ;AAC7C,QAAM,IAAI,MAAM,+CAA+C,QAAQ;;;AAI3E,MAAM,0BAA0B,eAAe;CAC7C,OAAO;CACP,WAAW,iBAAiB,GAAG,SAAS,aAAa,CAAC;CACtD,QAAQ;CACT,CAAC;AAEF,MAAa,uBAAuB,OAAO,WAAmB,iBAAyB;AACrF,KAAI;AACF,SAAO,MAAM,wBAAwB,WAAW,aAAa;UACtD,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,QAAM"}
1
+ {"version":3,"file":"findOrCreateCaptions.js","names":[],"sources":["../../src/tasks/findOrCreateCaptions.ts"],"mappings":";;;;;;AAQA,MAAM,kBAAkB,UAAU,SAAS;AAE3C,MAAM,MAAM,MAAM,sBAAsB;AAiCxC,MAAM,mCAAmC,gBAA8C;AAerF,QAAO;EAAE,UAdQ,YAAY,SAAS,KAAK,aAAa;GACtD,OAAO,KAAK,MAAM,QAAQ,QAAQ,IAAK;GACvC,KAAK,KAAK,MAAM,QAAQ,MAAM,IAAK;GACnC,MAAM,QAAQ,KAAK,MAAM;GAC1B,EAAE;EAUgB,eARG,YAAY,SAAS,SAAS,YAClD,QAAQ,MAAM,KAAK,UAAU;GAC3B,MAAM,KAAK;GACX,OAAO,KAAK,MAAM,KAAK,QAAQ,IAAK;GACpC,KAAK,KAAK,MAAM,KAAK,MAAM,IAAK;GACjC,EAAE,CACJ;EAEiC;;AAGpC,MAAa,8BAA8B,OAAO,iBAAyB;CACzE,MAAM,OAAO;EAAC;EAAc;EAAM;EAAe;EAAmB;EAAQ;EAAa;AACzF,KAAI,+BAA+B,KAAK;CACxC,MAAM,EAAE,WAAW,MAAM,gBAAgB,uBAAuB,KAAK;AAErE,KAAI;EAEF,MAAM,cAAc,gCADA,KAAK,MAAM,OAAO,CAC0B;AAChE,SAAO,KAAK,UAAU,aAAa,MAAM,EAAE;UACpC,OAAO;AACd,MAAI,iCAAiC,QAAQ;AAC7C,QAAM,IAAI,MAAM,+CAA+C,QAAQ;;;AAI3E,MAAM,0BAA0B,eAAe;CAC7C,OAAO;CACP,WAAW,iBAAiB,GAAG,SAAS,aAAa,CAAC;CACtD,QAAQ;CACT,CAAC;AAEF,MAAa,uBAAuB,OAAO,WAAmB,iBAAyB;AACrF,KAAI;AACF,SAAO,MAAM,wBAAwB,WAAW,aAAa;UACtD,OAAO;AACd,UAAQ,MAAM,sCAAsC,MAAM;AAC1D,QAAM"}
@@ -1,14 +1,11 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- const require_Probe = require('../Probe.cjs');
3
- const require_generateFragmentIndex = require('../generateFragmentIndex.cjs');
4
- const require_idempotentTask = require('../idempotentTask.cjs');
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_Probe = require("../Probe.cjs");
3
+ const require_generateFragmentIndex = require("../generateFragmentIndex.cjs");
4
+ const require_idempotentTask = require("../idempotentTask.cjs");
5
5
  let debug = require("debug");
6
- debug = require_rolldown_runtime.__toESM(debug);
6
+ debug = require_runtime.__toESM(debug);
7
7
  let node_stream = require("node:stream");
8
- node_stream = require_rolldown_runtime.__toESM(node_stream);
9
8
  let node_path = require("node:path");
10
- node_path = require_rolldown_runtime.__toESM(node_path);
11
-
12
9
  //#region src/tasks/generateScrubTrack.ts
13
10
  const log = (0, debug.default)("ef:generateScrubTrack");
14
11
  const generateScrubTrackFromPath = async (absolutePath) => {
@@ -90,8 +87,8 @@ const generateScrubTrack = async (cacheRoot, absolutePath) => {
90
87
  throw error;
91
88
  }
92
89
  };
93
-
94
90
  //#endregion
95
91
  exports.generateScrubTrack = generateScrubTrack;
96
92
  exports.generateScrubTrackFromPath = generateScrubTrackFromPath;
93
+
97
94
  //# sourceMappingURL=generateScrubTrack.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateScrubTrack.cjs","names":["Probe","PassThrough","generateFragmentIndex","idempotentTask","progressTimeout: NodeJS.Timeout | null"],"sources":["../../src/tasks/generateScrubTrack.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { PassThrough } from \"node:stream\";\nimport { Probe } from \"../Probe.js\";\nimport { generateFragmentIndex } from \"../generateFragmentIndex.js\";\n\nconst log = debug(\"ef:generateScrubTrack\");\n\nexport const generateScrubTrackFromPath = async (absolutePath: string) => {\n log(`Generating scrub track for ${absolutePath}`);\n\n const probe = await Probe.probePath(absolutePath);\n\n // Check if video stream exists\n if (probe.videoStreams.length === 0) {\n throw new Error(\"No video stream found for scrub track generation\");\n }\n\n // Get the scrub track stream from FFmpeg (low-res transcoded video)\n const scrubStream = probe.createScrubTrackReadstream();\n\n const startTimeOffsetMs = probe.startTimeOffsetMs;\n\n // Create a PassThrough to tee the stream\n const outputStream = new PassThrough();\n const indexStream = new PassThrough();\n\n // Pipe data but DON'T end outputStream automatically - we'll control this\n scrubStream.pipe(outputStream, { end: false });\n scrubStream.pipe(indexStream);\n\n // Track when the source stream ends (but don't end output yet)\n let sourceStreamEnded = false;\n scrubStream.on(\"end\", () => {\n sourceStreamEnded = true;\n });\n\n scrubStream.on(\"error\", (error) => {\n outputStream.destroy(error);\n indexStream.destroy(error);\n });\n\n // Generate fragment index from the scrub track stream\n // Use a special track ID to identify scrub track (e.g., -1 or \"scrub\")\n // We'll use a negative track ID to distinguish from regular tracks\n const scrubTrackId = -1;\n const trackIdMapping = { 1: scrubTrackId }; // Single track 1 -> scrub track ID\n\n const fragmentIndexPromise = generateFragmentIndex(\n indexStream,\n startTimeOffsetMs,\n trackIdMapping,\n );\n\n // End outputStream only after BOTH source ends AND fragment index completes\n fragmentIndexPromise\n .then(() => {\n if (sourceStreamEnded) {\n outputStream.end();\n } else {\n // If fragment index completes first, wait for stream to end\n scrubStream.once(\"end\", () => {\n outputStream.end();\n });\n }\n })\n .catch((error) => {\n outputStream.destroy(error);\n });\n\n // Return both the stream and the index\n return {\n stream: outputStream,\n fragmentIndex: fragmentIndexPromise,\n };\n};\n\nexport const generateScrubTrackTask = idempotentTask({\n label: \"scrub-track\",\n filename: (absolutePath: string) => `${basename(absolutePath)}.scrub-track.mp4`,\n runner: async (absolutePath: string) => {\n const probe = await Probe.probePath(absolutePath);\n\n if (probe.videoStreams.length === 0) {\n throw new Error(\"No video stream found for scrub track generation\");\n }\n\n // Get the scrub track stream from FFmpeg\n const scrubStream = probe.createScrubTrackReadstream();\n\n // Wrap in PassThrough with timeout handling to ensure stream completes\n const finalStream = new PassThrough();\n\n // Monitor progress and extend timeout based on actual work\n let progressTimeout: NodeJS.Timeout | null = null;\n\n const resetProgressTimeout = () => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n\n progressTimeout = setTimeout(() => {\n if (!finalStream.destroyed) {\n console.warn(`Progress timeout triggered for scrub track - no activity for 30 seconds`);\n finalStream.destroy(new Error(\"Scrub track generation timeout\"));\n }\n }, 30000); // 30 second sliding timeout (longer for transcoding)\n };\n\n // Start the initial timeout\n resetProgressTimeout();\n\n // Monitor data flow to detect active work\n scrubStream.on(\"data\", () => {\n resetProgressTimeout(); // Reset timeout when we see data\n });\n\n scrubStream.on(\"end\", () => {\n resetProgressTimeout(); // Reset timeout when stream ends\n finalStream.end();\n });\n\n scrubStream.on(\"error\", (error) => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n finalStream.destroy(error);\n });\n\n // Pipe data through\n scrubStream.pipe(finalStream, { end: false });\n\n // Clean up timeout when stream ends\n finalStream.on(\"end\", () => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n });\n\n return finalStream;\n },\n});\n\nexport const generateScrubTrack = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateScrubTrackTask(cacheRoot, absolutePath);\n } catch (error) {\n console.error(error);\n console.trace(\"Error generating scrub track\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;;;;;AAOA,MAAM,yBAAY,wBAAwB;AAE1C,MAAa,6BAA6B,OAAO,iBAAyB;AACxE,KAAI,8BAA8B,eAAe;CAEjD,MAAM,QAAQ,MAAMA,oBAAM,UAAU,aAAa;AAGjD,KAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;CAIrE,MAAM,cAAc,MAAM,4BAA4B;CAEtD,MAAM,oBAAoB,MAAM;CAGhC,MAAM,eAAe,IAAIC,yBAAa;CACtC,MAAM,cAAc,IAAIA,yBAAa;AAGrC,aAAY,KAAK,cAAc,EAAE,KAAK,OAAO,CAAC;AAC9C,aAAY,KAAK,YAAY;CAG7B,IAAI,oBAAoB;AACxB,aAAY,GAAG,aAAa;AAC1B,sBAAoB;GACpB;AAEF,aAAY,GAAG,UAAU,UAAU;AACjC,eAAa,QAAQ,MAAM;AAC3B,cAAY,QAAQ,MAAM;GAC1B;CAKF,MAAM,eAAe;CAGrB,MAAM,uBAAuBC,oDAC3B,aACA,mBAJqB,EAAE,GAAG,cAAc,CAMzC;AAGD,sBACG,WAAW;AACV,MAAI,kBACF,cAAa,KAAK;MAGlB,aAAY,KAAK,aAAa;AAC5B,gBAAa,KAAK;IAClB;GAEJ,CACD,OAAO,UAAU;AAChB,eAAa,QAAQ,MAAM;GAC3B;AAGJ,QAAO;EACL,QAAQ;EACR,eAAe;EAChB;;AAGH,MAAa,yBAAyBC,sCAAe;CACnD,OAAO;CACP,WAAW,iBAAyB,2BAAY,aAAa,CAAC;CAC9D,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAMH,oBAAM,UAAU,aAAa;AAEjD,MAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;EAIrE,MAAM,cAAc,MAAM,4BAA4B;EAGtD,MAAM,cAAc,IAAIC,yBAAa;EAGrC,IAAIG,kBAAyC;EAE7C,MAAM,6BAA6B;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAG/B,qBAAkB,iBAAiB;AACjC,QAAI,CAAC,YAAY,WAAW;AAC1B,aAAQ,KAAK,0EAA0E;AACvF,iBAAY,wBAAQ,IAAI,MAAM,iCAAiC,CAAC;;MAEjE,IAAM;;AAIX,wBAAsB;AAGtB,cAAY,GAAG,cAAc;AAC3B,yBAAsB;IACtB;AAEF,cAAY,GAAG,aAAa;AAC1B,yBAAsB;AACtB,eAAY,KAAK;IACjB;AAEF,cAAY,GAAG,UAAU,UAAU;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAE/B,eAAY,QAAQ,MAAM;IAC1B;AAGF,cAAY,KAAK,aAAa,EAAE,KAAK,OAAO,CAAC;AAG7C,cAAY,GAAG,aAAa;AAC1B,OAAI,gBACF,cAAa,gBAAgB;IAE/B;AAEF,SAAO;;CAEV,CAAC;AAEF,MAAa,qBAAqB,OAAO,WAAmB,iBAAyB;AACnF,KAAI;AACF,SAAO,MAAM,uBAAuB,WAAW,aAAa;UACrD,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,gCAAgC,MAAM;AACpD,QAAM"}
1
+ {"version":3,"file":"generateScrubTrack.cjs","names":["Probe","PassThrough","generateFragmentIndex","idempotentTask"],"sources":["../../src/tasks/generateScrubTrack.ts"],"mappings":";;;;;;;;;AAOA,MAAM,OAAA,GAAA,MAAA,SAAY,wBAAwB;AAE1C,MAAa,6BAA6B,OAAO,iBAAyB;AACxE,KAAI,8BAA8B,eAAe;CAEjD,MAAM,QAAQ,MAAMA,cAAAA,MAAM,UAAU,aAAa;AAGjD,KAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;CAIrE,MAAM,cAAc,MAAM,4BAA4B;CAEtD,MAAM,oBAAoB,MAAM;CAGhC,MAAM,eAAe,IAAIC,YAAAA,aAAa;CACtC,MAAM,cAAc,IAAIA,YAAAA,aAAa;AAGrC,aAAY,KAAK,cAAc,EAAE,KAAK,OAAO,CAAC;AAC9C,aAAY,KAAK,YAAY;CAG7B,IAAI,oBAAoB;AACxB,aAAY,GAAG,aAAa;AAC1B,sBAAoB;GACpB;AAEF,aAAY,GAAG,UAAU,UAAU;AACjC,eAAa,QAAQ,MAAM;AAC3B,cAAY,QAAQ,MAAM;GAC1B;CAKF,MAAM,eAAe;CAGrB,MAAM,uBAAuBC,8BAAAA,sBAC3B,aACA,mBAJqB,EAAE,GAAG,cAAc,CAMzC;AAGD,sBACG,WAAW;AACV,MAAI,kBACF,cAAa,KAAK;MAGlB,aAAY,KAAK,aAAa;AAC5B,gBAAa,KAAK;IAClB;GAEJ,CACD,OAAO,UAAU;AAChB,eAAa,QAAQ,MAAM;GAC3B;AAGJ,QAAO;EACL,QAAQ;EACR,eAAe;EAChB;;AAGH,MAAa,yBAAyBC,uBAAAA,eAAe;CACnD,OAAO;CACP,WAAW,iBAAyB,IAAA,GAAA,UAAA,UAAY,aAAa,CAAC;CAC9D,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAMH,cAAAA,MAAM,UAAU,aAAa;AAEjD,MAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;EAIrE,MAAM,cAAc,MAAM,4BAA4B;EAGtD,MAAM,cAAc,IAAIC,YAAAA,aAAa;EAGrC,IAAI,kBAAyC;EAE7C,MAAM,6BAA6B;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAG/B,qBAAkB,iBAAiB;AACjC,QAAI,CAAC,YAAY,WAAW;AAC1B,aAAQ,KAAK,0EAA0E;AACvF,iBAAY,wBAAQ,IAAI,MAAM,iCAAiC,CAAC;;MAEjE,IAAM;;AAIX,wBAAsB;AAGtB,cAAY,GAAG,cAAc;AAC3B,yBAAsB;IACtB;AAEF,cAAY,GAAG,aAAa;AAC1B,yBAAsB;AACtB,eAAY,KAAK;IACjB;AAEF,cAAY,GAAG,UAAU,UAAU;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAE/B,eAAY,QAAQ,MAAM;IAC1B;AAGF,cAAY,KAAK,aAAa,EAAE,KAAK,OAAO,CAAC;AAG7C,cAAY,GAAG,aAAa;AAC1B,OAAI,gBACF,cAAa,gBAAgB;IAE/B;AAEF,SAAO;;CAEV,CAAC;AAEF,MAAa,qBAAqB,OAAO,WAAmB,iBAAyB;AACnF,KAAI;AACF,SAAO,MAAM,uBAAuB,WAAW,aAAa;UACrD,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,gCAAgC,MAAM;AACpD,QAAM"}
@@ -4,7 +4,6 @@ import { idempotentTask } from "../idempotentTask.js";
4
4
  import debug from "debug";
5
5
  import { PassThrough } from "node:stream";
6
6
  import { basename } from "node:path";
7
-
8
7
  //#region src/tasks/generateScrubTrack.ts
9
8
  const log = debug("ef:generateScrubTrack");
10
9
  const generateScrubTrackFromPath = async (absolutePath) => {
@@ -86,7 +85,7 @@ const generateScrubTrack = async (cacheRoot, absolutePath) => {
86
85
  throw error;
87
86
  }
88
87
  };
89
-
90
88
  //#endregion
91
89
  export { generateScrubTrack, generateScrubTrackFromPath };
90
+
92
91
  //# sourceMappingURL=generateScrubTrack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateScrubTrack.js","names":["progressTimeout: NodeJS.Timeout | null"],"sources":["../../src/tasks/generateScrubTrack.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { PassThrough } from \"node:stream\";\nimport { Probe } from \"../Probe.js\";\nimport { generateFragmentIndex } from \"../generateFragmentIndex.js\";\n\nconst log = debug(\"ef:generateScrubTrack\");\n\nexport const generateScrubTrackFromPath = async (absolutePath: string) => {\n log(`Generating scrub track for ${absolutePath}`);\n\n const probe = await Probe.probePath(absolutePath);\n\n // Check if video stream exists\n if (probe.videoStreams.length === 0) {\n throw new Error(\"No video stream found for scrub track generation\");\n }\n\n // Get the scrub track stream from FFmpeg (low-res transcoded video)\n const scrubStream = probe.createScrubTrackReadstream();\n\n const startTimeOffsetMs = probe.startTimeOffsetMs;\n\n // Create a PassThrough to tee the stream\n const outputStream = new PassThrough();\n const indexStream = new PassThrough();\n\n // Pipe data but DON'T end outputStream automatically - we'll control this\n scrubStream.pipe(outputStream, { end: false });\n scrubStream.pipe(indexStream);\n\n // Track when the source stream ends (but don't end output yet)\n let sourceStreamEnded = false;\n scrubStream.on(\"end\", () => {\n sourceStreamEnded = true;\n });\n\n scrubStream.on(\"error\", (error) => {\n outputStream.destroy(error);\n indexStream.destroy(error);\n });\n\n // Generate fragment index from the scrub track stream\n // Use a special track ID to identify scrub track (e.g., -1 or \"scrub\")\n // We'll use a negative track ID to distinguish from regular tracks\n const scrubTrackId = -1;\n const trackIdMapping = { 1: scrubTrackId }; // Single track 1 -> scrub track ID\n\n const fragmentIndexPromise = generateFragmentIndex(\n indexStream,\n startTimeOffsetMs,\n trackIdMapping,\n );\n\n // End outputStream only after BOTH source ends AND fragment index completes\n fragmentIndexPromise\n .then(() => {\n if (sourceStreamEnded) {\n outputStream.end();\n } else {\n // If fragment index completes first, wait for stream to end\n scrubStream.once(\"end\", () => {\n outputStream.end();\n });\n }\n })\n .catch((error) => {\n outputStream.destroy(error);\n });\n\n // Return both the stream and the index\n return {\n stream: outputStream,\n fragmentIndex: fragmentIndexPromise,\n };\n};\n\nexport const generateScrubTrackTask = idempotentTask({\n label: \"scrub-track\",\n filename: (absolutePath: string) => `${basename(absolutePath)}.scrub-track.mp4`,\n runner: async (absolutePath: string) => {\n const probe = await Probe.probePath(absolutePath);\n\n if (probe.videoStreams.length === 0) {\n throw new Error(\"No video stream found for scrub track generation\");\n }\n\n // Get the scrub track stream from FFmpeg\n const scrubStream = probe.createScrubTrackReadstream();\n\n // Wrap in PassThrough with timeout handling to ensure stream completes\n const finalStream = new PassThrough();\n\n // Monitor progress and extend timeout based on actual work\n let progressTimeout: NodeJS.Timeout | null = null;\n\n const resetProgressTimeout = () => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n\n progressTimeout = setTimeout(() => {\n if (!finalStream.destroyed) {\n console.warn(`Progress timeout triggered for scrub track - no activity for 30 seconds`);\n finalStream.destroy(new Error(\"Scrub track generation timeout\"));\n }\n }, 30000); // 30 second sliding timeout (longer for transcoding)\n };\n\n // Start the initial timeout\n resetProgressTimeout();\n\n // Monitor data flow to detect active work\n scrubStream.on(\"data\", () => {\n resetProgressTimeout(); // Reset timeout when we see data\n });\n\n scrubStream.on(\"end\", () => {\n resetProgressTimeout(); // Reset timeout when stream ends\n finalStream.end();\n });\n\n scrubStream.on(\"error\", (error) => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n finalStream.destroy(error);\n });\n\n // Pipe data through\n scrubStream.pipe(finalStream, { end: false });\n\n // Clean up timeout when stream ends\n finalStream.on(\"end\", () => {\n if (progressTimeout) {\n clearTimeout(progressTimeout);\n }\n });\n\n return finalStream;\n },\n});\n\nexport const generateScrubTrack = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateScrubTrackTask(cacheRoot, absolutePath);\n } catch (error) {\n console.error(error);\n console.trace(\"Error generating scrub track\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;AAOA,MAAM,MAAM,MAAM,wBAAwB;AAE1C,MAAa,6BAA6B,OAAO,iBAAyB;AACxE,KAAI,8BAA8B,eAAe;CAEjD,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;AAGjD,KAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;CAIrE,MAAM,cAAc,MAAM,4BAA4B;CAEtD,MAAM,oBAAoB,MAAM;CAGhC,MAAM,eAAe,IAAI,aAAa;CACtC,MAAM,cAAc,IAAI,aAAa;AAGrC,aAAY,KAAK,cAAc,EAAE,KAAK,OAAO,CAAC;AAC9C,aAAY,KAAK,YAAY;CAG7B,IAAI,oBAAoB;AACxB,aAAY,GAAG,aAAa;AAC1B,sBAAoB;GACpB;AAEF,aAAY,GAAG,UAAU,UAAU;AACjC,eAAa,QAAQ,MAAM;AAC3B,cAAY,QAAQ,MAAM;GAC1B;CAKF,MAAM,eAAe;CAGrB,MAAM,uBAAuB,sBAC3B,aACA,mBAJqB,EAAE,GAAG,cAAc,CAMzC;AAGD,sBACG,WAAW;AACV,MAAI,kBACF,cAAa,KAAK;MAGlB,aAAY,KAAK,aAAa;AAC5B,gBAAa,KAAK;IAClB;GAEJ,CACD,OAAO,UAAU;AAChB,eAAa,QAAQ,MAAM;GAC3B;AAGJ,QAAO;EACL,QAAQ;EACR,eAAe;EAChB;;AAGH,MAAa,yBAAyB,eAAe;CACnD,OAAO;CACP,WAAW,iBAAyB,GAAG,SAAS,aAAa,CAAC;CAC9D,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;AAEjD,MAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;EAIrE,MAAM,cAAc,MAAM,4BAA4B;EAGtD,MAAM,cAAc,IAAI,aAAa;EAGrC,IAAIA,kBAAyC;EAE7C,MAAM,6BAA6B;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAG/B,qBAAkB,iBAAiB;AACjC,QAAI,CAAC,YAAY,WAAW;AAC1B,aAAQ,KAAK,0EAA0E;AACvF,iBAAY,wBAAQ,IAAI,MAAM,iCAAiC,CAAC;;MAEjE,IAAM;;AAIX,wBAAsB;AAGtB,cAAY,GAAG,cAAc;AAC3B,yBAAsB;IACtB;AAEF,cAAY,GAAG,aAAa;AAC1B,yBAAsB;AACtB,eAAY,KAAK;IACjB;AAEF,cAAY,GAAG,UAAU,UAAU;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAE/B,eAAY,QAAQ,MAAM;IAC1B;AAGF,cAAY,KAAK,aAAa,EAAE,KAAK,OAAO,CAAC;AAG7C,cAAY,GAAG,aAAa;AAC1B,OAAI,gBACF,cAAa,gBAAgB;IAE/B;AAEF,SAAO;;CAEV,CAAC;AAEF,MAAa,qBAAqB,OAAO,WAAmB,iBAAyB;AACnF,KAAI;AACF,SAAO,MAAM,uBAAuB,WAAW,aAAa;UACrD,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,gCAAgC,MAAM;AACpD,QAAM"}
1
+ {"version":3,"file":"generateScrubTrack.js","names":[],"sources":["../../src/tasks/generateScrubTrack.ts"],"mappings":";;;;;;;AAOA,MAAM,MAAM,MAAM,wBAAwB;AAE1C,MAAa,6BAA6B,OAAO,iBAAyB;AACxE,KAAI,8BAA8B,eAAe;CAEjD,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;AAGjD,KAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;CAIrE,MAAM,cAAc,MAAM,4BAA4B;CAEtD,MAAM,oBAAoB,MAAM;CAGhC,MAAM,eAAe,IAAI,aAAa;CACtC,MAAM,cAAc,IAAI,aAAa;AAGrC,aAAY,KAAK,cAAc,EAAE,KAAK,OAAO,CAAC;AAC9C,aAAY,KAAK,YAAY;CAG7B,IAAI,oBAAoB;AACxB,aAAY,GAAG,aAAa;AAC1B,sBAAoB;GACpB;AAEF,aAAY,GAAG,UAAU,UAAU;AACjC,eAAa,QAAQ,MAAM;AAC3B,cAAY,QAAQ,MAAM;GAC1B;CAKF,MAAM,eAAe;CAGrB,MAAM,uBAAuB,sBAC3B,aACA,mBAJqB,EAAE,GAAG,cAAc,CAMzC;AAGD,sBACG,WAAW;AACV,MAAI,kBACF,cAAa,KAAK;MAGlB,aAAY,KAAK,aAAa;AAC5B,gBAAa,KAAK;IAClB;GAEJ,CACD,OAAO,UAAU;AAChB,eAAa,QAAQ,MAAM;GAC3B;AAGJ,QAAO;EACL,QAAQ;EACR,eAAe;EAChB;;AAGH,MAAa,yBAAyB,eAAe;CACnD,OAAO;CACP,WAAW,iBAAyB,GAAG,SAAS,aAAa,CAAC;CAC9D,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;AAEjD,MAAI,MAAM,aAAa,WAAW,EAChC,OAAM,IAAI,MAAM,mDAAmD;EAIrE,MAAM,cAAc,MAAM,4BAA4B;EAGtD,MAAM,cAAc,IAAI,aAAa;EAGrC,IAAI,kBAAyC;EAE7C,MAAM,6BAA6B;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAG/B,qBAAkB,iBAAiB;AACjC,QAAI,CAAC,YAAY,WAAW;AAC1B,aAAQ,KAAK,0EAA0E;AACvF,iBAAY,wBAAQ,IAAI,MAAM,iCAAiC,CAAC;;MAEjE,IAAM;;AAIX,wBAAsB;AAGtB,cAAY,GAAG,cAAc;AAC3B,yBAAsB;IACtB;AAEF,cAAY,GAAG,aAAa;AAC1B,yBAAsB;AACtB,eAAY,KAAK;IACjB;AAEF,cAAY,GAAG,UAAU,UAAU;AACjC,OAAI,gBACF,cAAa,gBAAgB;AAE/B,eAAY,QAAQ,MAAM;IAC1B;AAGF,cAAY,KAAK,aAAa,EAAE,KAAK,OAAO,CAAC;AAG7C,cAAY,GAAG,aAAa;AAC1B,OAAI,gBACF,cAAa,gBAAgB;IAE/B;AAEF,SAAO;;CAEV,CAAC;AAEF,MAAa,qBAAqB,OAAO,WAAmB,iBAAyB;AACnF,KAAI;AACF,SAAO,MAAM,uBAAuB,WAAW,aAAa;UACrD,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,gCAAgC,MAAM;AACpD,QAAM"}
@@ -1,19 +1,31 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- const require_idempotentTask = require('../idempotentTask.cjs');
3
- const require_generateSingleTrack = require('../generateSingleTrack.cjs');
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_Probe = require("../Probe.cjs");
3
+ const require_idempotentTask = require("../idempotentTask.cjs");
4
+ const require_generateWebmSegmentIndex = require("../generateWebmSegmentIndex.cjs");
5
+ const require_generateSingleTrack = require("../generateSingleTrack.cjs");
4
6
  let debug = require("debug");
5
- debug = require_rolldown_runtime.__toESM(debug);
7
+ debug = require_runtime.__toESM(debug);
8
+ let node_stream = require("node:stream");
9
+ let node_fs_promises = require("node:fs/promises");
6
10
  let node_path = require("node:path");
7
- node_path = require_rolldown_runtime.__toESM(node_path);
8
-
9
11
  //#region src/tasks/generateTrack.ts
10
12
  const generateTrackFromPath = async (absolutePath, trackId) => {
11
- (0, debug.default)("ef:generateTrackFragment")(`Generating track ${trackId} for ${absolutePath}`);
13
+ const log = (0, debug.default)("ef:generateTrackFragment");
14
+ log(`Generating track ${trackId} for ${absolutePath}`);
15
+ if ((await require_Probe.Probe.probePath(absolutePath)).hasAlphaVideo) {
16
+ log(`VP9 alpha WebM: copying source with Segment size + SeekHead patched`);
17
+ const buf = await (0, node_fs_promises.readFile)(absolutePath);
18
+ require_generateWebmSegmentIndex.patchWebmForSegmentedServing(buf);
19
+ return node_stream.Readable.from(buf);
20
+ }
12
21
  return (await require_generateSingleTrack.generateSingleTrackFromPath(absolutePath, trackId)).stream;
13
22
  };
14
23
  const generateTrackTask = require_idempotentTask.idempotentTask({
15
24
  label: "track",
16
- filename: (absolutePath, trackId) => `${(0, node_path.basename)(absolutePath)}.track-${trackId}.mp4`,
25
+ filename: (absolutePath, _trackId) => {
26
+ const ext = absolutePath.endsWith(".webm") ? "webm" : "mp4";
27
+ return `${(0, node_path.basename)(absolutePath)}.track-1.${ext}`;
28
+ },
17
29
  runner: generateTrackFromPath
18
30
  });
19
31
  const generateTrack = async (cacheRoot, absolutePath, url) => {
@@ -27,8 +39,8 @@ const generateTrack = async (cacheRoot, absolutePath, url) => {
27
39
  throw error;
28
40
  }
29
41
  };
30
-
31
42
  //#endregion
32
43
  exports.generateTrack = generateTrack;
33
44
  exports.generateTrackFromPath = generateTrackFromPath;
45
+
34
46
  //# sourceMappingURL=generateTrack.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateTrack.cjs","names":["generateSingleTrackFromPath","idempotentTask"],"sources":["../../src/tasks/generateTrack.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { generateSingleTrackFromPath } from \"../generateSingleTrack.js\";\n\nexport const generateTrackFromPath = async (absolutePath: string, trackId: number) => {\n const log = debug(\"ef:generateTrackFragment\");\n log(`Generating track ${trackId} for ${absolutePath}`);\n\n // Use the single-track implementation\n const result = await generateSingleTrackFromPath(absolutePath, trackId);\n\n // Return just the stream for compatibility with existing API\n return result.stream;\n};\n\nexport const generateTrackTask = idempotentTask({\n label: \"track\",\n filename: (absolutePath: string, trackId: number) =>\n `${basename(absolutePath)}.track-${trackId}.mp4`,\n runner: generateTrackFromPath,\n});\n\nexport const generateTrack = async (cacheRoot: string, absolutePath: string, url: string) => {\n try {\n const trackId = new URL(`http://localhost${url}`).searchParams.get(\"trackId\");\n if (trackId === null) {\n throw new Error(\n \"No trackId provided. It must be specified in the query string: ?trackId=1 (for video) or ?trackId=2 (for audio)\",\n );\n }\n return await generateTrackTask(cacheRoot, absolutePath, Number(trackId));\n } catch (error) {\n console.error(error);\n console.trace(\"Error generating track\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;;AAKA,MAAa,wBAAwB,OAAO,cAAsB,YAAoB;AAEpF,oBADkB,2BAA2B,CACzC,oBAAoB,QAAQ,OAAO,eAAe;AAMtD,SAHe,MAAMA,wDAA4B,cAAc,QAAQ,EAGzD;;AAGhB,MAAa,oBAAoBC,sCAAe;CAC9C,OAAO;CACP,WAAW,cAAsB,YAC/B,2BAAY,aAAa,CAAC,SAAS,QAAQ;CAC7C,QAAQ;CACT,CAAC;AAEF,MAAa,gBAAgB,OAAO,WAAmB,cAAsB,QAAgB;AAC3F,KAAI;EACF,MAAM,UAAU,IAAI,IAAI,mBAAmB,MAAM,CAAC,aAAa,IAAI,UAAU;AAC7E,MAAI,YAAY,KACd,OAAM,IAAI,MACR,kHACD;AAEH,SAAO,MAAM,kBAAkB,WAAW,cAAc,OAAO,QAAQ,CAAC;UACjE,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,0BAA0B,MAAM;AAC9C,QAAM"}
1
+ {"version":3,"file":"generateTrack.cjs","names":["Probe","Readable","generateSingleTrackFromPath","idempotentTask"],"sources":["../../src/tasks/generateTrack.ts"],"mappings":";;;;;;;;;;;AASA,MAAa,wBAAwB,OAAO,cAAsB,YAAoB;CACpF,MAAM,OAAA,GAAA,MAAA,SAAY,2BAA2B;AAC7C,KAAI,oBAAoB,QAAQ,OAAO,eAAe;AAYtD,MAVc,MAAMA,cAAAA,MAAM,UAAU,aAAa,EAUvC,eAAe;AACvB,MAAI,sEAAsE;EAC1E,MAAM,MAAM,OAAA,GAAA,iBAAA,UAAe,aAAa;AACxC,mCAAA,6BAA6B,IAAI;AACjC,SAAOC,YAAAA,SAAS,KAAK,IAAI;;AAI3B,SADe,MAAMC,4BAAAA,4BAA4B,cAAc,QAAQ,EACzD;;AAGhB,MAAa,oBAAoBC,uBAAAA,eAAe;CAC9C,OAAO;CACP,WAAW,cAAsB,aAAqB;EAEpD,MAAM,MAAM,aAAa,SAAS,QAAQ,GAAG,SAAS;AACtD,SAAO,IAAA,GAAA,UAAA,UAAY,aAAa,CAAC,WAAW;;CAE9C,QAAQ;CACT,CAAC;AAEF,MAAa,gBAAgB,OAAO,WAAmB,cAAsB,QAAgB;AAC3F,KAAI;EACF,MAAM,UAAU,IAAI,IAAI,mBAAmB,MAAM,CAAC,aAAa,IAAI,UAAU;AAC7E,MAAI,YAAY,KACd,OAAM,IAAI,MACR,kHACD;AAEH,SAAO,MAAM,kBAAkB,WAAW,cAAc,OAAO,QAAQ,CAAC;UACjE,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,0BAA0B,MAAM;AAC9C,QAAM"}
@@ -1,16 +1,29 @@
1
+ import { Probe } from "../Probe.js";
1
2
  import { idempotentTask } from "../idempotentTask.js";
3
+ import { patchWebmForSegmentedServing } from "../generateWebmSegmentIndex.js";
2
4
  import { generateSingleTrackFromPath } from "../generateSingleTrack.js";
3
5
  import debug from "debug";
6
+ import { Readable } from "node:stream";
7
+ import { readFile } from "node:fs/promises";
4
8
  import { basename } from "node:path";
5
-
6
9
  //#region src/tasks/generateTrack.ts
7
10
  const generateTrackFromPath = async (absolutePath, trackId) => {
8
- debug("ef:generateTrackFragment")(`Generating track ${trackId} for ${absolutePath}`);
11
+ const log = debug("ef:generateTrackFragment");
12
+ log(`Generating track ${trackId} for ${absolutePath}`);
13
+ if ((await Probe.probePath(absolutePath)).hasAlphaVideo) {
14
+ log(`VP9 alpha WebM: copying source with Segment size + SeekHead patched`);
15
+ const buf = await readFile(absolutePath);
16
+ patchWebmForSegmentedServing(buf);
17
+ return Readable.from(buf);
18
+ }
9
19
  return (await generateSingleTrackFromPath(absolutePath, trackId)).stream;
10
20
  };
11
21
  const generateTrackTask = idempotentTask({
12
22
  label: "track",
13
- filename: (absolutePath, trackId) => `${basename(absolutePath)}.track-${trackId}.mp4`,
23
+ filename: (absolutePath, _trackId) => {
24
+ const ext = absolutePath.endsWith(".webm") ? "webm" : "mp4";
25
+ return `${basename(absolutePath)}.track-1.${ext}`;
26
+ },
14
27
  runner: generateTrackFromPath
15
28
  });
16
29
  const generateTrack = async (cacheRoot, absolutePath, url) => {
@@ -24,7 +37,7 @@ const generateTrack = async (cacheRoot, absolutePath, url) => {
24
37
  throw error;
25
38
  }
26
39
  };
27
-
28
40
  //#endregion
29
41
  export { generateTrack, generateTrackFromPath };
42
+
30
43
  //# sourceMappingURL=generateTrack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateTrack.js","names":[],"sources":["../../src/tasks/generateTrack.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { generateSingleTrackFromPath } from \"../generateSingleTrack.js\";\n\nexport const generateTrackFromPath = async (absolutePath: string, trackId: number) => {\n const log = debug(\"ef:generateTrackFragment\");\n log(`Generating track ${trackId} for ${absolutePath}`);\n\n // Use the single-track implementation\n const result = await generateSingleTrackFromPath(absolutePath, trackId);\n\n // Return just the stream for compatibility with existing API\n return result.stream;\n};\n\nexport const generateTrackTask = idempotentTask({\n label: \"track\",\n filename: (absolutePath: string, trackId: number) =>\n `${basename(absolutePath)}.track-${trackId}.mp4`,\n runner: generateTrackFromPath,\n});\n\nexport const generateTrack = async (cacheRoot: string, absolutePath: string, url: string) => {\n try {\n const trackId = new URL(`http://localhost${url}`).searchParams.get(\"trackId\");\n if (trackId === null) {\n throw new Error(\n \"No trackId provided. It must be specified in the query string: ?trackId=1 (for video) or ?trackId=2 (for audio)\",\n );\n }\n return await generateTrackTask(cacheRoot, absolutePath, Number(trackId));\n } catch (error) {\n console.error(error);\n console.trace(\"Error generating track\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;AAKA,MAAa,wBAAwB,OAAO,cAAsB,YAAoB;AAEpF,CADY,MAAM,2BAA2B,CACzC,oBAAoB,QAAQ,OAAO,eAAe;AAMtD,SAHe,MAAM,4BAA4B,cAAc,QAAQ,EAGzD;;AAGhB,MAAa,oBAAoB,eAAe;CAC9C,OAAO;CACP,WAAW,cAAsB,YAC/B,GAAG,SAAS,aAAa,CAAC,SAAS,QAAQ;CAC7C,QAAQ;CACT,CAAC;AAEF,MAAa,gBAAgB,OAAO,WAAmB,cAAsB,QAAgB;AAC3F,KAAI;EACF,MAAM,UAAU,IAAI,IAAI,mBAAmB,MAAM,CAAC,aAAa,IAAI,UAAU;AAC7E,MAAI,YAAY,KACd,OAAM,IAAI,MACR,kHACD;AAEH,SAAO,MAAM,kBAAkB,WAAW,cAAc,OAAO,QAAQ,CAAC;UACjE,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,0BAA0B,MAAM;AAC9C,QAAM"}
1
+ {"version":3,"file":"generateTrack.js","names":[],"sources":["../../src/tasks/generateTrack.ts"],"mappings":";;;;;;;;;AASA,MAAa,wBAAwB,OAAO,cAAsB,YAAoB;CACpF,MAAM,MAAM,MAAM,2BAA2B;AAC7C,KAAI,oBAAoB,QAAQ,OAAO,eAAe;AAYtD,MAVc,MAAM,MAAM,UAAU,aAAa,EAUvC,eAAe;AACvB,MAAI,sEAAsE;EAC1E,MAAM,MAAM,MAAM,SAAS,aAAa;AACxC,+BAA6B,IAAI;AACjC,SAAO,SAAS,KAAK,IAAI;;AAI3B,SADe,MAAM,4BAA4B,cAAc,QAAQ,EACzD;;AAGhB,MAAa,oBAAoB,eAAe;CAC9C,OAAO;CACP,WAAW,cAAsB,aAAqB;EAEpD,MAAM,MAAM,aAAa,SAAS,QAAQ,GAAG,SAAS;AACtD,SAAO,GAAG,SAAS,aAAa,CAAC,WAAW;;CAE9C,QAAQ;CACT,CAAC;AAEF,MAAa,gBAAgB,OAAO,WAAmB,cAAsB,QAAgB;AAC3F,KAAI;EACF,MAAM,UAAU,IAAI,IAAI,mBAAmB,MAAM,CAAC,aAAa,IAAI,UAAU;AAC7E,MAAI,YAAY,KACd,OAAM,IAAI,MACR,kHACD;AAEH,SAAO,MAAM,kBAAkB,WAAW,cAAc,OAAO,QAAQ,CAAC;UACjE,OAAO;AACd,UAAQ,MAAM,MAAM;AACpB,UAAQ,MAAM,0BAA0B,MAAM;AAC9C,QAAM"}
@@ -1,12 +1,11 @@
1
- const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- const require_Probe = require('../Probe.cjs');
3
- const require_generateFragmentIndex = require('../generateFragmentIndex.cjs');
4
- const require_idempotentTask = require('../idempotentTask.cjs');
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_Probe = require("../Probe.cjs");
3
+ const require_generateFragmentIndex = require("../generateFragmentIndex.cjs");
4
+ const require_idempotentTask = require("../idempotentTask.cjs");
5
+ const require_generateWebmSegmentIndex = require("../generateWebmSegmentIndex.cjs");
5
6
  let debug = require("debug");
6
- debug = require_rolldown_runtime.__toESM(debug);
7
+ debug = require_runtime.__toESM(debug);
7
8
  let node_path = require("node:path");
8
- node_path = require_rolldown_runtime.__toESM(node_path);
9
-
10
9
  //#region src/tasks/generateTrackFragmentIndex.ts
11
10
  const generateTrackFragmentIndexFromPath = async (absolutePath) => {
12
11
  const log = (0, debug.default)("ef:generateTrackFragment");
@@ -14,6 +13,24 @@ const generateTrackFragmentIndexFromPath = async (absolutePath) => {
14
13
  const startTimeOffsetMs = probe.startTimeOffsetMs;
15
14
  if (startTimeOffsetMs !== void 0) log(`Extracted start_time offset: ${startTimeOffsetMs}ms`);
16
15
  else log("No format/stream timing offset found - will detect from composition time");
16
+ if (probe.hasAlphaVideo) {
17
+ log(`VP9 alpha WebM: using EBML cluster index (no transcoding)`);
18
+ const webmIndex = await require_generateWebmSegmentIndex.generateWebmSegmentIndex(absolutePath, startTimeOffsetMs);
19
+ const scrubResult = await (async () => {
20
+ try {
21
+ log("Generating scrub track fragment index for alpha WebM");
22
+ const result = await require_generateFragmentIndex.generateFragmentIndex(probe.createScrubTrackReadstream(), startTimeOffsetMs, { 0: -1 });
23
+ log("Scrub track fragment index generated successfully");
24
+ return result;
25
+ } catch (error) {
26
+ log(`Failed to generate scrub track fragment index: ${error}`);
27
+ return null;
28
+ }
29
+ })();
30
+ const trackFragmentIndexes = { ...webmIndex };
31
+ if (scrubResult) Object.assign(trackFragmentIndexes, scrubResult);
32
+ return trackFragmentIndexes;
33
+ }
17
34
  log(`Generating track fragment index for ${absolutePath} using single-track approach`);
18
35
  const trackTasks = probe.streams.map((stream, streamIndex) => {
19
36
  if (stream.codec_type !== "audio" && stream.codec_type !== "video") return null;
@@ -24,9 +41,7 @@ const generateTrackFragmentIndexFromPath = async (absolutePath) => {
24
41
  const scrubTask = probe.videoStreams.length > 0 ? (async () => {
25
42
  try {
26
43
  log("Generating scrub track fragment index");
27
- const scrubStream = probe.createScrubTrackReadstream();
28
- const scrubTrackId = -1;
29
- const result = await require_generateFragmentIndex.generateFragmentIndex(scrubStream, startTimeOffsetMs, { 0: scrubTrackId });
44
+ const result = await require_generateFragmentIndex.generateFragmentIndex(probe.createScrubTrackReadstream(), startTimeOffsetMs, { 0: -1 });
30
45
  log("Scrub track fragment index generated successfully");
31
46
  return result;
32
47
  } catch (error) {
@@ -56,8 +71,8 @@ const generateTrackFragmentIndex = async (cacheRoot, absolutePath) => {
56
71
  throw error;
57
72
  }
58
73
  };
59
-
60
74
  //#endregion
61
75
  exports.generateTrackFragmentIndex = generateTrackFragmentIndex;
62
76
  exports.generateTrackFragmentIndexFromPath = generateTrackFragmentIndexFromPath;
77
+
63
78
  //# sourceMappingURL=generateTrackFragmentIndex.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateTrackFragmentIndex.cjs","names":["Probe","generateFragmentIndex","scrubTask: Promise<Record<number, TrackFragmentIndex> | null>","trackFragmentIndexes: Record<number, TrackFragmentIndex>","idempotentTask"],"sources":["../../src/tasks/generateTrackFragmentIndex.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { Probe } from \"../Probe.js\";\nimport { generateFragmentIndex } from \"../generateFragmentIndex.js\";\nimport type { TrackFragmentIndex } from \"../Probe.js\";\n\nexport const generateTrackFragmentIndexFromPath = async (absolutePath: string) => {\n const log = debug(\"ef:generateTrackFragment\");\n const probe = await Probe.probePath(absolutePath);\n\n const startTimeOffsetMs = probe.startTimeOffsetMs;\n if (startTimeOffsetMs !== undefined) {\n log(`Extracted start_time offset: ${startTimeOffsetMs}ms`);\n } else {\n log(\"No format/stream timing offset found - will detect from composition time\");\n }\n\n log(`Generating track fragment index for ${absolutePath} using single-track approach`);\n\n // Process all audio/video streams and scrub track in parallel\n const trackTasks = probe.streams\n .map((stream, streamIndex) => {\n if (stream.codec_type !== \"audio\" && stream.codec_type !== \"video\") {\n return null;\n }\n const trackId = streamIndex + 1;\n log(`Processing track ${trackId} (${stream.codec_type})`);\n const trackStream = probe.createTrackReadstream(streamIndex);\n const trackIdMapping = { 0: trackId };\n return generateFragmentIndex(trackStream, startTimeOffsetMs, trackIdMapping);\n })\n .filter((task): task is Promise<Record<number, TrackFragmentIndex>> => task !== null);\n\n const scrubTask: Promise<Record<number, TrackFragmentIndex> | null> =\n probe.videoStreams.length > 0\n ? (async () => {\n try {\n log(\"Generating scrub track fragment index\");\n const scrubStream = probe.createScrubTrackReadstream();\n const scrubTrackId = -1;\n const result = await generateFragmentIndex(scrubStream, startTimeOffsetMs, {\n 0: scrubTrackId,\n });\n log(\"Scrub track fragment index generated successfully\");\n return result;\n } catch (error) {\n log(`Failed to generate scrub track fragment index: ${error}`);\n return null;\n }\n })()\n : Promise.resolve(null);\n\n const [trackResults, scrubResult] = await Promise.all([Promise.all(trackTasks), scrubTask]);\n\n const trackFragmentIndexes: Record<number, TrackFragmentIndex> = {};\n for (const result of trackResults) {\n Object.assign(trackFragmentIndexes, result);\n }\n if (scrubResult) {\n Object.assign(trackFragmentIndexes, scrubResult);\n }\n\n return trackFragmentIndexes;\n};\n\nconst generateTrackFragmentIndexTask = idempotentTask({\n label: \"trackFragmentIndex\",\n filename: (absolutePath) => `${basename(absolutePath)}.tracks.json`,\n runner: async (absolutePath: string) => {\n const index = await generateTrackFragmentIndexFromPath(absolutePath);\n return JSON.stringify(index, null, 2);\n },\n});\n\nexport const generateTrackFragmentIndex = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateTrackFragmentIndexTask(cacheRoot, absolutePath);\n } catch (error) {\n console.trace(\"Error generating track fragment index\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;;;;AAOA,MAAa,qCAAqC,OAAO,iBAAyB;CAChF,MAAM,yBAAY,2BAA2B;CAC7C,MAAM,QAAQ,MAAMA,oBAAM,UAAU,aAAa;CAEjD,MAAM,oBAAoB,MAAM;AAChC,KAAI,sBAAsB,OACxB,KAAI,gCAAgC,kBAAkB,IAAI;KAE1D,KAAI,2EAA2E;AAGjF,KAAI,uCAAuC,aAAa,8BAA8B;CAGtF,MAAM,aAAa,MAAM,QACtB,KAAK,QAAQ,gBAAgB;AAC5B,MAAI,OAAO,eAAe,WAAW,OAAO,eAAe,QACzD,QAAO;EAET,MAAM,UAAU,cAAc;AAC9B,MAAI,oBAAoB,QAAQ,IAAI,OAAO,WAAW,GAAG;AAGzD,SAAOC,oDAFa,MAAM,sBAAsB,YAAY,EAElB,mBADnB,EAAE,GAAG,SAAS,CACuC;GAC5E,CACD,QAAQ,SAA8D,SAAS,KAAK;CAEvF,MAAMC,YACJ,MAAM,aAAa,SAAS,KACvB,YAAY;AACX,MAAI;AACF,OAAI,wCAAwC;GAC5C,MAAM,cAAc,MAAM,4BAA4B;GACtD,MAAM,eAAe;GACrB,MAAM,SAAS,MAAMD,oDAAsB,aAAa,mBAAmB,EACzE,GAAG,cACJ,CAAC;AACF,OAAI,oDAAoD;AACxD,UAAO;WACA,OAAO;AACd,OAAI,kDAAkD,QAAQ;AAC9D,UAAO;;KAEP,GACJ,QAAQ,QAAQ,KAAK;CAE3B,MAAM,CAAC,cAAc,eAAe,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,WAAW,EAAE,UAAU,CAAC;CAE3F,MAAME,uBAA2D,EAAE;AACnE,MAAK,MAAM,UAAU,aACnB,QAAO,OAAO,sBAAsB,OAAO;AAE7C,KAAI,YACF,QAAO,OAAO,sBAAsB,YAAY;AAGlD,QAAO;;AAGT,MAAM,iCAAiCC,sCAAe;CACpD,OAAO;CACP,WAAW,iBAAiB,2BAAY,aAAa,CAAC;CACtD,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,mCAAmC,aAAa;AACpE,SAAO,KAAK,UAAU,OAAO,MAAM,EAAE;;CAExC,CAAC;AAEF,MAAa,6BAA6B,OAAO,WAAmB,iBAAyB;AAC3F,KAAI;AACF,SAAO,MAAM,+BAA+B,WAAW,aAAa;UAC7D,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
1
+ {"version":3,"file":"generateTrackFragmentIndex.cjs","names":["Probe","generateWebmSegmentIndex","generateFragmentIndex","idempotentTask"],"sources":["../../src/tasks/generateTrackFragmentIndex.ts"],"mappings":";;;;;;;;;AAQA,MAAa,qCAAqC,OAAO,iBAAyB;CAChF,MAAM,OAAA,GAAA,MAAA,SAAY,2BAA2B;CAC7C,MAAM,QAAQ,MAAMA,cAAAA,MAAM,UAAU,aAAa;CAEjD,MAAM,oBAAoB,MAAM;AAChC,KAAI,sBAAsB,KAAA,EACxB,KAAI,gCAAgC,kBAAkB,IAAI;KAE1D,KAAI,2EAA2E;AAOjF,KAAI,MAAM,eAAe;AACvB,MAAI,4DAA4D;EAChE,MAAM,YAAY,MAAMC,iCAAAA,yBAAyB,cAAc,kBAAkB;EAgBjF,MAAM,cAAc,OAbmD,YAAY;AACjF,OAAI;AACF,QAAI,uDAAuD;IAE3D,MAAM,SAAS,MAAMC,8BAAAA,sBADD,MAAM,4BAA4B,EACE,mBAAmB,EAAE,GAAG,IAAI,CAAC;AACrF,QAAI,oDAAoD;AACxD,WAAO;YACA,OAAO;AACd,QAAI,kDAAkD,QAAQ;AAC9D,WAAO;;MAEP;EAGJ,MAAM,uBAA2D,EAAE,GAAG,WAAW;AACjF,MAAI,YAAa,QAAO,OAAO,sBAAsB,YAAY;AACjE,SAAO;;AAIT,KAAI,uCAAuC,aAAa,8BAA8B;CAEtF,MAAM,aAAa,MAAM,QACtB,KAAK,QAAQ,gBAAgB;AAC5B,MAAI,OAAO,eAAe,WAAW,OAAO,eAAe,QACzD,QAAO;EAET,MAAM,UAAU,cAAc;AAC9B,MAAI,oBAAoB,QAAQ,IAAI,OAAO,WAAW,GAAG;AAGzD,SAAOA,8BAAAA,sBAFa,MAAM,sBAAsB,YAAY,EAElB,mBADnB,EAAE,GAAG,SAAS,CACuC;GAC5E,CACD,QAAQ,SAA8D,SAAS,KAAK;CAEvF,MAAM,YACJ,MAAM,aAAa,SAAS,KACvB,YAAY;AACX,MAAI;AACF,OAAI,wCAAwC;GAE5C,MAAM,SAAS,MAAMA,8BAAAA,sBADD,MAAM,4BAA4B,EACE,mBAAmB,EAAE,GAAG,IAAI,CAAC;AACrF,OAAI,oDAAoD;AACxD,UAAO;WACA,OAAO;AACd,OAAI,kDAAkD,QAAQ;AAC9D,UAAO;;KAEP,GACJ,QAAQ,QAAQ,KAAK;CAE3B,MAAM,CAAC,cAAc,eAAe,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,WAAW,EAAE,UAAU,CAAC;CAE3F,MAAM,uBAA2D,EAAE;AACnE,MAAK,MAAM,UAAU,aACnB,QAAO,OAAO,sBAAsB,OAAO;AAE7C,KAAI,YACF,QAAO,OAAO,sBAAsB,YAAY;AAGlD,QAAO;;AAGT,MAAM,iCAAiCC,uBAAAA,eAAe;CACpD,OAAO;CACP,WAAW,iBAAiB,IAAA,GAAA,UAAA,UAAY,aAAa,CAAC;CACtD,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,mCAAmC,aAAa;AACpE,SAAO,KAAK,UAAU,OAAO,MAAM,EAAE;;CAExC,CAAC;AAEF,MAAa,6BAA6B,OAAO,WAAmB,iBAAyB;AAC3F,KAAI;AACF,SAAO,MAAM,+BAA+B,WAAW,aAAa;UAC7D,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
@@ -1,9 +1,9 @@
1
1
  import { Probe } from "../Probe.js";
2
2
  import { generateFragmentIndex } from "../generateFragmentIndex.js";
3
3
  import { idempotentTask } from "../idempotentTask.js";
4
+ import { generateWebmSegmentIndex } from "../generateWebmSegmentIndex.js";
4
5
  import debug from "debug";
5
6
  import { basename } from "node:path";
6
-
7
7
  //#region src/tasks/generateTrackFragmentIndex.ts
8
8
  const generateTrackFragmentIndexFromPath = async (absolutePath) => {
9
9
  const log = debug("ef:generateTrackFragment");
@@ -11,6 +11,24 @@ const generateTrackFragmentIndexFromPath = async (absolutePath) => {
11
11
  const startTimeOffsetMs = probe.startTimeOffsetMs;
12
12
  if (startTimeOffsetMs !== void 0) log(`Extracted start_time offset: ${startTimeOffsetMs}ms`);
13
13
  else log("No format/stream timing offset found - will detect from composition time");
14
+ if (probe.hasAlphaVideo) {
15
+ log(`VP9 alpha WebM: using EBML cluster index (no transcoding)`);
16
+ const webmIndex = await generateWebmSegmentIndex(absolutePath, startTimeOffsetMs);
17
+ const scrubResult = await (async () => {
18
+ try {
19
+ log("Generating scrub track fragment index for alpha WebM");
20
+ const result = await generateFragmentIndex(probe.createScrubTrackReadstream(), startTimeOffsetMs, { 0: -1 });
21
+ log("Scrub track fragment index generated successfully");
22
+ return result;
23
+ } catch (error) {
24
+ log(`Failed to generate scrub track fragment index: ${error}`);
25
+ return null;
26
+ }
27
+ })();
28
+ const trackFragmentIndexes = { ...webmIndex };
29
+ if (scrubResult) Object.assign(trackFragmentIndexes, scrubResult);
30
+ return trackFragmentIndexes;
31
+ }
14
32
  log(`Generating track fragment index for ${absolutePath} using single-track approach`);
15
33
  const trackTasks = probe.streams.map((stream, streamIndex) => {
16
34
  if (stream.codec_type !== "audio" && stream.codec_type !== "video") return null;
@@ -21,9 +39,7 @@ const generateTrackFragmentIndexFromPath = async (absolutePath) => {
21
39
  const scrubTask = probe.videoStreams.length > 0 ? (async () => {
22
40
  try {
23
41
  log("Generating scrub track fragment index");
24
- const scrubStream = probe.createScrubTrackReadstream();
25
- const scrubTrackId = -1;
26
- const result = await generateFragmentIndex(scrubStream, startTimeOffsetMs, { 0: scrubTrackId });
42
+ const result = await generateFragmentIndex(probe.createScrubTrackReadstream(), startTimeOffsetMs, { 0: -1 });
27
43
  log("Scrub track fragment index generated successfully");
28
44
  return result;
29
45
  } catch (error) {
@@ -53,7 +69,7 @@ const generateTrackFragmentIndex = async (cacheRoot, absolutePath) => {
53
69
  throw error;
54
70
  }
55
71
  };
56
-
57
72
  //#endregion
58
73
  export { generateTrackFragmentIndex, generateTrackFragmentIndexFromPath };
74
+
59
75
  //# sourceMappingURL=generateTrackFragmentIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateTrackFragmentIndex.js","names":["scrubTask: Promise<Record<number, TrackFragmentIndex> | null>","trackFragmentIndexes: Record<number, TrackFragmentIndex>"],"sources":["../../src/tasks/generateTrackFragmentIndex.ts"],"sourcesContent":["import { idempotentTask } from \"../idempotentTask.js\";\nimport debug from \"debug\";\nimport { basename } from \"node:path\";\nimport { Probe } from \"../Probe.js\";\nimport { generateFragmentIndex } from \"../generateFragmentIndex.js\";\nimport type { TrackFragmentIndex } from \"../Probe.js\";\n\nexport const generateTrackFragmentIndexFromPath = async (absolutePath: string) => {\n const log = debug(\"ef:generateTrackFragment\");\n const probe = await Probe.probePath(absolutePath);\n\n const startTimeOffsetMs = probe.startTimeOffsetMs;\n if (startTimeOffsetMs !== undefined) {\n log(`Extracted start_time offset: ${startTimeOffsetMs}ms`);\n } else {\n log(\"No format/stream timing offset found - will detect from composition time\");\n }\n\n log(`Generating track fragment index for ${absolutePath} using single-track approach`);\n\n // Process all audio/video streams and scrub track in parallel\n const trackTasks = probe.streams\n .map((stream, streamIndex) => {\n if (stream.codec_type !== \"audio\" && stream.codec_type !== \"video\") {\n return null;\n }\n const trackId = streamIndex + 1;\n log(`Processing track ${trackId} (${stream.codec_type})`);\n const trackStream = probe.createTrackReadstream(streamIndex);\n const trackIdMapping = { 0: trackId };\n return generateFragmentIndex(trackStream, startTimeOffsetMs, trackIdMapping);\n })\n .filter((task): task is Promise<Record<number, TrackFragmentIndex>> => task !== null);\n\n const scrubTask: Promise<Record<number, TrackFragmentIndex> | null> =\n probe.videoStreams.length > 0\n ? (async () => {\n try {\n log(\"Generating scrub track fragment index\");\n const scrubStream = probe.createScrubTrackReadstream();\n const scrubTrackId = -1;\n const result = await generateFragmentIndex(scrubStream, startTimeOffsetMs, {\n 0: scrubTrackId,\n });\n log(\"Scrub track fragment index generated successfully\");\n return result;\n } catch (error) {\n log(`Failed to generate scrub track fragment index: ${error}`);\n return null;\n }\n })()\n : Promise.resolve(null);\n\n const [trackResults, scrubResult] = await Promise.all([Promise.all(trackTasks), scrubTask]);\n\n const trackFragmentIndexes: Record<number, TrackFragmentIndex> = {};\n for (const result of trackResults) {\n Object.assign(trackFragmentIndexes, result);\n }\n if (scrubResult) {\n Object.assign(trackFragmentIndexes, scrubResult);\n }\n\n return trackFragmentIndexes;\n};\n\nconst generateTrackFragmentIndexTask = idempotentTask({\n label: \"trackFragmentIndex\",\n filename: (absolutePath) => `${basename(absolutePath)}.tracks.json`,\n runner: async (absolutePath: string) => {\n const index = await generateTrackFragmentIndexFromPath(absolutePath);\n return JSON.stringify(index, null, 2);\n },\n});\n\nexport const generateTrackFragmentIndex = async (cacheRoot: string, absolutePath: string) => {\n try {\n return await generateTrackFragmentIndexTask(cacheRoot, absolutePath);\n } catch (error) {\n console.trace(\"Error generating track fragment index\", error);\n throw error;\n }\n};\n"],"mappings":";;;;;;;AAOA,MAAa,qCAAqC,OAAO,iBAAyB;CAChF,MAAM,MAAM,MAAM,2BAA2B;CAC7C,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;CAEjD,MAAM,oBAAoB,MAAM;AAChC,KAAI,sBAAsB,OACxB,KAAI,gCAAgC,kBAAkB,IAAI;KAE1D,KAAI,2EAA2E;AAGjF,KAAI,uCAAuC,aAAa,8BAA8B;CAGtF,MAAM,aAAa,MAAM,QACtB,KAAK,QAAQ,gBAAgB;AAC5B,MAAI,OAAO,eAAe,WAAW,OAAO,eAAe,QACzD,QAAO;EAET,MAAM,UAAU,cAAc;AAC9B,MAAI,oBAAoB,QAAQ,IAAI,OAAO,WAAW,GAAG;AAGzD,SAAO,sBAFa,MAAM,sBAAsB,YAAY,EAElB,mBADnB,EAAE,GAAG,SAAS,CACuC;GAC5E,CACD,QAAQ,SAA8D,SAAS,KAAK;CAEvF,MAAMA,YACJ,MAAM,aAAa,SAAS,KACvB,YAAY;AACX,MAAI;AACF,OAAI,wCAAwC;GAC5C,MAAM,cAAc,MAAM,4BAA4B;GACtD,MAAM,eAAe;GACrB,MAAM,SAAS,MAAM,sBAAsB,aAAa,mBAAmB,EACzE,GAAG,cACJ,CAAC;AACF,OAAI,oDAAoD;AACxD,UAAO;WACA,OAAO;AACd,OAAI,kDAAkD,QAAQ;AAC9D,UAAO;;KAEP,GACJ,QAAQ,QAAQ,KAAK;CAE3B,MAAM,CAAC,cAAc,eAAe,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,WAAW,EAAE,UAAU,CAAC;CAE3F,MAAMC,uBAA2D,EAAE;AACnE,MAAK,MAAM,UAAU,aACnB,QAAO,OAAO,sBAAsB,OAAO;AAE7C,KAAI,YACF,QAAO,OAAO,sBAAsB,YAAY;AAGlD,QAAO;;AAGT,MAAM,iCAAiC,eAAe;CACpD,OAAO;CACP,WAAW,iBAAiB,GAAG,SAAS,aAAa,CAAC;CACtD,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,mCAAmC,aAAa;AACpE,SAAO,KAAK,UAAU,OAAO,MAAM,EAAE;;CAExC,CAAC;AAEF,MAAa,6BAA6B,OAAO,WAAmB,iBAAyB;AAC3F,KAAI;AACF,SAAO,MAAM,+BAA+B,WAAW,aAAa;UAC7D,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
1
+ {"version":3,"file":"generateTrackFragmentIndex.js","names":[],"sources":["../../src/tasks/generateTrackFragmentIndex.ts"],"mappings":";;;;;;;AAQA,MAAa,qCAAqC,OAAO,iBAAyB;CAChF,MAAM,MAAM,MAAM,2BAA2B;CAC7C,MAAM,QAAQ,MAAM,MAAM,UAAU,aAAa;CAEjD,MAAM,oBAAoB,MAAM;AAChC,KAAI,sBAAsB,KAAA,EACxB,KAAI,gCAAgC,kBAAkB,IAAI;KAE1D,KAAI,2EAA2E;AAOjF,KAAI,MAAM,eAAe;AACvB,MAAI,4DAA4D;EAChE,MAAM,YAAY,MAAM,yBAAyB,cAAc,kBAAkB;EAgBjF,MAAM,cAAc,OAbmD,YAAY;AACjF,OAAI;AACF,QAAI,uDAAuD;IAE3D,MAAM,SAAS,MAAM,sBADD,MAAM,4BAA4B,EACE,mBAAmB,EAAE,GAAG,IAAI,CAAC;AACrF,QAAI,oDAAoD;AACxD,WAAO;YACA,OAAO;AACd,QAAI,kDAAkD,QAAQ;AAC9D,WAAO;;MAEP;EAGJ,MAAM,uBAA2D,EAAE,GAAG,WAAW;AACjF,MAAI,YAAa,QAAO,OAAO,sBAAsB,YAAY;AACjE,SAAO;;AAIT,KAAI,uCAAuC,aAAa,8BAA8B;CAEtF,MAAM,aAAa,MAAM,QACtB,KAAK,QAAQ,gBAAgB;AAC5B,MAAI,OAAO,eAAe,WAAW,OAAO,eAAe,QACzD,QAAO;EAET,MAAM,UAAU,cAAc;AAC9B,MAAI,oBAAoB,QAAQ,IAAI,OAAO,WAAW,GAAG;AAGzD,SAAO,sBAFa,MAAM,sBAAsB,YAAY,EAElB,mBADnB,EAAE,GAAG,SAAS,CACuC;GAC5E,CACD,QAAQ,SAA8D,SAAS,KAAK;CAEvF,MAAM,YACJ,MAAM,aAAa,SAAS,KACvB,YAAY;AACX,MAAI;AACF,OAAI,wCAAwC;GAE5C,MAAM,SAAS,MAAM,sBADD,MAAM,4BAA4B,EACE,mBAAmB,EAAE,GAAG,IAAI,CAAC;AACrF,OAAI,oDAAoD;AACxD,UAAO;WACA,OAAO;AACd,OAAI,kDAAkD,QAAQ;AAC9D,UAAO;;KAEP,GACJ,QAAQ,QAAQ,KAAK;CAE3B,MAAM,CAAC,cAAc,eAAe,MAAM,QAAQ,IAAI,CAAC,QAAQ,IAAI,WAAW,EAAE,UAAU,CAAC;CAE3F,MAAM,uBAA2D,EAAE;AACnE,MAAK,MAAM,UAAU,aACnB,QAAO,OAAO,sBAAsB,OAAO;AAE7C,KAAI,YACF,QAAO,OAAO,sBAAsB,YAAY;AAGlD,QAAO;;AAGT,MAAM,iCAAiC,eAAe;CACpD,OAAO;CACP,WAAW,iBAAiB,GAAG,SAAS,aAAa,CAAC;CACtD,QAAQ,OAAO,iBAAyB;EACtC,MAAM,QAAQ,MAAM,mCAAmC,aAAa;AACpE,SAAO,KAAK,UAAU,OAAO,MAAM,EAAE;;CAExC,CAAC;AAEF,MAAa,6BAA6B,OAAO,WAAmB,iBAAyB;AAC3F,KAAI;AACF,SAAO,MAAM,+BAA+B,WAAW,aAAa;UAC7D,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
@@ -1,10 +1,9 @@
1
-
2
1
  //#region src/truncateDecimal.ts
3
2
  function truncateDecimal(num, decimals) {
4
3
  const factor = 10 ** decimals;
5
4
  return Math.trunc(num * factor) / factor;
6
5
  }
7
-
8
6
  //#endregion
9
7
  exports.truncateDecimal = truncateDecimal;
8
+
10
9
  //# sourceMappingURL=truncateDecimal.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"truncateDecimal.cjs","names":[],"sources":["../src/truncateDecimal.ts"],"sourcesContent":["// Helper to calculate AAC frame-aligned segment durations for audio\nexport function truncateDecimal(num: number, decimals: number) {\n const factor = 10 ** decimals;\n return Math.trunc(num * factor) / factor;\n}\n"],"mappings":";;AACA,SAAgB,gBAAgB,KAAa,UAAkB;CAC7D,MAAM,SAAS,MAAM;AACrB,QAAO,KAAK,MAAM,MAAM,OAAO,GAAG"}
1
+ {"version":3,"file":"truncateDecimal.cjs","names":[],"sources":["../src/truncateDecimal.ts"],"mappings":";AACA,SAAgB,gBAAgB,KAAa,UAAkB;CAC7D,MAAM,SAAS,MAAM;AACrB,QAAO,KAAK,MAAM,MAAM,OAAO,GAAG"}
@@ -3,7 +3,7 @@ function truncateDecimal(num, decimals) {
3
3
  const factor = 10 ** decimals;
4
4
  return Math.trunc(num * factor) / factor;
5
5
  }
6
-
7
6
  //#endregion
8
7
  export { truncateDecimal };
8
+
9
9
  //# sourceMappingURL=truncateDecimal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"truncateDecimal.js","names":[],"sources":["../src/truncateDecimal.ts"],"sourcesContent":["// Helper to calculate AAC frame-aligned segment durations for audio\nexport function truncateDecimal(num: number, decimals: number) {\n const factor = 10 ** decimals;\n return Math.trunc(num * factor) / factor;\n}\n"],"mappings":";AACA,SAAgB,gBAAgB,KAAa,UAAkB;CAC7D,MAAM,SAAS,MAAM;AACrB,QAAO,KAAK,MAAM,MAAM,OAAO,GAAG"}
1
+ {"version":3,"file":"truncateDecimal.js","names":[],"sources":["../src/truncateDecimal.ts"],"mappings":";AACA,SAAgB,gBAAgB,KAAa,UAAkB;CAC7D,MAAM,SAAS,MAAM;AACrB,QAAO,KAAK,MAAM,MAAM,OAAO,GAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/assets",
3
- "version": "0.47.1",
3
+ "version": "0.48.0",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",