@echovisionlab/youtube-audio 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -15
- package/dist/memory-store.d.ts +4 -1
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/memory-store.js +33 -2
- package/dist/memory-store.js.map +1 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +40 -14
- package/dist/service.js.map +1 -1
- package/dist/youtube-js.d.ts +2 -0
- package/dist/youtube-js.d.ts.map +1 -1
- package/dist/youtube-js.js +131 -25
- package/dist/youtube-js.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,28 +23,32 @@ const service = createYoutubeAudioService({
|
|
|
23
23
|
});
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
This package is dual-use software, not a public download service. Access must
|
|
29
|
-
be restricted to signed-in users. Use it only for media you own or are
|
|
30
|
-
authorized to acquire and process, and obtain all required copyright and rights
|
|
31
|
-
clearances. Echo Vision Lab does not encourage infringement or unauthorized
|
|
32
|
-
copying. See [DISCLOSURE.md](DISCLOSURE.md).
|
|
33
|
-
|
|
34
|
-
YouTube and its private APIs can change independently. Keep failures observable
|
|
35
|
-
and review YouTube's terms and applicable law for your integration.
|
|
26
|
+
See [DISCLOSURE.md](DISCLOSURE.md) for access and use conditions.
|
|
36
27
|
|
|
37
28
|
`createYoutubeJsAudioProvider()` is exported separately so browser bundles do
|
|
38
29
|
not accidentally pull the unofficial InnerTube client into application code.
|
|
39
30
|
It rejects live/upcoming video and any source without a finite audio-only byte
|
|
40
|
-
length. The adapter
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
length. The adapter tries the `VISIONOS` and `YTKIDS` YouTube.js clients in
|
|
32
|
+
order, accepting a source only after exact one-byte reads succeed at the
|
|
33
|
+
beginning, middle, and end of the file. This keeps source preparation bounded
|
|
34
|
+
for long public videos while rejecting URLs that resolve but later fail random
|
|
35
|
+
access. Callers may override `client` when required. YouTube.js and the upstream
|
|
36
|
+
private API can change independently; keep
|
|
45
37
|
resolution failures observable and update this package rather than adding
|
|
46
38
|
fallback scraping to the web application.
|
|
47
39
|
|
|
40
|
+
Each caller's wait for YouTube.js client creation, video metadata, and URL
|
|
41
|
+
deciphering ends promptly when its `AbortSignal` is aborted; shared client
|
|
42
|
+
creation continues for other callers. The pinned YouTube.js APIs do not accept
|
|
43
|
+
an abort signal for `Innertube.create()`, `getBasicInfo()`, or `decipher()`, so
|
|
44
|
+
aborting a caller does not stop the underlying library work.
|
|
45
|
+
|
|
46
|
+
The exported `createMemoryYoutubeAudioSourceStore()` is process-local. It prunes
|
|
47
|
+
expired records during put, get, and delete operations; inject `now` when a
|
|
48
|
+
deterministic clock is needed. It does not evict unexpired records, so use a
|
|
49
|
+
shared store with an explicit capacity policy for long-lived multi-process
|
|
50
|
+
services.
|
|
51
|
+
|
|
48
52
|
## Development
|
|
49
53
|
|
|
50
54
|
```sh
|
package/dist/memory-store.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { YoutubeAudioSourceStore } from './contracts.js';
|
|
2
|
-
export
|
|
2
|
+
export interface CreateMemoryYoutubeAudioSourceStoreOptions {
|
|
3
|
+
readonly now?: () => number;
|
|
4
|
+
}
|
|
5
|
+
export declare function createMemoryYoutubeAudioSourceStore(options?: CreateMemoryYoutubeAudioSourceStoreOptions): YoutubeAudioSourceStore;
|
|
3
6
|
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,gBAAgB,CAAC;AAExB,wBAAgB,mCAAmC,
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,0CAA0C;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,wBAAgB,mCAAmC,CACjD,OAAO,GAAE,0CAA+C,GACvD,uBAAuB,CA4CzB"}
|
package/dist/memory-store.js
CHANGED
|
@@ -1,15 +1,46 @@
|
|
|
1
|
-
export function createMemoryYoutubeAudioSourceStore() {
|
|
1
|
+
export function createMemoryYoutubeAudioSourceStore(options = {}) {
|
|
2
2
|
const sources = new Map();
|
|
3
|
+
const now = options.now ?? Date.now;
|
|
4
|
+
let earliestExpiry = Number.POSITIVE_INFINITY;
|
|
3
5
|
return {
|
|
4
6
|
async delete(id) {
|
|
7
|
+
pruneExpired();
|
|
5
8
|
sources.delete(id);
|
|
6
9
|
},
|
|
7
10
|
async get(id) {
|
|
8
|
-
|
|
11
|
+
// Preserve the store contract: callers can still distinguish an expired
|
|
12
|
+
// record from a missing one, while pruning it from the backing map.
|
|
13
|
+
const source = sources.get(id) ?? null;
|
|
14
|
+
pruneExpired();
|
|
15
|
+
return source;
|
|
9
16
|
},
|
|
10
17
|
async put(source) {
|
|
18
|
+
const currentTime = now();
|
|
19
|
+
pruneExpired(currentTime);
|
|
20
|
+
const expiresAt = source.expiresAt;
|
|
21
|
+
if (expiresAt <= currentTime) {
|
|
22
|
+
sources.delete(source.id);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
11
25
|
sources.set(source.id, source);
|
|
26
|
+
earliestExpiry = Math.min(earliestExpiry, expiresAt);
|
|
12
27
|
},
|
|
13
28
|
};
|
|
29
|
+
function pruneExpired(currentTime = now()) {
|
|
30
|
+
if (currentTime < earliestExpiry) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let nextExpiry = Number.POSITIVE_INFINITY;
|
|
34
|
+
for (const [id, source] of sources) {
|
|
35
|
+
const expiresAt = source.expiresAt;
|
|
36
|
+
if (expiresAt <= currentTime) {
|
|
37
|
+
sources.delete(id);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
nextExpiry = Math.min(nextExpiry, expiresAt);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
earliestExpiry = nextExpiry;
|
|
44
|
+
}
|
|
14
45
|
}
|
|
15
46
|
//# sourceMappingURL=memory-store.js.map
|
package/dist/memory-store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../src/memory-store.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,mCAAmC,CACjD,OAAO,GAA+C,EAAE;IAExD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoC,CAAC;IAC5D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,IAAI,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAC9C,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,EAAE;YACb,YAAY,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE;YACV,wEAAwE;YACxE,oEAAoE;YACpE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;YACvC,YAAY,EAAE,CAAC;YACf,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAM;YACd,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;YAC1B,YAAY,CAAC,WAAW,CAAC,CAAC;YAC1B,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;YACnC,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;gBAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/B,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;QACvD,CAAC;KACF,CAAC;IAEF,SAAS,YAAY,CAAC,WAAW,GAAG,GAAG,EAAE;QACvC,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,UAAU,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAC1C,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;YACnC,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;gBAC7B,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QACD,cAAc,GAAG,UAAU,CAAC;IAC9B,CAAC;AACH,CAAC"}
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gCAAgC,EAKhC,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAQxB,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gCAAgC,EAKhC,mBAAmB,EAGpB,MAAM,gBAAgB,CAAC;AAQxB,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,mBAAmB,CAkJrB"}
|
package/dist/service.js
CHANGED
|
@@ -47,6 +47,15 @@ export function createYoutubeAudioService(options) {
|
|
|
47
47
|
upstream: freezeUpstream(upstream),
|
|
48
48
|
});
|
|
49
49
|
await options.sourceStore.put(record);
|
|
50
|
+
if (request.signal?.aborted) {
|
|
51
|
+
try {
|
|
52
|
+
await options.sourceStore.delete(sourceId);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Cleanup is best-effort; cancellation remains the primary outcome.
|
|
56
|
+
}
|
|
57
|
+
throw new YoutubeAudioError('REQUEST_ABORTED', 'The audio request was aborted.');
|
|
58
|
+
}
|
|
50
59
|
return Object.freeze({
|
|
51
60
|
contentType: upstream.contentType,
|
|
52
61
|
expiresAt,
|
|
@@ -94,21 +103,27 @@ export function createYoutubeAudioService(options) {
|
|
|
94
103
|
throwIfAborted(request.signal);
|
|
95
104
|
throw new YoutubeAudioError('UPSTREAM_FAILURE', 'The upstream audio range request failed.');
|
|
96
105
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
try {
|
|
107
|
+
throwIfAborted(request.signal);
|
|
108
|
+
validateUpstreamRangeResponse(response, range, record.upstream.size);
|
|
109
|
+
if (response.body === null) {
|
|
110
|
+
throw new YoutubeAudioError('INVALID_UPSTREAM_RESPONSE', 'The upstream audio response has no body.');
|
|
111
|
+
}
|
|
112
|
+
return new Response(response.body, {
|
|
113
|
+
headers: {
|
|
114
|
+
'Accept-Ranges': 'bytes',
|
|
115
|
+
'Cache-Control': 'private, no-store',
|
|
116
|
+
'Content-Length': String(range.end - range.start + 1),
|
|
117
|
+
'Content-Range': `bytes ${range.start}-${range.end}/${record.upstream.size}`,
|
|
118
|
+
'Content-Type': record.upstream.contentType,
|
|
119
|
+
},
|
|
120
|
+
status: 206,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
await cancelResponseBody(response);
|
|
125
|
+
throw error;
|
|
101
126
|
}
|
|
102
|
-
return new Response(response.body, {
|
|
103
|
-
headers: {
|
|
104
|
-
'Accept-Ranges': 'bytes',
|
|
105
|
-
'Cache-Control': 'private, no-store',
|
|
106
|
-
'Content-Length': String(range.end - range.start + 1),
|
|
107
|
-
'Content-Range': `bytes ${range.start}-${range.end}/${record.upstream.size}`,
|
|
108
|
-
'Content-Type': record.upstream.contentType,
|
|
109
|
-
},
|
|
110
|
-
status: 206,
|
|
111
|
-
});
|
|
112
127
|
}
|
|
113
128
|
async function revokeSource(request) {
|
|
114
129
|
const subject = validateSubject(request.subject);
|
|
@@ -123,6 +138,17 @@ export function createYoutubeAudioService(options) {
|
|
|
123
138
|
await options.sourceStore.delete(sourceId);
|
|
124
139
|
}
|
|
125
140
|
}
|
|
141
|
+
async function cancelResponseBody(response) {
|
|
142
|
+
if (response.body === null) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
await response.body.cancel();
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Preserve the post-fetch validation or cancellation error.
|
|
150
|
+
}
|
|
151
|
+
}
|
|
126
152
|
function parseClosedRange(value, size) {
|
|
127
153
|
const match = /^bytes=(\d+)-(\d+)$/.exec(value);
|
|
128
154
|
if (match === null) {
|
package/dist/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAWzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAC9C,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAC1C,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,UAAU,yBAAyB,CACvC,OAAyC;IAEzC,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,UAAU,CAAC;IAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IAE3C,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO;YAChB,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;IAEF,KAAK,UAAU,aAAa,CAC1B,OAAmC;QAEnC,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,QAAoC,CAAC;QACzC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;QACD,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAEvD,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;QACzC,MAAM,SAAS,GACb,QAAQ,CAAC,SAAS,KAAK,IAAI;YACzB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,GAA6B,MAAM,CAAC,MAAM,CAAC;YACrD,SAAS;YACT,EAAE,EAAE,QAAQ;YACZ,OAAO;YACP,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAWzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAC9C,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAC1C,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,MAAM,UAAU,yBAAyB,CACvC,OAAyC;IAEzC,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,qBAAqB,CAAC,CAAC;IAC9E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,UAAU,CAAC;IAC5D,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IAE3C,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO;YAChB,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;IAEF,KAAK,UAAU,aAAa,CAC1B,OAAmC;QAEnC,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,QAAoC,CAAC;QACzC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC;QACD,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAEvD,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;QACzC,MAAM,SAAS,GACb,QAAQ,CAAC,SAAS,KAAK,IAAI;YACzB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrE,MAAM,MAAM,GAA6B,MAAM,CAAC,MAAM,CAAC;YACrD,SAAS;YACT,EAAE,EAAE,QAAQ;YACZ,OAAO;YACP,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACP,oEAAoE;YACtE,CAAC;YACD,MAAM,IAAI,iBAAiB,CAAC,iBAAiB,EAAE,gCAAgC,CAAC,CAAC;QACnF,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,SAAS;YACT,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC;oBAClB,WAAW,EAAE,SAAkB;oBAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,GAAG,EAAE,SAAS;iBACf,CAAC;gBACF,IAAI,EAAE,QAAQ,CAAC,QAAQ;aACxB,CAAC;YACF,QAAQ;YACR,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,OAAgC;QACxD,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpD,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,EAAE,6BAA6B,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,iBAAiB,CAAC,cAAc,EAAE,gCAAgC,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,IAAI,GAAG,EAAE,EAAE,CAAC;YAC9B,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,IAAI,iBAAiB,CAAC,gBAAgB,EAAE,2BAA2B,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACrE,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAChD,KAAK,EAAE,UAAU;gBACjB,OAAO;gBACP,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,QAAQ;gBAClB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;aACpE,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,IAAI,iBAAiB,CACzB,kBAAkB,EAClB,0CAA0C,CAC3C,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/B,6BAA6B,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrE,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC3B,MAAM,IAAI,iBAAiB,CACzB,2BAA2B,EAC3B,0CAA0C,CAC3C,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE;gBACjC,OAAO,EAAE;oBACP,eAAe,EAAE,OAAO;oBACxB,eAAe,EAAE,mBAAmB;oBACpC,gBAAgB,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;oBACrD,eAAe,EAAE,SAAS,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;oBAC5E,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW;iBAC5C;gBACD,MAAM,EAAE,GAAG;aACZ,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,UAAU,YAAY,CACzB,OAAkC;QAElC,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC/B,MAAM,IAAI,iBAAiB,CAAC,cAAc,EAAE,gCAAgC,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,QAAkB;IAClD,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,4DAA4D;IAC9D,CAAC;AACH,CAAC;AAQD,SAAS,gBAAgB,CAAC,KAAa,EAAE,IAAY;IACnD,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,yCAAyC,CAC1C,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC;QAC5B,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC;QAC1B,KAAK,GAAG,CAAC;QACT,GAAG,GAAG,KAAK;QACX,GAAG,IAAI,IAAI,EACX,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,uDAAuD,CACxD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,6BAA6B,CACpC,QAAkB,EAClB,KAAkB,EAClB,IAAY;IAEZ,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,iBAAiB,CACzB,kBAAkB,EAClB,oDAAoD,QAAQ,CAAC,MAAM,GAAG,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,SAAS,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7D,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,QAAQ,EAAE,CAAC;QAClF,MAAM,IAAI,iBAAiB,CACzB,2BAA2B,EAC3B,+DAA+D,CAChE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAkC,EAClC,KAAa;IAEb,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,iBAAiB,CACzB,2BAA2B,EAC3B,iDAAiD,CAClD,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,iBAAiB,CACzB,2BAA2B,EAC3B,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAAkC,EAClC,eAAuB,EACvB,GAAW;IAEX,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,eAAe,EAAE,CAAC;IAC1B,CAAC;IACD,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;QACzB,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,MAAM,CAAC,OAAO,KAAK,eAAe;QAClC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,IAAI,GAAG,CAAC;QACf,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC;QAC/B,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5B,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC;QACzB,CAAC,MAAM,CAAC,SAAS,KAAK,IAAI;YACxB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC,EACvE,CAAC;QACD,MAAM,eAAe,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,MAAkC;IAElC,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,MAAM;QACT,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS;YAC9B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAC5D,MAAM,IAAI,iBAAiB,CACzB,cAAc,EACd,uCAAuC,CACxC,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,iBAAiB,CAAC,iBAAiB,EAAE,6BAA6B,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,IACE,CAAC,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;QACvD,GAAG,CAAC,QAAQ,KAAK,EAAE;QACnB,GAAG,CAAC,QAAQ,KAAK,EAAE,EACnB,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,oDAAoD,CACrD,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAC/E,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,+CAA+C,iBAAiB,GAAG,CACpE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB;IAC1C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,iBAAiB,CAAC,iBAAiB,EAAE,gCAAgC,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc,EAAE,MAAoB;IAChE,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;QACvC,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,iBAAiB,CACzB,kBAAkB,EAClB,kCAAkC,CACnC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,iBAAiB,CAC1B,2BAA2B,EAC3B,+CAA+C,CAChD,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/youtube-js.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export interface CreateYoutubeJsAudioProviderOptions {
|
|
|
7
7
|
readonly innertubeConfig?: Types.InnerTubeConfig;
|
|
8
8
|
/** Optional YouTube client override. */
|
|
9
9
|
readonly client?: Types.InnerTubeClient;
|
|
10
|
+
/** Test seam for validating random-access media reads. */
|
|
11
|
+
readonly fetcher?: typeof fetch;
|
|
10
12
|
/** Optional container preference such as `m4a` or `webm`. */
|
|
11
13
|
readonly format?: string;
|
|
12
14
|
}
|
package/dist/youtube-js.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"youtube-js.d.ts","sourceRoot":"","sources":["../src/youtube-js.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"youtube-js.d.ts","sourceRoot":"","sources":["../src/youtube-js.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,mCAAmC;IAClD,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC;IACjD,wCAAwC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAOD,wBAAgB,4BAA4B,CAC1C,OAAO,GAAE,mCAAwC,GAChD,oBAAoB,CA8EtB"}
|
package/dist/youtube-js.js
CHANGED
|
@@ -1,43 +1,111 @@
|
|
|
1
|
-
import { Innertube } from 'youtubei.js';
|
|
1
|
+
import { Innertube, Platform } from 'youtubei.js';
|
|
2
2
|
import { YoutubeAudioError } from './errors.js';
|
|
3
|
+
const DEFAULT_CLIENT_TYPES = [
|
|
4
|
+
'VISIONOS',
|
|
5
|
+
'YTKIDS',
|
|
6
|
+
];
|
|
3
7
|
export function createYoutubeJsAudioProvider(options = {}) {
|
|
4
8
|
let clientPromise;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
+
const clientTypes = options.client === undefined
|
|
10
|
+
? DEFAULT_CLIENT_TYPES
|
|
11
|
+
: [options.client];
|
|
12
|
+
const fetcher = options.fetcher ?? fetch;
|
|
9
13
|
return {
|
|
10
14
|
async resolve(video, signal) {
|
|
11
15
|
throwIfAborted(signal);
|
|
12
|
-
|
|
13
|
-
throwIfAborted(signal);
|
|
16
|
+
let innertube;
|
|
14
17
|
try {
|
|
15
|
-
|
|
16
|
-
throwIfAborted(signal);
|
|
17
|
-
if (info.basic_info.is_live || info.basic_info.is_upcoming) {
|
|
18
|
-
throw new YoutubeAudioError('UNSUPPORTED_VIDEO', 'Live and upcoming YouTube videos are not supported.');
|
|
19
|
-
}
|
|
20
|
-
const format = info.chooseFormat({
|
|
21
|
-
...videoInfoOptions(clientType),
|
|
22
|
-
format: options.format ?? 'any',
|
|
23
|
-
quality: 'best',
|
|
24
|
-
type: 'audio',
|
|
25
|
-
});
|
|
26
|
-
format.url = await format.decipher(innertube.session.player);
|
|
27
|
-
throwIfAborted(signal);
|
|
28
|
-
return toUpstreamSource(video, info.basic_info.title, format);
|
|
18
|
+
innertube = await waitForCaller(getInnertube(), signal);
|
|
29
19
|
}
|
|
30
20
|
catch (error) {
|
|
31
21
|
rethrowYoutubeJsError(error, signal);
|
|
32
22
|
}
|
|
23
|
+
throwIfAborted(signal);
|
|
24
|
+
let lastError;
|
|
25
|
+
for (const clientType of clientTypes) {
|
|
26
|
+
try {
|
|
27
|
+
return await resolveWithClient(innertube, video, clientType, signal);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throwIfAborted(signal);
|
|
31
|
+
lastError = error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
rethrowYoutubeJsError(lastError, signal);
|
|
33
35
|
},
|
|
34
36
|
};
|
|
35
37
|
function getInnertube() {
|
|
36
|
-
clientPromise
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
if (clientPromise === undefined) {
|
|
39
|
+
const creating = options.innertube === undefined
|
|
40
|
+
? Innertube.create(options.innertubeConfig)
|
|
41
|
+
: Promise.resolve(options.innertube);
|
|
42
|
+
clientPromise = creating.catch((error) => {
|
|
43
|
+
// A transient initialization failure must not poison this provider for
|
|
44
|
+
// every later request or retain the rejected promise indefinitely.
|
|
45
|
+
clientPromise = undefined;
|
|
46
|
+
throw error;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
39
49
|
return clientPromise;
|
|
40
50
|
}
|
|
51
|
+
async function resolveWithClient(innertube, video, clientType, signal) {
|
|
52
|
+
const infoOptions = videoInfoOptions(clientType);
|
|
53
|
+
const info = await waitForCaller(innertube.getBasicInfo(video.videoId, infoOptions), signal);
|
|
54
|
+
throwIfAborted(signal);
|
|
55
|
+
if (info.basic_info.is_live || info.basic_info.is_upcoming) {
|
|
56
|
+
throw new YoutubeAudioError('UNSUPPORTED_VIDEO', 'Live and upcoming YouTube videos are not supported.');
|
|
57
|
+
}
|
|
58
|
+
const format = info.chooseFormat({
|
|
59
|
+
...infoOptions,
|
|
60
|
+
format: options.format ?? 'any',
|
|
61
|
+
quality: 'best',
|
|
62
|
+
type: 'audio',
|
|
63
|
+
});
|
|
64
|
+
format.url = await waitForCaller(decipherFormat(format, innertube, signal), signal);
|
|
65
|
+
throwIfAborted(signal);
|
|
66
|
+
const source = toUpstreamSource(video, info.basic_info.title, format);
|
|
67
|
+
await validateRandomAccessSource(source, fetcher, signal);
|
|
68
|
+
return source;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function decipherFormat(format, innertube, signal) {
|
|
72
|
+
try {
|
|
73
|
+
return await format.decipher(innertube.session.player);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throwIfAborted(signal);
|
|
77
|
+
if (!isMissingJavascriptEvaluator(error)) {
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
Platform.shim.eval = async (data) => new Function(data.output)();
|
|
81
|
+
return format.decipher(innertube.session.player);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function validateRandomAccessSource(source, fetcher, signal) {
|
|
85
|
+
const positions = new Set([
|
|
86
|
+
0,
|
|
87
|
+
Math.floor((source.size - 1) / 2),
|
|
88
|
+
source.size - 1,
|
|
89
|
+
]);
|
|
90
|
+
for (const position of positions) {
|
|
91
|
+
throwIfAborted(signal);
|
|
92
|
+
const response = await fetcher(source.url, {
|
|
93
|
+
headers: { Range: `bytes=${position}-${position}` },
|
|
94
|
+
...(signal === undefined ? {} : { signal }),
|
|
95
|
+
});
|
|
96
|
+
const expectedRange = `bytes ${position}-${position}/${source.size}`;
|
|
97
|
+
const valid = response.status === 206 &&
|
|
98
|
+
response.headers.get('content-range') === expectedRange;
|
|
99
|
+
// The probe needs headers only; cancelling promptly avoids retaining an
|
|
100
|
+
// upstream response stream when clients return more than the requested byte.
|
|
101
|
+
await response.body?.cancel().catch(() => undefined);
|
|
102
|
+
if (!valid) {
|
|
103
|
+
throw new YoutubeAudioError('UPSTREAM_FAILURE', 'YouTube did not provide a stable random-access audio source.');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function isMissingJavascriptEvaluator(error) {
|
|
108
|
+
return error instanceof Error && error.message.includes('provide your own JavaScript evaluator');
|
|
41
109
|
}
|
|
42
110
|
function toUpstreamSource(video, title, format) {
|
|
43
111
|
if (typeof title !== 'string' ||
|
|
@@ -97,8 +165,46 @@ function sanitizeFileName(title) {
|
|
|
97
165
|
}
|
|
98
166
|
function throwIfAborted(signal) {
|
|
99
167
|
if (signal?.aborted) {
|
|
100
|
-
throw
|
|
168
|
+
throw abortedError();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function waitForCaller(promise, signal) {
|
|
172
|
+
if (signal === undefined) {
|
|
173
|
+
return promise;
|
|
101
174
|
}
|
|
175
|
+
return new Promise((resolve, reject) => {
|
|
176
|
+
let settled = false;
|
|
177
|
+
const cleanup = () => signal.removeEventListener('abort', onAbort);
|
|
178
|
+
const onAbort = () => {
|
|
179
|
+
settled = true;
|
|
180
|
+
cleanup();
|
|
181
|
+
reject(abortedError());
|
|
182
|
+
};
|
|
183
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
184
|
+
promise.then((value) => {
|
|
185
|
+
if (settled) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
settled = true;
|
|
189
|
+
cleanup();
|
|
190
|
+
resolve(value);
|
|
191
|
+
}, (error) => {
|
|
192
|
+
if (settled) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
settled = true;
|
|
196
|
+
cleanup();
|
|
197
|
+
reject(error);
|
|
198
|
+
});
|
|
199
|
+
// Aborts before listener setup do not replay the event. Check only after
|
|
200
|
+
// attaching both promise handlers so a late rejection remains handled.
|
|
201
|
+
if (signal.aborted) {
|
|
202
|
+
onAbort();
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
function abortedError() {
|
|
207
|
+
return new YoutubeAudioError('REQUEST_ABORTED', 'The audio request was aborted.');
|
|
102
208
|
}
|
|
103
209
|
function rethrowYoutubeJsError(error, signal) {
|
|
104
210
|
throwIfAborted(signal);
|
package/dist/youtube-js.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"youtube-js.js","sourceRoot":"","sources":["../src/youtube-js.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"youtube-js.js","sourceRoot":"","sources":["../src/youtube-js.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED