From 7af58dd9e842c96571c8f1c7bc852fd7a706b5bf Mon Sep 17 00:00:00 2001
From: Jorrin <43169049+JorrinKievit@users.noreply.github.com>
Date: Tue, 27 Feb 2024 23:19:40 +0100
Subject: [PATCH 1/2] prepare stream for all domains in a hls playlist

---
 pnpm-lock.yaml                                |  1 +
 src/backend/extension/messaging.ts            |  5 ++++
 src/backend/extension/streams.ts              |  4 +--
 src/components/player/display/base.ts         | 28 +++++++++++++++++--
 .../player/utils/convertRunoutputToSource.ts  |  2 ++
 src/stores/player/utils/qualities.ts          |  3 ++
 6 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2ded1fb4..0e19baec 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -7359,6 +7359,7 @@ packages:
 
   /workbox-google-analytics@7.0.0:
     resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
+    deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
     dependencies:
       workbox-background-sync: 7.0.0
       workbox-core: 7.0.0
diff --git a/src/backend/extension/messaging.ts b/src/backend/extension/messaging.ts
index 3204d541..c280f9bd 100644
--- a/src/backend/extension/messaging.ts
+++ b/src/backend/extension/messaging.ts
@@ -6,6 +6,11 @@ import {
 import { isAllowedExtensionVersion } from "@/backend/extension/compatibility";
 import { ExtensionMakeRequestResponse } from "@/backend/extension/plasmo";
 
+export const RULE_IDS = {
+  PREPARE_STREAM: 1,
+  SET_DOMAINS_HLS: 2,
+};
+
 // for some reason, about 500 ms is needed after
 // page load before the extension starts responding properly
 const isExtensionReady = new Promise<void>((resolve) => {
diff --git a/src/backend/extension/streams.ts b/src/backend/extension/streams.ts
index 588718af..af535f38 100644
--- a/src/backend/extension/streams.ts
+++ b/src/backend/extension/streams.ts
@@ -1,6 +1,6 @@
 import { Stream } from "@movie-web/providers";
 
-import { setDomainRule } from "@/backend/extension/messaging";
+import { RULE_IDS, setDomainRule } from "@/backend/extension/messaging";
 
 function extractDomain(url: string): string | null {
   try {
@@ -36,7 +36,7 @@ function buildHeadersFromStream(stream: Stream): Record<string, string> {
 
 export async function prepareStream(stream: Stream) {
   await setDomainRule({
-    ruleId: 1,
+    ruleId: RULE_IDS.PREPARE_STREAM,
     targetDomains: extractDomainsFromStream(stream),
     requestHeaders: buildHeadersFromStream(stream),
   });
diff --git a/src/components/player/display/base.ts b/src/components/player/display/base.ts
index 9b163363..4d850923 100644
--- a/src/components/player/display/base.ts
+++ b/src/components/player/display/base.ts
@@ -1,6 +1,11 @@
 import fscreen from "fscreen";
 import Hls, { Level } from "hls.js";
 
+import {
+  RULE_IDS,
+  isExtensionActiveCached,
+  setDomainRule,
+} from "@/backend/extension/messaging";
 import {
   DisplayInterface,
   DisplayInterfaceEvents,
@@ -31,8 +36,8 @@ const levelConversionMap: Record<number, SourceQuality> = {
   480: "480",
 };
 
-function hlsLevelToQuality(level: Level): SourceQuality | null {
-  return levelConversionMap[level.height] ?? null;
+function hlsLevelToQuality(level?: Level): SourceQuality | null {
+  return levelConversionMap[level?.height ?? 0] ?? null;
 }
 
 function qualityToHlsLevel(quality: SourceQuality): number | null {
@@ -144,6 +149,25 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
           if (!hls) return;
           reportLevels();
           setupQualityForHls();
+
+          if (isExtensionActiveCached()) {
+            hls.on(Hls.Events.LEVEL_LOADED, async (_, data) => {
+              console.log(data);
+              const chunkUrlsDomains = data.details.fragments
+                .map((v) => v.url)
+                .map((v) => new URL(v).hostname);
+              const chunkUrls = [...new Set(chunkUrlsDomains)];
+
+              await setDomainRule({
+                ruleId: RULE_IDS.SET_DOMAINS_HLS,
+                targetDomains: chunkUrls,
+                requestHeaders: {
+                  ...src.preferredHeaders,
+                  ...src.headers,
+                },
+              });
+            });
+          }
         });
         hls.on(Hls.Events.LEVEL_SWITCHED, () => {
           if (!hls) return;
diff --git a/src/components/player/utils/convertRunoutputToSource.ts b/src/components/player/utils/convertRunoutputToSource.ts
index f54c5396..3fd07232 100644
--- a/src/components/player/utils/convertRunoutputToSource.ts
+++ b/src/components/player/utils/convertRunoutputToSource.ts
@@ -28,6 +28,7 @@ export function convertRunoutputToSource(out: {
     return {
       type: "hls",
       url: out.stream.playlist,
+      headers: out.stream.headers,
       preferredHeaders: out.stream.preferredHeaders,
     };
   }
@@ -50,6 +51,7 @@ export function convertRunoutputToSource(out: {
     return {
       type: "file",
       qualities,
+      headers: out.stream.headers,
       preferredHeaders: out.stream.preferredHeaders,
     };
   }
diff --git a/src/stores/player/utils/qualities.ts b/src/stores/player/utils/qualities.ts
index e5140d53..afd90d25 100644
--- a/src/stores/player/utils/qualities.ts
+++ b/src/stores/player/utils/qualities.ts
@@ -14,6 +14,7 @@ export type SourceFileStream = {
 export type LoadableSource = {
   type: StreamType;
   url: string;
+  headers?: Stream["headers"];
   preferredHeaders?: Stream["preferredHeaders"];
 };
 
@@ -21,11 +22,13 @@ export type SourceSliceSource =
   | {
       type: "file";
       qualities: Partial<Record<SourceQuality, SourceFileStream>>;
+      headers?: Stream["headers"];
       preferredHeaders?: Stream["preferredHeaders"];
     }
   | {
       type: "hls";
       url: string;
+      headers?: Stream["headers"];
       preferredHeaders?: Stream["preferredHeaders"];
     };
 

From d20ab4be08ba25b1b5b23018faa5440a53edbeb1 Mon Sep 17 00:00:00 2001
From: Jorrin <43169049+JorrinKievit@users.noreply.github.com>
Date: Tue, 27 Feb 2024 23:30:00 +0100
Subject: [PATCH 2/2] double map into one

---
 src/components/player/display/base.ts | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/components/player/display/base.ts b/src/components/player/display/base.ts
index 4d850923..a12661ab 100644
--- a/src/components/player/display/base.ts
+++ b/src/components/player/display/base.ts
@@ -152,10 +152,9 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
 
           if (isExtensionActiveCached()) {
             hls.on(Hls.Events.LEVEL_LOADED, async (_, data) => {
-              console.log(data);
-              const chunkUrlsDomains = data.details.fragments
-                .map((v) => v.url)
-                .map((v) => new URL(v).hostname);
+              const chunkUrlsDomains = data.details.fragments.map(
+                (v) => new URL(v.url).hostname,
+              );
               const chunkUrls = [...new Set(chunkUrlsDomains)];
 
               await setDomainRule({