diff --git a/package-lock.json b/package-lock.json index 5767c67..021cbd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "quickjs-emscripten": "^0.31.0", - "youtubei.js": "github:alexeichhorn/YouTube.js#feat/android-sdkless-client" + "youtubei.js": "github:alexeichhorn/YouTube.js#4f74d89a" }, "devDependencies": { "@cloudflare/vitest-pool-workers": "^0.16.11", @@ -2819,7 +2819,7 @@ }, "node_modules/youtubei.js": { "version": "17.0.1", - "resolved": "git+ssh://git@github.com/alexeichhorn/YouTube.js.git#434e0a09d6dadeb39f66d745def91f93f45daf7a", + "resolved": "git+ssh://git@github.com/alexeichhorn/YouTube.js.git#4f74d89a1af198f857f9136f907414b4ab62f721", "funding": [ "https://github.com/sponsors/LuanRT" ], diff --git a/package.json b/package.json index 1c9cd4e..2935eac 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,6 @@ }, "dependencies": { "quickjs-emscripten": "^0.31.0", - "youtubei.js": "github:alexeichhorn/YouTube.js#feat/android-sdkless-client" + "youtubei.js": "github:alexeichhorn/YouTube.js#4f74d89a" } } diff --git a/src/youtube/service.ts b/src/youtube/service.ts index 68c9c32..b81c5d0 100644 --- a/src/youtube/service.ts +++ b/src/youtube/service.ts @@ -261,18 +261,29 @@ export class YouTubeService { } } - // TODO: remove duplicate itags // TODO: parallelize it if (allStreams.length === 0) { try { - return await this.getStreamsForClient(innertube, fallbackClient); + return this.deduplicateStreams(await this.getStreamsForClient(innertube, fallbackClient)); } catch (error) { console.error(`Failed to get streams for fallback client ${fallbackClient}:`, error); } } - return allStreams; + return this.deduplicateStreams(allStreams); + } + + private deduplicateStreams(streams: RemoteStream[]): RemoteStream[] { + const streamsByItag = new Map(); + + for (const stream of streams) { + if (!streamsByItag.has(stream.itag)) { + streamsByItag.set(stream.itag, stream); + } + } + + return Array.from(streamsByItag.values()); } private async getStreamsForClient(innertube: Innertube, client: AvailableInnertubeClient): Promise {