@steipete/summarize-core 0.11.1 → 0.13.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 (138) hide show
  1. package/dist/esm/content/bun.js +21 -0
  2. package/dist/esm/content/bun.js.map +1 -0
  3. package/dist/esm/content/direct-media.js +100 -0
  4. package/dist/esm/content/direct-media.js.map +1 -0
  5. package/dist/esm/content/index.js +2 -1
  6. package/dist/esm/content/index.js.map +1 -1
  7. package/dist/esm/content/link-preview/client.js +6 -0
  8. package/dist/esm/content/link-preview/client.js.map +1 -1
  9. package/dist/esm/content/link-preview/content/fetcher.js +19 -2
  10. package/dist/esm/content/link-preview/content/fetcher.js.map +1 -1
  11. package/dist/esm/content/link-preview/content/firecrawl.js.map +1 -1
  12. package/dist/esm/content/link-preview/content/html.js.map +1 -1
  13. package/dist/esm/content/link-preview/content/index.js +29 -12
  14. package/dist/esm/content/link-preview/content/index.js.map +1 -1
  15. package/dist/esm/content/link-preview/content/utils.js.map +1 -1
  16. package/dist/esm/content/link-preview/content/video.js +1 -1
  17. package/dist/esm/content/link-preview/content/video.js.map +1 -1
  18. package/dist/esm/content/local-file.js +58 -0
  19. package/dist/esm/content/local-file.js.map +1 -0
  20. package/dist/esm/content/transcript/index.js +2 -0
  21. package/dist/esm/content/transcript/index.js.map +1 -1
  22. package/dist/esm/content/transcript/providers/generic-direct-media.js +47 -0
  23. package/dist/esm/content/transcript/providers/generic-direct-media.js.map +1 -0
  24. package/dist/esm/content/transcript/providers/generic-embedded.js +126 -0
  25. package/dist/esm/content/transcript/providers/generic-embedded.js.map +1 -0
  26. package/dist/esm/content/transcript/providers/generic-twitter.js +78 -0
  27. package/dist/esm/content/transcript/providers/generic-twitter.js.map +1 -0
  28. package/dist/esm/content/transcript/providers/generic.js +12 -248
  29. package/dist/esm/content/transcript/providers/generic.js.map +1 -1
  30. package/dist/esm/content/transcript/providers/podcast/apple-flow.js.map +1 -1
  31. package/dist/esm/content/transcript/providers/podcast/media.js +9 -1
  32. package/dist/esm/content/transcript/providers/podcast/media.js.map +1 -1
  33. package/dist/esm/content/transcript/providers/podcast/provider-flow.js +157 -0
  34. package/dist/esm/content/transcript/providers/podcast/provider-flow.js.map +1 -0
  35. package/dist/esm/content/transcript/providers/podcast/rss-feed.js +123 -0
  36. package/dist/esm/content/transcript/providers/podcast/rss-feed.js.map +1 -0
  37. package/dist/esm/content/transcript/providers/podcast/rss-transcript.js +113 -0
  38. package/dist/esm/content/transcript/providers/podcast/rss-transcript.js.map +1 -0
  39. package/dist/esm/content/transcript/providers/podcast/rss.js +2 -226
  40. package/dist/esm/content/transcript/providers/podcast/rss.js.map +1 -1
  41. package/dist/esm/content/transcript/providers/podcast/spotify-flow.js.map +1 -1
  42. package/dist/esm/content/transcript/providers/podcast.js +26 -155
  43. package/dist/esm/content/transcript/providers/podcast.js.map +1 -1
  44. package/dist/esm/content/transcript/providers/transcription-capability.js +22 -0
  45. package/dist/esm/content/transcript/providers/transcription-capability.js.map +1 -0
  46. package/dist/esm/content/transcript/providers/transcription-start.js +43 -32
  47. package/dist/esm/content/transcript/providers/transcription-start.js.map +1 -1
  48. package/dist/esm/content/transcript/providers/youtube/api.js +3 -2
  49. package/dist/esm/content/transcript/providers/youtube/api.js.map +1 -1
  50. package/dist/esm/content/transcript/providers/youtube/captions-player.js +173 -0
  51. package/dist/esm/content/transcript/providers/youtube/captions-player.js.map +1 -0
  52. package/dist/esm/content/transcript/providers/youtube/captions-shared.js +8 -0
  53. package/dist/esm/content/transcript/providers/youtube/captions-shared.js.map +1 -0
  54. package/dist/esm/content/transcript/providers/youtube/captions-transcript.js +361 -0
  55. package/dist/esm/content/transcript/providers/youtube/captions-transcript.js.map +1 -0
  56. package/dist/esm/content/transcript/providers/youtube/captions.js +2 -557
  57. package/dist/esm/content/transcript/providers/youtube/captions.js.map +1 -1
  58. package/dist/esm/content/transcript/providers/youtube/provider-flow.js +217 -0
  59. package/dist/esm/content/transcript/providers/youtube/provider-flow.js.map +1 -0
  60. package/dist/esm/content/transcript/providers/youtube/yt-dlp.js +33 -9
  61. package/dist/esm/content/transcript/providers/youtube/yt-dlp.js.map +1 -1
  62. package/dist/esm/content/transcript/providers/youtube.js +42 -194
  63. package/dist/esm/content/transcript/providers/youtube.js.map +1 -1
  64. package/dist/esm/content/transcript/transcription-config.js +24 -4
  65. package/dist/esm/content/transcript/transcription-config.js.map +1 -1
  66. package/dist/esm/content/url.js +5 -33
  67. package/dist/esm/content/url.js.map +1 -1
  68. package/dist/esm/processes.js.map +1 -1
  69. package/dist/esm/prompts/format.js +6 -0
  70. package/dist/esm/prompts/format.js.map +1 -1
  71. package/dist/esm/prompts/link-summary.js +27 -3
  72. package/dist/esm/prompts/link-summary.js.map +1 -1
  73. package/dist/esm/transcription/onnx-cli.js.map +1 -1
  74. package/dist/esm/transcription/whisper/assemblyai.js +132 -0
  75. package/dist/esm/transcription/whisper/assemblyai.js.map +1 -0
  76. package/dist/esm/transcription/whisper/chunking.js +64 -0
  77. package/dist/esm/transcription/whisper/chunking.js.map +1 -0
  78. package/dist/esm/transcription/whisper/cloud-providers.js +69 -0
  79. package/dist/esm/transcription/whisper/cloud-providers.js.map +1 -0
  80. package/dist/esm/transcription/whisper/core.js +320 -390
  81. package/dist/esm/transcription/whisper/core.js.map +1 -1
  82. package/dist/esm/transcription/whisper/gemini.js +324 -0
  83. package/dist/esm/transcription/whisper/gemini.js.map +1 -0
  84. package/dist/esm/transcription/whisper/groq.js +62 -1
  85. package/dist/esm/transcription/whisper/groq.js.map +1 -1
  86. package/dist/esm/transcription/whisper/preferences.js +16 -0
  87. package/dist/esm/transcription/whisper/preferences.js.map +1 -0
  88. package/dist/esm/transcription/whisper/provider-setup.js +62 -0
  89. package/dist/esm/transcription/whisper/provider-setup.js.map +1 -0
  90. package/dist/esm/transcription/whisper/remote-provider-attempts.js +189 -0
  91. package/dist/esm/transcription/whisper/remote-provider-attempts.js.map +1 -0
  92. package/dist/esm/transcription/whisper/remote.js +220 -0
  93. package/dist/esm/transcription/whisper/remote.js.map +1 -0
  94. package/dist/esm/transcription/whisper/whisper-cpp.js +21 -18
  95. package/dist/esm/transcription/whisper/whisper-cpp.js.map +1 -1
  96. package/dist/types/content/bun.d.ts +6 -0
  97. package/dist/types/content/direct-media.d.ts +9 -0
  98. package/dist/types/content/index.d.ts +2 -1
  99. package/dist/types/content/link-preview/client.d.ts +3 -1
  100. package/dist/types/content/link-preview/content/fetcher.d.ts +1 -1
  101. package/dist/types/content/link-preview/content/html.d.ts +1 -1
  102. package/dist/types/content/link-preview/deps.d.ts +8 -2
  103. package/dist/types/content/link-preview/types.d.ts +1 -1
  104. package/dist/types/content/local-file.d.ts +16 -0
  105. package/dist/types/content/transcript/providers/generic-direct-media.d.ts +11 -0
  106. package/dist/types/content/transcript/providers/generic-embedded.d.ts +16 -0
  107. package/dist/types/content/transcript/providers/generic-twitter.d.ts +11 -0
  108. package/dist/types/content/transcript/providers/podcast/flow-context.d.ts +3 -0
  109. package/dist/types/content/transcript/providers/podcast/media.d.ts +4 -2
  110. package/dist/types/content/transcript/providers/podcast/provider-flow.d.ts +7 -0
  111. package/dist/types/content/transcript/providers/podcast/rss-feed.d.ts +15 -0
  112. package/dist/types/content/transcript/providers/podcast/rss-transcript.d.ts +12 -0
  113. package/dist/types/content/transcript/providers/podcast/rss.d.ts +2 -24
  114. package/dist/types/content/transcript/providers/transcription-capability.d.ts +18 -0
  115. package/dist/types/content/transcript/providers/transcription-start.d.ts +11 -3
  116. package/dist/types/content/transcript/providers/youtube/captions-player.d.ts +12 -0
  117. package/dist/types/content/transcript/providers/youtube/captions-shared.d.ts +42 -0
  118. package/dist/types/content/transcript/providers/youtube/captions-transcript.d.ts +4 -0
  119. package/dist/types/content/transcript/providers/youtube/captions.d.ts +2 -19
  120. package/dist/types/content/transcript/providers/youtube/provider-flow.d.ts +34 -0
  121. package/dist/types/content/transcript/providers/youtube/yt-dlp.d.ts +4 -2
  122. package/dist/types/content/transcript/transcription-config.d.ts +6 -0
  123. package/dist/types/content/transcript/types.d.ts +1 -0
  124. package/dist/types/content/url.d.ts +2 -3
  125. package/dist/types/prompts/format.d.ts +1 -0
  126. package/dist/types/prompts/link-summary.d.ts +2 -1
  127. package/dist/types/transcription/whisper/assemblyai.d.ts +17 -0
  128. package/dist/types/transcription/whisper/chunking.d.ts +11 -0
  129. package/dist/types/transcription/whisper/cloud-providers.d.ts +22 -0
  130. package/dist/types/transcription/whisper/core.d.ts +12 -14
  131. package/dist/types/transcription/whisper/gemini.d.ts +14 -0
  132. package/dist/types/transcription/whisper/preferences.d.ts +4 -0
  133. package/dist/types/transcription/whisper/provider-setup.d.ts +30 -0
  134. package/dist/types/transcription/whisper/remote-provider-attempts.d.ts +51 -0
  135. package/dist/types/transcription/whisper/remote.d.ts +51 -0
  136. package/dist/types/transcription/whisper/types.d.ts +1 -1
  137. package/dist/types/transcription/whisper/whisper-cpp.d.ts +4 -3
  138. package/package.json +14 -10
