summd 0.1.6 → 0.1.7

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 (2) hide show
  1. package/dist/url-to-md.js +40 -33
  2. package/package.json +1 -1
package/dist/url-to-md.js CHANGED
@@ -78,54 +78,61 @@ async function fetchYouTubeTitle(url, videoId) {
78
78
  catch { }
79
79
  return `YouTube: ${videoId}`;
80
80
  }
81
- // Subtitle language priority: English first, then common languages, then anything available.
82
- // yt-dlp picks the first match; --write-auto-subs covers ASR variants (en-orig etc.)
83
- const SUB_LANGS = 'en,zh-Hans,zh-Hant,zh,ja,ko,fr,de,es,pt,ru';
84
- // yt-dlp — works from any IP, supports auth/geo-block via --cookies-from-browser
81
+ // Browser cookie sources tried in order, first one that succeeds is used.
82
+ // Cookies bypass bot-detection and geo-blocks; required on most IPs.
83
+ const BROWSERS = ['chrome', 'chromium', 'firefox', 'safari', 'edge'];
84
+ // yt-dlp — uses browser cookies by default; falls back to no-cookies for public videos.
85
+ // --sub-langs all: accept whatever subtitle language the video provides, no preference.
85
86
  async function ytDlpTranscript(url, videoId) {
86
87
  const dir = tmpdir();
87
88
  const outTemplate = join(dir, videoId);
88
- const run = (...extra) => execFileAsync('yt-dlp', [
89
+ const run = (cookieArgs) => execFileAsync('yt-dlp', [
89
90
  '--write-subs',
90
91
  '--write-auto-subs',
91
- '--sub-langs', SUB_LANGS,
92
+ '--sub-langs', 'all', // accept any language — no hardcoded preference
92
93
  '--sub-format', 'json3',
93
94
  '--skip-download',
94
95
  '--quiet',
95
96
  '--no-progress',
96
- ...extra,
97
+ ...cookieArgs,
97
98
  '-o', outTemplate,
98
99
  url,
99
100
  ], { timeout: 30_000 });
100
- try {
101
- await run();
101
+ // Try with browser cookies first (handles bot-detection, auth, geo-block).
102
+ // Fall back to no-cookies only if no browser is available.
103
+ let ran = false;
104
+ for (const browser of BROWSERS) {
105
+ try {
106
+ await run(['--cookies-from-browser', browser]);
107
+ ran = true;
108
+ break;
109
+ }
110
+ catch (e) {
111
+ const err = e;
112
+ if (err.code === 'ENOENT')
113
+ return { transcript: null, reason: 'not-installed' };
114
+ const stderr = err.stderr ?? '';
115
+ // Cookie access failed (browser not installed / locked DB) — try next browser
116
+ if (stderr.includes('browser') || stderr.includes('cookie') || stderr.includes('Could not find'))
117
+ continue;
118
+ // yt-dlp ran but failed for another reason (video unavailable, no captions…)
119
+ ran = true;
120
+ break;
121
+ }
102
122
  }
103
- catch (e) {
104
- const err = e;
105
- if (err.code === 'ENOENT')
106
- return { transcript: null, reason: 'not-installed' };
107
- // YouTube bot-detection: retry with browser cookies
108
- // Triggered when running from cloud/residential IPs without a session
109
- const stderr = err.stderr ?? '';
110
- if (stderr.includes('Sign in') || stderr.includes('bot')) {
111
- const browsers = ['chrome', 'chromium', 'firefox', 'safari', 'edge'];
112
- let authed = false;
113
- for (const browser of browsers) {
114
- try {
115
- await run('--cookies-from-browser', browser);
116
- authed = true;
117
- break;
118
- }
119
- catch {
120
- continue;
121
- }
122
- }
123
- if (!authed)
124
- return { transcript: null, reason: 'no-transcript' };
123
+ // No browser found with usable cookies — try without (works for fully public videos)
124
+ if (!ran) {
125
+ try {
126
+ await run([]);
127
+ }
128
+ catch (e) {
129
+ const err = e;
130
+ if (err.code === 'ENOENT')
131
+ return { transcript: null, reason: 'not-installed' };
132
+ return { transcript: null, reason: 'no-transcript' };
125
133
  }
126
- // Other errors (geo-block, video unavailable): fall through to file check
127
134
  }
128
- // Find output file: {videoId}.en.json3, {videoId}.zh-Hans.json3, etc.
135
+ // Read the first valid output file; clean up all temp files regardless
129
136
  try {
130
137
  const files = readdirSync(dir).filter(f => f.startsWith(videoId) && f.endsWith('.json3'));
131
138
  for (const file of files) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "summd",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "CLI for sum.md — Sum to anything.",
5
5
  "license": "MIT",
6
6
  "bin": {