pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

first mvp extension

Jorrin ef85c217 fbb5ef71

+133 -55
+1
package.json
··· 31 31 "@ladjs/country-language": "^1.0.3", 32 32 "@movie-web/providers": "^2.0.5", 33 33 "@noble/hashes": "^1.3.3", 34 + "@plasmohq/messaging": "^0.6.1", 34 35 "@react-spring/web": "^9.7.3", 35 36 "@scure/bip39": "^1.2.2", 36 37 "@sozialhelden/ietf-language-tags": "^5.4.2",
+21
pnpm-lock.yaml
··· 27 27 '@noble/hashes': 28 28 specifier: ^1.3.3 29 29 version: 1.3.3 30 + '@plasmohq/messaging': 31 + specifier: ^0.6.1 32 + version: 0.6.1(react@18.2.0) 30 33 '@react-spring/web': 31 34 specifier: ^9.7.3 32 35 version: 9.7.3(react-dom@18.2.0)(react@18.2.0) ··· 1979 1982 picocolors: 1.0.0 1980 1983 tslib: 2.6.2 1981 1984 dev: true 1985 + 1986 + /@plasmohq/messaging@0.6.1(react@18.2.0): 1987 + resolution: {integrity: sha512-/nn1k8SG5z++o/NnZu+byHWcC9MhPLxfmvj+AP3buqMn7uwfYDcYWURLuMW2Knw08HBg+wku2v1Ltt4evN0nzA==} 1988 + peerDependencies: 1989 + react: ^16.8.6 || ^17 || ^18 1990 + peerDependenciesMeta: 1991 + react: 1992 + optional: true 1993 + dependencies: 1994 + nanoid: 5.0.3 1995 + react: 18.2.0 1996 + dev: false 1982 1997 1983 1998 /@react-spring/animated@9.7.3(react@18.2.0): 1984 1999 resolution: {integrity: sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==} ··· 5155 5170 resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 5156 5171 engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 5157 5172 hasBin: true 5173 + 5174 + /nanoid@5.0.3: 5175 + resolution: {integrity: sha512-I7X2b22cxA4LIHXPSqbBCEQSL+1wv8TuoefejsX4HFWyC6jc5JG7CEaxOltiKjc1M+YCS2YkrZZcj4+dytw9GA==} 5176 + engines: {node: ^18 || >=20} 5177 + hasBin: true 5178 + dev: false 5158 5179 5159 5180 /nanoid@5.0.4: 5160 5181 resolution: {integrity: sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==}
+37
src/@types/plasmo.d.ts
··· 1 + /* eslint-disable @typescript-eslint/ban-types */ 2 + import "@plasmohq/messaging"; 3 + 4 + export interface PlasmoRequestBody { 5 + ruleId: number; 6 + domain: string; 7 + requestHeaders?: Record<string, string>; 8 + responseHeaders?: Record<string, string>; 9 + } 10 + 11 + export type PlasmoResponseBody = 12 + | { 13 + success: true; 14 + ruleId: number; 15 + } 16 + | { 17 + success: false; 18 + error: string; 19 + }; 20 + 21 + interface MmMetadata { 22 + "declarative-net-request": { 23 + req: PlasmoRequestBody; 24 + res: PlasmoResponseBody; 25 + }; 26 + "proxy-request": { 27 + req: PlasmoRequestBody; 28 + res: PlasmoResponseBody; 29 + }; 30 + } 31 + 32 + interface MpMetadata {} 33 + 34 + declare module "@plasmohq/messaging" { 35 + interface MessagesMetadata extends MmMetadata {} 36 + interface PortsMetadata extends MpMetadata {} 37 + }
+65 -53
src/components/player/display/base.ts
··· 1 + import { sendToBackgroundViaRelay } from "@plasmohq/messaging"; 1 2 import fscreen from "fscreen"; 2 3 import Hls, { Level } from "hls.js"; 3 4 5 + import { PlasmoRequestBody, PlasmoResponseBody } from "@/@types/plasmo"; 4 6 import { 5 7 DisplayInterface, 6 8 DisplayInterfaceEvents, ··· 100 102 } 101 103 102 104 function setupSource(vid: HTMLVideoElement, src: LoadableSource) { 103 - if (src.type === "hls") { 104 - if (canPlayHlsNatively(vid)) { 105 - vid.src = processCdnLink(src.url); 106 - vid.currentTime = startAt; 107 - return; 108 - } 105 + // TODO: Add check whether the extension is installed 106 + sendToBackgroundViaRelay<PlasmoRequestBody, PlasmoResponseBody>({ 107 + name: "declarative-net-request", 108 + body: { 109 + ruleId: 1, 110 + domain: src.type === "hls" ? new URL(src.url).hostname : src.url, 111 + requestHeaders: src.preferredHeaders, 112 + }, 113 + }).then(() => { 114 + if (src.type === "hls") { 115 + if (canPlayHlsNatively(vid)) { 116 + vid.src = processCdnLink(src.url); 117 + vid.currentTime = startAt; 118 + return; 119 + } 109 120 110 - if (!Hls.isSupported()) throw new Error("HLS not supported"); 111 - if (!hls) { 112 - hls = new Hls({ 113 - maxBufferSize: 500 * 1000 * 1000, // 500 mb of buffering, should load more fragments at once 114 - fragLoadPolicy: { 115 - default: { 116 - maxLoadTimeMs: 30 * 1000, // allow it load extra long, fragments are slow if requested for the first time on an origin 117 - maxTimeToFirstByteMs: 30 * 1000, 118 - errorRetry: { 119 - maxNumRetry: 2, 120 - retryDelayMs: 1000, 121 - maxRetryDelayMs: 8000, 122 - }, 123 - timeoutRetry: { 124 - maxNumRetry: 3, 125 - maxRetryDelayMs: 0, 126 - retryDelayMs: 0, 121 + if (!Hls.isSupported()) throw new Error("HLS not supported"); 122 + if (!hls) { 123 + hls = new Hls({ 124 + maxBufferSize: 500 * 1000 * 1000, // 500 mb of buffering, should load more fragments at once 125 + fragLoadPolicy: { 126 + default: { 127 + maxLoadTimeMs: 30 * 1000, // allow it load extra long, fragments are slow if requested for the first time on an origin 128 + maxTimeToFirstByteMs: 30 * 1000, 129 + errorRetry: { 130 + maxNumRetry: 2, 131 + retryDelayMs: 1000, 132 + maxRetryDelayMs: 8000, 133 + }, 134 + timeoutRetry: { 135 + maxNumRetry: 3, 136 + maxRetryDelayMs: 0, 137 + retryDelayMs: 0, 138 + }, 127 139 }, 128 140 }, 129 - }, 130 - }); 131 - hls.on(Hls.Events.ERROR, (event, data) => { 132 - console.error("HLS error", data); 133 - if (data.fatal) { 134 - emit("error", { 135 - message: data.error.message, 136 - stackTrace: data.error.stack, 137 - errorName: data.error.name, 138 - type: "hls", 139 - }); 140 - } 141 - }); 142 - hls.on(Hls.Events.MANIFEST_LOADED, () => { 143 - if (!hls) return; 144 - reportLevels(); 145 - setupQualityForHls(); 146 - }); 147 - hls.on(Hls.Events.LEVEL_SWITCHED, () => { 148 - if (!hls) return; 149 - const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]); 150 - emit("changedquality", quality); 151 - }); 141 + }); 142 + hls.on(Hls.Events.ERROR, (event, data) => { 143 + console.error("HLS error", data); 144 + if (data.fatal) { 145 + emit("error", { 146 + message: data.error.message, 147 + stackTrace: data.error.stack, 148 + errorName: data.error.name, 149 + type: "hls", 150 + }); 151 + } 152 + }); 153 + hls.on(Hls.Events.MANIFEST_LOADED, () => { 154 + if (!hls) return; 155 + reportLevels(); 156 + setupQualityForHls(); 157 + }); 158 + hls.on(Hls.Events.LEVEL_SWITCHED, () => { 159 + if (!hls) return; 160 + const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]); 161 + emit("changedquality", quality); 162 + }); 163 + } 164 + 165 + hls.attachMedia(vid); 166 + hls.loadSource(processCdnLink(src.url)); 167 + vid.currentTime = startAt; 168 + return; 152 169 } 153 170 154 - hls.attachMedia(vid); 155 - hls.loadSource(processCdnLink(src.url)); 171 + vid.src = processCdnLink(src.url); 156 172 vid.currentTime = startAt; 157 - return; 158 - } 159 - 160 - vid.src = processCdnLink(src.url); 161 - vid.currentTime = startAt; 173 + }); 162 174 } 163 175 164 176 function setSource() {
+2
src/components/player/utils/convertRunoutputToSource.ts
··· 28 28 return { 29 29 type: "hls", 30 30 url: out.stream.playlist, 31 + preferredHeaders: out.stream.preferredHeaders, 31 32 }; 32 33 } 33 34 if (out.stream.type === "file") { ··· 49 50 return { 50 51 type: "file", 51 52 qualities, 53 + preferredHeaders: out.stream.preferredHeaders, 52 54 }; 53 55 } 54 56 throw new Error("unrecognized type");
+4 -1
src/stores/player/utils/qualities.ts
··· 1 - import { Qualities } from "@movie-web/providers"; 1 + import { Qualities, Stream } from "@movie-web/providers"; 2 2 3 3 import { QualityStore } from "@/stores/quality"; 4 4 ··· 14 14 export type LoadableSource = { 15 15 type: StreamType; 16 16 url: string; 17 + preferredHeaders?: Stream["preferredHeaders"]; 17 18 }; 18 19 19 20 export type SourceSliceSource = 20 21 | { 21 22 type: "file"; 22 23 qualities: Partial<Record<SourceQuality, SourceFileStream>>; 24 + preferredHeaders?: Stream["preferredHeaders"]; 23 25 } 24 26 | { 25 27 type: "hls"; 26 28 url: string; 29 + preferredHeaders?: Stream["preferredHeaders"]; 27 30 }; 28 31 29 32 const qualitySorting: Record<SourceQuality, number> = {
+3 -1
src/utils/providers.ts
··· 62 62 export const providers = makeProviders({ 63 63 fetcher: makeStandardFetcher(fetch), 64 64 proxiedFetcher: makeLoadBalancedSimpleProxyFetcher(), 65 - target: targets.BROWSER, 65 + // TODO: Add check whether the extension is installed 66 + // target: targets.BROWSER, 67 + target: targets.BROWSER_EXTENSION, 66 68 }) as any as ProviderControls;