@@ -0,0 +1,173 @@
1
+ import { withBunCompressionHeaders } from "../../../bun.js";
2
+ import { fetchWithTimeout } from "../../../link-preview/fetch-with-timeout.js";
3
+ import { extractYoutubeiBootstrap } from "./api.js";
4
+ import { INNERTUBE_API_KEY_REGEX, REQUEST_HEADERS, YT_INITIAL_PLAYER_RESPONSE_TOKEN, isObjectLike, } from "./captions-shared.js";
5
+ function extractBalancedJsonObject(source, startAt) {
6
+ const start = source.indexOf("{", startAt);
7
+ if (start < 0) {
8
+ return null;
9
+ }
10
+ let depth = 0;
11
+ let inString = false;
12
+ let quote = null;
13
+ let escaping = false;
14
+ for (let i = start; i < source.length; i += 1) {
15
+ const ch = source[i];
16
+ if (!ch)
17
+ continue;
18
+ if (inString) {
19
+ if (escaping) {
20
+ escaping = false;
21
+ continue;
22
+ }
23
+ if (ch === "\\") {
24
+ escaping = true;
25
+ continue;
26
+ }
27
+ if (quote && ch === quote) {
28
+ inString = false;
29
+ quote = null;
30
+ }
31
+ continue;
32
+ }
33
+ if (ch === '"' || ch === "'") {
34
+ inString = true;
35
+ quote = ch;
36
+ continue;
37
+ }
38
+ if (ch === "{") {
39
+ depth += 1;
40
+ continue;
41
+ }
42
+ if (ch === "}") {
43
+ depth -= 1;
44
+ if (depth === 0) {
45
+ return source.slice(start, i + 1);
46
+ }
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ export function extractInitialPlayerResponse(html) {
52
+ const tokenIndex = html.indexOf(YT_INITIAL_PLAYER_RESPONSE_TOKEN);
53
+ if (tokenIndex < 0) {
54
+ return null;
55
+ }
56
+ const assignmentIndex = html.indexOf("=", tokenIndex);
57
+ if (assignmentIndex < 0) {
58
+ return null;
59
+ }
60
+ const objectText = extractBalancedJsonObject(html, assignmentIndex);
61
+ if (!objectText) {
62
+ return null;
63
+ }
64
+ try {
65
+ const parsed = JSON.parse(objectText);
66
+ return isObjectLike(parsed) ? parsed : null;
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ }
72
+ function coerceDurationSeconds(value) {
73
+ const asNumber = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
74
+ if (!Number.isFinite(asNumber) || asNumber <= 0)
75
+ return null;
76
+ return asNumber;
77
+ }
78
+ function extractDurationSecondsFromHtml(html) {
79
+ const candidates = [
80
+ /"lengthSeconds":"(\d+)"/,
81
+ /"lengthSeconds":(\d+)/,
82
+ /"durationSeconds":"(\d+)"/,
83
+ /"durationSeconds":(\d+)/,
84
+ ];
85
+ for (const pattern of candidates) {
86
+ const match = html.match(pattern);
87
+ if (!match?.[1])
88
+ continue;
89
+ const value = Number(match[1]);
90
+ if (Number.isFinite(value) && value > 0)
91
+ return value;
92
+ }
93
+ return null;
94
+ }
95
+ export function extractDurationSecondsFromPlayerPayload(payload) {
96
+ const videoDetails = payload.videoDetails;
97
+ if (isObjectLike(videoDetails)) {
98
+ const duration = coerceDurationSeconds(videoDetails.lengthSeconds);
99
+ if (duration)
100
+ return duration;
101
+ }
102
+ const microformat = payload.microformat;
103
+ if (isObjectLike(microformat)) {
104
+ const renderer = microformat.playerMicroformatRenderer;
105
+ if (isObjectLike(renderer)) {
106
+ const duration = coerceDurationSeconds(renderer.lengthSeconds);
107
+ if (duration)
108
+ return duration;
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ export function extractYoutubeDurationSeconds(html) {
114
+ const playerResponse = extractInitialPlayerResponse(html);
115
+ if (playerResponse) {
116
+ const duration = extractDurationSecondsFromPlayerPayload(playerResponse);
117
+ if (duration)
118
+ return duration;
119
+ }
120
+ return extractDurationSecondsFromHtml(html);
121
+ }
122
+ export function extractInnertubeApiKey(html) {
123
+ const match = html.match(INNERTUBE_API_KEY_REGEX);
124
+ const key = match?.[1] ?? match?.[2] ?? null;
125
+ return typeof key === "string" && key.trim().length > 0 ? key.trim() : null;
126
+ }
127
+ export async function fetchYoutubePlayerPayload(fetchImpl, { html, videoId }) {
128
+ const bootstrap = extractYoutubeiBootstrap(html);
129
+ const apiKey = bootstrap?.apiKey ?? extractInnertubeApiKey(html);
130
+ if (!apiKey)
131
+ return null;
132
+ const context = bootstrap?.context;
133
+ const clientContext = isObjectLike(context) && isObjectLike(context.client) ? context.client : null;
134
+ const requestBody = {
135
+ context: clientContext && isObjectLike(context)
136
+ ? context
137
+ : {
138
+ client: {
139
+ clientName: "ANDROID",
140
+ clientVersion: "20.10.38",
141
+ },
142
+ },
143
+ videoId,
144
+ };
145
+ try {
146
+ const userAgent = REQUEST_HEADERS["User-Agent"] ??
147
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36";
148
+ const response = await fetchWithTimeout(fetchImpl, `https://www.youtube.com/youtubei/v1/player?key=${apiKey}`, {
149
+ method: "POST",
150
+ headers: withBunCompressionHeaders({
151
+ "Content-Type": "application/json",
152
+ "User-Agent": userAgent,
153
+ "Accept-Language": REQUEST_HEADERS["Accept-Language"] ?? "en-US,en;q=0.9",
154
+ Accept: "application/json",
155
+ }),
156
+ body: JSON.stringify(requestBody),
157
+ });
158
+ if (!response.ok)
159
+ return null;
160
+ const parsed = await response.json();
161
+ return isObjectLike(parsed) ? parsed : null;
162
+ }
163
+ catch {
164
+ return null;
165
+ }
166
+ }
167
+ export async function fetchYoutubeDurationSecondsViaPlayer(fetchImpl, { html, videoId }) {
168
+ const payload = await fetchYoutubePlayerPayload(fetchImpl, { html, videoId });
169
+ if (!payload)
170
+ return null;
171
+ return extractDurationSecondsFromPlayerPayload(payload);
172
+ }
173
+ //# sourceMappingURL=captions-player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captions-player.js","sourceRoot":"","sources":["../../../../../../src/content/transcript/providers/youtube/captions-player.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export const REQUEST_HEADERS = {
2
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
3
+ "Accept-Language": "en-US,en;q=0.9",
4
+ };
5
+ export const YT_INITIAL_PLAYER_RESPONSE_TOKEN = "ytInitialPlayerResponse";
6
+ export const INNERTUBE_API_KEY_REGEX = /"INNERTUBE_API_KEY":"([^"]+)"|INNERTUBE_API_KEY\\":\\"([^\\"]+)\\"/;
7
+ export const isObjectLike = (value) => typeof value === "object" && value !== null;
8
+ //# sourceMappingURL=captions-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captions-shared.js","sourceRoot":"","sources":["../../../../../../src/content/transcript/providers/youtube/captions-shared.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,YAAY,EACV,iHAAiH;IACnH,iBAAiB,EAAE,gBAAgB;CACpC,CAAC;AAEF,MAAM,CAAC,MAAM,gCAAgC,GAAG,yBAAyB,CAAC;AAC1E,MAAM,CAAC,MAAM,uBAAuB,GAClC,oEAAoE,CAAC;AAEvE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAoC,EAAE,CAC/E,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC"}
@@ -0,0 +1,361 @@
1
+ import { withBunCompressionHeaders } from "../../../bun.js";
2
+ import { fetchWithTimeout } from "../../../link-preview/fetch-with-timeout.js";
3
+ import { parseTimestampToMs } from "../../timestamps.js";
4
+ import { decodeHtmlEntities, sanitizeYoutubeJsonResponse } from "../../utils.js";
5
+ import { extractYoutubeiBootstrap } from "./api.js";
6
+ import { extractInitialPlayerResponse, extractInnertubeApiKey } from "./captions-player.js";
7
+ import { REQUEST_HEADERS, isObjectLike, } from "./captions-shared.js";
8
+ async function fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated, }) {
9
+ const apiKey = extractInnertubeApiKey(html);
10
+ if (!apiKey) {
11
+ return null;
12
+ }
13
+ try {
14
+ const userAgent = REQUEST_HEADERS["User-Agent"] ??
15
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36";
16
+ const response = await fetchWithTimeout(fetchImpl, `https://www.youtube.com/youtubei/v1/player?key=${apiKey}`, {
17
+ method: "POST",
18
+ headers: withBunCompressionHeaders({
19
+ "Content-Type": "application/json",
20
+ "User-Agent": userAgent,
21
+ "Accept-Language": REQUEST_HEADERS["Accept-Language"] ?? "en-US,en;q=0.9",
22
+ Accept: "application/json",
23
+ }),
24
+ body: JSON.stringify({
25
+ context: {
26
+ client: {
27
+ clientName: "ANDROID",
28
+ clientVersion: "20.10.38",
29
+ },
30
+ },
31
+ videoId,
32
+ }),
33
+ });
34
+ if (!response.ok) {
35
+ return null;
36
+ }
37
+ const parsed = await response.json();
38
+ if (!isObjectLike(parsed)) {
39
+ return null;
40
+ }
41
+ return await extractTranscriptFromPlayerPayload(fetchImpl, parsed, skipAutoGenerated);
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ export const fetchTranscriptFromCaptionTracks = async (fetchImpl, { html, originalUrl, videoId, skipAutoGenerated, }) => {
48
+ const initialPlayerResponse = extractInitialPlayerResponse(html);
49
+ if (initialPlayerResponse) {
50
+ const transcript = await extractTranscriptFromPlayerPayload(fetchImpl, initialPlayerResponse, skipAutoGenerated);
51
+ if (transcript) {
52
+ return transcript;
53
+ }
54
+ }
55
+ const bootstrap = extractYoutubeiBootstrap(html);
56
+ if (!bootstrap) {
57
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
58
+ }
59
+ const { apiKey, clientName, clientVersion, context, pageCl, pageLabel, visitorData, xsrfToken } = bootstrap;
60
+ if (!apiKey) {
61
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
62
+ }
63
+ const contextRecord = context;
64
+ const clientContext = isObjectLike(contextRecord.client)
65
+ ? contextRecord.client
66
+ : {};
67
+ const requestBody = {
68
+ context: {
69
+ ...contextRecord,
70
+ client: {
71
+ ...clientContext,
72
+ originalUrl,
73
+ },
74
+ },
75
+ videoId,
76
+ playbackContext: {
77
+ contentPlaybackContext: {
78
+ html5Preference: "HTML5_PREF_WANTS",
79
+ },
80
+ },
81
+ contentCheckOk: true,
82
+ racyCheckOk: true,
83
+ };
84
+ try {
85
+ const userAgent = REQUEST_HEADERS["User-Agent"] ??
86
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36";
87
+ const headers = withBunCompressionHeaders({
88
+ "Content-Type": "application/json",
89
+ "User-Agent": userAgent,
90
+ Accept: "application/json",
91
+ Origin: "https://www.youtube.com",
92
+ Referer: originalUrl,
93
+ "X-Goog-AuthUser": "0",
94
+ "X-Youtube-Bootstrap-Logged-In": "false",
95
+ });
96
+ if (clientName)
97
+ headers["X-Youtube-Client-Name"] = clientName;
98
+ if (clientVersion)
99
+ headers["X-Youtube-Client-Version"] = clientVersion;
100
+ if (visitorData)
101
+ headers["X-Goog-Visitor-Id"] = visitorData;
102
+ if (typeof pageCl === "number" && Number.isFinite(pageCl)) {
103
+ headers["X-Youtube-Page-CL"] = String(pageCl);
104
+ }
105
+ if (pageLabel)
106
+ headers["X-Youtube-Page-Label"] = pageLabel;
107
+ if (xsrfToken)
108
+ headers["X-Youtube-Identity-Token"] = xsrfToken;
109
+ const response = await fetchWithTimeout(fetchImpl, `https://www.youtube.com/youtubei/v1/player?key=${apiKey}`, {
110
+ method: "POST",
111
+ headers,
112
+ body: JSON.stringify(requestBody),
113
+ });
114
+ if (!response.ok) {
115
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
116
+ }
117
+ const raw = await response.text();
118
+ const sanitized = sanitizeYoutubeJsonResponse(raw);
119
+ const parsed = JSON.parse(sanitized);
120
+ if (!isObjectLike(parsed)) {
121
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
122
+ }
123
+ const transcript = await extractTranscriptFromPlayerPayload(fetchImpl, parsed, skipAutoGenerated);
124
+ if (transcript) {
125
+ return transcript;
126
+ }
127
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
128
+ }
129
+ catch {
130
+ return await fetchTranscriptViaAndroidPlayer(fetchImpl, { html, videoId, skipAutoGenerated });
131
+ }
132
+ };
133
+ const extractTranscriptFromPlayerPayload = async (fetchImpl, payload, skipAutoGenerated) => {
134
+ const payloadRecord = payload;
135
+ const captionsCandidate = payloadRecord.captions;
136
+ const captions = isObjectLike(captionsCandidate) ? captionsCandidate : null;
137
+ const rendererCandidate = (captions ? captions.playerCaptionsTracklistRenderer : null) ??
138
+ payloadRecord.playerCaptionsTracklistRenderer;
139
+ const renderer = isObjectLike(rendererCandidate)
140
+ ? rendererCandidate
141
+ : null;
142
+ const captionTracks = Array.isArray(renderer?.captionTracks)
143
+ ? renderer?.captionTracks
144
+ : null;
145
+ const automaticTracks = Array.isArray(renderer?.automaticCaptions)
146
+ ? renderer?.automaticCaptions
147
+ : null;
148
+ const orderedTracks = [];
149
+ if (captionTracks) {
150
+ orderedTracks.push(...captionTracks.filter((track) => isObjectLike(track)));
151
+ }
152
+ if (!skipAutoGenerated && automaticTracks) {
153
+ orderedTracks.push(...automaticTracks.filter((track) => isObjectLike(track)));
154
+ }
155
+ const sortedTracks = [...orderedTracks].toSorted((a, b) => {
156
+ const aTrack = a;
157
+ const bTrack = b;
158
+ const aKind = typeof aTrack.kind === "string" ? aTrack.kind : "";
159
+ const bKind = typeof bTrack.kind === "string" ? bTrack.kind : "";
160
+ if (aKind === "asr" && bKind !== "asr")
161
+ return 1;
162
+ if (bKind === "asr" && aKind !== "asr")
163
+ return -1;
164
+ const aLang = typeof aTrack.languageCode === "string" ? aTrack.languageCode : "";
165
+ const bLang = typeof bTrack.languageCode === "string" ? bTrack.languageCode : "";
166
+ const aIsEnglish = aLang === "en" || aLang.startsWith("en-");
167
+ const bIsEnglish = bLang === "en" || bLang.startsWith("en-");
168
+ if (aIsEnglish && !bIsEnglish)
169
+ return -1;
170
+ if (bIsEnglish && !aIsEnglish)
171
+ return 1;
172
+ return 0;
173
+ });
174
+ const seenLanguages = new Set();
175
+ const normalizedTracks = [];
176
+ for (const candidate of sortedTracks) {
177
+ const trackRecord = candidate;
178
+ const languageCandidate = trackRecord.languageCode;
179
+ const lang = typeof languageCandidate === "string" ? languageCandidate.toLowerCase() : "";
180
+ if (lang && seenLanguages.has(lang)) {
181
+ continue;
182
+ }
183
+ if (lang) {
184
+ seenLanguages.add(lang);
185
+ }
186
+ normalizedTracks.push(candidate);
187
+ }
188
+ const tracksToUse = skipAutoGenerated
189
+ ? normalizedTracks.filter((track) => {
190
+ const t = track;
191
+ return t.kind !== "asr";
192
+ })
193
+ : normalizedTracks;
194
+ if (tracksToUse.length === 0) {
195
+ return null;
196
+ }
197
+ return await findFirstTranscript(fetchImpl, tracksToUse, 0);
198
+ };
199
+ const findFirstTranscript = async (fetchImpl, tracks, index) => {
200
+ if (index >= tracks.length) {
201
+ return null;
202
+ }
203
+ const candidate = await downloadCaptionTrack(fetchImpl, tracks[index] ?? {});
204
+ if (candidate) {
205
+ return candidate;
206
+ }
207
+ return findFirstTranscript(fetchImpl, tracks, index + 1);
208
+ };
209
+ const downloadCaptionTrack = async (fetchImpl, track) => {
210
+ const trackRecord = track;
211
+ const baseUrl = typeof trackRecord.baseUrl === "string"
212
+ ? trackRecord.baseUrl
213
+ : typeof trackRecord.url === "string"
214
+ ? trackRecord.url
215
+ : null;
216
+ if (!baseUrl) {
217
+ return null;
218
+ }
219
+ const json3Url = (() => {
220
+ try {
221
+ const parsed = new URL(baseUrl);
222
+ parsed.searchParams.set("fmt", "json3");
223
+ parsed.searchParams.set("alt", "json");
224
+ return parsed.toString();
225
+ }
226
+ catch {
227
+ const separator = baseUrl.includes("?") ? "&" : "?";
228
+ return `${baseUrl}${separator}fmt=json3&alt=json`;
229
+ }
230
+ })();
231
+ try {
232
+ const response = await fetchWithTimeout(fetchImpl, json3Url, {
233
+ headers: REQUEST_HEADERS,
234
+ });
235
+ if (!response.ok) {
236
+ return await downloadXmlTranscript(fetchImpl, baseUrl);
237
+ }
238
+ const text = await response.text();
239
+ if (text.length === 0) {
240
+ return await downloadXmlTranscript(fetchImpl, baseUrl);
241
+ }
242
+ const jsonResult = parseJsonTranscript(text);
243
+ if (jsonResult)
244
+ return jsonResult;
245
+ const xmlFallback = parseXmlTranscript(text);
246
+ if (xmlFallback)
247
+ return xmlFallback;
248
+ return await downloadXmlTranscript(fetchImpl, baseUrl);
249
+ }
250
+ catch {
251
+ return await downloadXmlTranscript(fetchImpl, baseUrl);
252
+ }
253
+ };
254
+ const downloadXmlTranscript = async (fetchImpl, baseUrl) => {
255
+ const xmlUrl = baseUrl.replaceAll(/&fmt=[^&]+/g, "");
256
+ try {
257
+ const response = await fetchWithTimeout(fetchImpl, xmlUrl, { headers: REQUEST_HEADERS });
258
+ if (!response.ok) {
259
+ return null;
260
+ }
261
+ const text = await response.text();
262
+ const jsonResult = parseJsonTranscript(text);
263
+ if (jsonResult) {
264
+ return jsonResult;
265
+ }
266
+ return parseXmlTranscript(text);
267
+ }
268
+ catch {
269
+ return null;
270
+ }
271
+ };
272
+ const parseJsonTranscript = (raw) => {
273
+ try {
274
+ const parsed = JSON.parse(raw);
275
+ if (!isObjectLike(parsed)) {
276
+ return null;
277
+ }
278
+ const payloadRecord = parsed;
279
+ const eventsUnknown = payloadRecord.events;
280
+ if (!Array.isArray(eventsUnknown)) {
281
+ return null;
282
+ }
283
+ const lines = [];
284
+ const segments = [];
285
+ for (const event of eventsUnknown) {
286
+ if (!isObjectLike(event))
287
+ continue;
288
+ const eventRecord = event;
289
+ const segs = Array.isArray(eventRecord.segs) ? eventRecord.segs : null;
290
+ if (!segs)
291
+ continue;
292
+ const text = segs
293
+ .map((seg) => {
294
+ if (!isObjectLike(seg))
295
+ return "";
296
+ const segRecord = seg;
297
+ return typeof segRecord.utf8 === "string" ? segRecord.utf8 : "";
298
+ })
299
+ .join("")
300
+ .trim();
301
+ if (text.length > 0) {
302
+ lines.push(text);
303
+ const startMs = parseTimestampToMs(eventRecord.tStartMs, false);
304
+ const durationMs = parseTimestampToMs(eventRecord.dDurationMs, false);
305
+ if (startMs != null) {
306
+ segments.push({
307
+ startMs,
308
+ endMs: durationMs != null ? startMs + durationMs : null,
309
+ text: text.replace(/\s+/g, " ").trim(),
310
+ });
311
+ }
312
+ }
313
+ }
314
+ const transcript = lines.join("\n").trim();
315
+ if (transcript.length === 0) {
316
+ return null;
317
+ }
318
+ return {
319
+ text: transcript,
320
+ segments: segments.length > 0 ? segments : null,
321
+ };
322
+ }
323
+ catch {
324
+ return null;
325
+ }
326
+ };
327
+ const parseXmlTranscript = (xml) => {
328
+ const pattern = /<text[^>]*>([\s\S]*?)<\/text>/gi;
329
+ const lines = [];
330
+ const segments = [];
331
+ let match = pattern.exec(xml);
332
+ while (match) {
333
+ const content = match[1] ?? "";
334
+ const decoded = decodeHtmlEntities(content).replaceAll(/\s+/g, " ").trim();
335
+ if (decoded.length > 0) {
336
+ lines.push(decoded);
337
+ const tag = match[0] ?? "";
338
+ const startMatch = tag.match(/\bstart\s*=\s*(['"])([^'"]+)\1/i);
339
+ const durMatch = tag.match(/\bdur\s*=\s*(['"])([^'"]+)\1/i);
340
+ const startMs = startMatch?.[2] ? parseTimestampToMs(startMatch[2], true) : null;
341
+ const durationMs = durMatch?.[2] ? parseTimestampToMs(durMatch[2], true) : null;
342
+ if (startMs != null) {
343
+ segments.push({
344
+ startMs,
345
+ endMs: durationMs != null ? startMs + durationMs : null,
346
+ text: decoded.replace(/\s+/g, " ").trim(),
347
+ });
348
+ }
349
+ }
350
+ match = pattern.exec(xml);
351
+ }
352
+ const transcript = lines.join("\n").trim();
353
+ if (transcript.length === 0) {
354
+ return null;
355
+ }
356
+ return {
357
+ text: transcript,
358
+ segments: segments.length > 0 ? segments : null,
359
+ };
360
+ };
361
+ //# sourceMappingURL=captions-transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captions-transcript.js","sourceRoot":"","sources":["../../../../../../src/content/transcript/providers/youtube/captions-transcript.ts"],"names":[],"mappings":"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"}