|
|
@ -1,6 +1,8 @@ |
|
|
|
|
|
|
|
import { sendToBackgroundViaRelay } from "@plasmohq/messaging"; |
|
|
|
import fscreen from "fscreen"; |
|
|
|
import fscreen from "fscreen"; |
|
|
|
import Hls, { Level } from "hls.js"; |
|
|
|
import Hls, { Level } from "hls.js"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { PlasmoRequestBody, PlasmoResponseBody } from "@/@types/plasmo"; |
|
|
|
import { |
|
|
|
import { |
|
|
|
DisplayInterface, |
|
|
|
DisplayInterface, |
|
|
|
DisplayInterfaceEvents, |
|
|
|
DisplayInterfaceEvents, |
|
|
@ -100,65 +102,75 @@ export function makeVideoElementDisplayInterface(): DisplayInterface { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function setupSource(vid: HTMLVideoElement, src: LoadableSource) { |
|
|
|
function setupSource(vid: HTMLVideoElement, src: LoadableSource) { |
|
|
|
if (src.type === "hls") { |
|
|
|
// TODO: Add check whether the extension is installed
|
|
|
|
if (canPlayHlsNatively(vid)) { |
|
|
|
sendToBackgroundViaRelay<PlasmoRequestBody, PlasmoResponseBody>({ |
|
|
|
vid.src = processCdnLink(src.url); |
|
|
|
name: "declarative-net-request", |
|
|
|
vid.currentTime = startAt; |
|
|
|
body: { |
|
|
|
return; |
|
|
|
ruleId: 1, |
|
|
|
} |
|
|
|
domain: src.type === "hls" ? new URL(src.url).hostname : src.url, |
|
|
|
|
|
|
|
requestHeaders: src.preferredHeaders, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}).then(() => { |
|
|
|
|
|
|
|
if (src.type === "hls") { |
|
|
|
|
|
|
|
if (canPlayHlsNatively(vid)) { |
|
|
|
|
|
|
|
vid.src = processCdnLink(src.url); |
|
|
|
|
|
|
|
vid.currentTime = startAt; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!Hls.isSupported()) throw new Error("HLS not supported"); |
|
|
|
if (!Hls.isSupported()) throw new Error("HLS not supported"); |
|
|
|
if (!hls) { |
|
|
|
if (!hls) { |
|
|
|
hls = new Hls({ |
|
|
|
hls = new Hls({ |
|
|
|
maxBufferSize: 500 * 1000 * 1000, // 500 mb of buffering, should load more fragments at once
|
|
|
|
maxBufferSize: 500 * 1000 * 1000, // 500 mb of buffering, should load more fragments at once
|
|
|
|
fragLoadPolicy: { |
|
|
|
fragLoadPolicy: { |
|
|
|
default: { |
|
|
|
default: { |
|
|
|
maxLoadTimeMs: 30 * 1000, // allow it load extra long, fragments are slow if requested for the first time on an origin
|
|
|
|
maxLoadTimeMs: 30 * 1000, // allow it load extra long, fragments are slow if requested for the first time on an origin
|
|
|
|
maxTimeToFirstByteMs: 30 * 1000, |
|
|
|
maxTimeToFirstByteMs: 30 * 1000, |
|
|
|
errorRetry: { |
|
|
|
errorRetry: { |
|
|
|
maxNumRetry: 2, |
|
|
|
maxNumRetry: 2, |
|
|
|
retryDelayMs: 1000, |
|
|
|
retryDelayMs: 1000, |
|
|
|
maxRetryDelayMs: 8000, |
|
|
|
maxRetryDelayMs: 8000, |
|
|
|
}, |
|
|
|
}, |
|
|
|
timeoutRetry: { |
|
|
|
timeoutRetry: { |
|
|
|
maxNumRetry: 3, |
|
|
|
maxNumRetry: 3, |
|
|
|
maxRetryDelayMs: 0, |
|
|
|
maxRetryDelayMs: 0, |
|
|
|
retryDelayMs: 0, |
|
|
|
retryDelayMs: 0, |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|
hls.on(Hls.Events.ERROR, (event, data) => { |
|
|
|
hls.on(Hls.Events.ERROR, (event, data) => { |
|
|
|
console.error("HLS error", data); |
|
|
|
console.error("HLS error", data); |
|
|
|
if (data.fatal) { |
|
|
|
if (data.fatal) { |
|
|
|
emit("error", { |
|
|
|
emit("error", { |
|
|
|
message: data.error.message, |
|
|
|
message: data.error.message, |
|
|
|
stackTrace: data.error.stack, |
|
|
|
stackTrace: data.error.stack, |
|
|
|
errorName: data.error.name, |
|
|
|
errorName: data.error.name, |
|
|
|
type: "hls", |
|
|
|
type: "hls", |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
hls.on(Hls.Events.MANIFEST_LOADED, () => { |
|
|
|
hls.on(Hls.Events.MANIFEST_LOADED, () => { |
|
|
|
if (!hls) return; |
|
|
|
if (!hls) return; |
|
|
|
reportLevels(); |
|
|
|
reportLevels(); |
|
|
|
setupQualityForHls(); |
|
|
|
setupQualityForHls(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
hls.on(Hls.Events.LEVEL_SWITCHED, () => { |
|
|
|
hls.on(Hls.Events.LEVEL_SWITCHED, () => { |
|
|
|
if (!hls) return; |
|
|
|
if (!hls) return; |
|
|
|
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]); |
|
|
|
const quality = hlsLevelToQuality(hls.levels[hls.currentLevel]); |
|
|
|
emit("changedquality", quality); |
|
|
|
emit("changedquality", quality); |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hls.attachMedia(vid); |
|
|
|
|
|
|
|
hls.loadSource(processCdnLink(src.url)); |
|
|
|
|
|
|
|
vid.currentTime = startAt; |
|
|
|
|
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
hls.attachMedia(vid); |
|
|
|
vid.src = processCdnLink(src.url); |
|
|
|
hls.loadSource(processCdnLink(src.url)); |
|
|
|
|
|
|
|
vid.currentTime = startAt; |
|
|
|
vid.currentTime = startAt; |
|
|
|
return; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vid.src = processCdnLink(src.url); |
|
|
|
|
|
|
|
vid.currentTime = startAt; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function setSource() { |
|
|
|
function setSource() { |
|
|
|