mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Prevent duplicate modal playback sessions
This commit is contained in:
1 parent
ea81e3bf32
commit
7995f92a38
2 files changed
+90
-23
No files matched your search
@@ -238,29 +238,30 @@ class Application {
|
||||
deriveTorrentPlaybackConfig,
|
||||
isValidMagnetUri,
|
||||
urlFirstEnabled: URL_FIRST_ENABLED,
|
||||
analyticsCallbacks: {
|
||||
"session-start": (detail) => {
|
||||
const urlProvided = detail?.urlProvided ? "true" : "false";
|
||||
const magnetProvided = detail?.magnetProvided ? "true" : "false";
|
||||
const magnetUsable = detail?.magnetUsable ? "true" : "false";
|
||||
this.log(
|
||||
`[playVideoWithFallback] Session start urlProvided=${urlProvided} magnetProvided=${magnetProvided} magnetUsable=${magnetUsable}`
|
||||
);
|
||||
},
|
||||
fallback: (detail) => {
|
||||
if (detail?.reason) {
|
||||
analyticsCallbacks: {
|
||||
"session-start": (detail) => {
|
||||
const urlProvided = detail?.urlProvided ? "true" : "false";
|
||||
const magnetProvided = detail?.magnetProvided ? "true" : "false";
|
||||
const magnetUsable = detail?.magnetUsable ? "true" : "false";
|
||||
this.log(
|
||||
`[playVideoWithFallback] Falling back to WebTorrent (${detail.reason}).`
|
||||
`[playVideoWithFallback] Session start urlProvided=${urlProvided} magnetProvided=${magnetProvided} magnetUsable=${magnetUsable}`
|
||||
);
|
||||
}
|
||||
},
|
||||
fallback: (detail) => {
|
||||
if (detail?.reason) {
|
||||
this.log(
|
||||
`[playVideoWithFallback] Falling back to WebTorrent (${detail.reason}).`
|
||||
);
|
||||
}
|
||||
},
|
||||
error: (detail) => {
|
||||
if (detail?.error) {
|
||||
this.log("[playVideoWithFallback] Playback error observed", detail.error);
|
||||
}
|
||||
},
|
||||
},
|
||||
error: (detail) => {
|
||||
if (detail?.error) {
|
||||
this.log("[playVideoWithFallback] Playback error observed", detail.error);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
this.activePlaybackResultPromise = null;
|
||||
this.activePlaybackSession = null;
|
||||
|
||||
this.authService =
|
||||
@@ -7009,11 +7010,32 @@ class Application {
|
||||
* and falls back to WebTorrent when needed.
|
||||
*/
|
||||
async playVideoWithFallback({ url = "", magnet = "" } = {}) {
|
||||
await this.waitForCleanup();
|
||||
this.cancelPendingViewLogging();
|
||||
|
||||
const sanitizedUrl = typeof url === "string" ? url.trim() : "";
|
||||
const trimmedMagnet = typeof magnet === "string" ? magnet.trim() : "";
|
||||
const requestSignature = JSON.stringify({
|
||||
url: sanitizedUrl,
|
||||
magnet: trimmedMagnet,
|
||||
});
|
||||
|
||||
if (
|
||||
this.activePlaybackSession &&
|
||||
typeof this.activePlaybackSession.matchesRequestSignature === "function" &&
|
||||
this.activePlaybackSession.matchesRequestSignature(requestSignature)
|
||||
) {
|
||||
this.log(
|
||||
"[playVideoWithFallback] Duplicate playback request detected; reusing active session."
|
||||
);
|
||||
if (this.activePlaybackResultPromise) {
|
||||
return this.activePlaybackResultPromise;
|
||||
}
|
||||
if (typeof this.activePlaybackSession.getResult === "function") {
|
||||
return this.activePlaybackSession.getResult();
|
||||
}
|
||||
return { source: null };
|
||||
}
|
||||
|
||||
await this.waitForCleanup();
|
||||
this.cancelPendingViewLogging();
|
||||
|
||||
let modalVideoEl = this.modalVideo;
|
||||
if (!modalVideoEl && this.videoModal) {
|
||||
@@ -7062,11 +7084,15 @@ class Application {
|
||||
if (refreshedModal) {
|
||||
this.modalVideo = refreshedModal;
|
||||
modalVideoEl = this.modalVideo;
|
||||
this.applyModalLoadingPoster();
|
||||
} else {
|
||||
this.applyModalLoadingPoster();
|
||||
}
|
||||
|
||||
const session = this.playbackService.createSession({
|
||||
url: sanitizedUrl,
|
||||
magnet: trimmedMagnet,
|
||||
requestSignature,
|
||||
videoElement: this.modalVideo,
|
||||
waitForCleanup: () => this.waitForCleanup(),
|
||||
cancelPendingViewLogging: () => this.cancelPendingViewLogging(),
|
||||
@@ -7082,6 +7108,7 @@ class Application {
|
||||
});
|
||||
|
||||
this.activePlaybackSession = session;
|
||||
this.activePlaybackResultPromise = null;
|
||||
|
||||
this.resetTorrentStats();
|
||||
this.playSource = null;
|
||||
@@ -7150,6 +7177,7 @@ class Application {
|
||||
subscribe("finished", () => {
|
||||
if (this.activePlaybackSession === session) {
|
||||
this.activePlaybackSession = null;
|
||||
this.activePlaybackResultPromise = null;
|
||||
}
|
||||
while (unsubscribers.length) {
|
||||
const off = unsubscribers.pop();
|
||||
@@ -7166,7 +7194,9 @@ class Application {
|
||||
}
|
||||
});
|
||||
|
||||
const result = await session.start();
|
||||
const startPromise = session.start();
|
||||
this.activePlaybackResultPromise = startPromise;
|
||||
const result = await startPromise;
|
||||
|
||||
if (!result || result.error) {
|
||||
return result;
|
||||
|
||||
@@ -234,11 +234,20 @@ class PlaybackSession extends SimpleEventEmitter {
|
||||
this.options = options;
|
||||
this.watchdogCleanup = null;
|
||||
this.result = { source: null };
|
||||
this.finished = false;
|
||||
this.startPromise = null;
|
||||
|
||||
this.sanitizedUrl =
|
||||
typeof options.url === "string" ? options.url.trim() : "";
|
||||
this.trimmedMagnet =
|
||||
typeof options.magnet === "string" ? options.magnet.trim() : "";
|
||||
this.requestSignature =
|
||||
typeof options.requestSignature === "string"
|
||||
? options.requestSignature
|
||||
: JSON.stringify({
|
||||
url: this.sanitizedUrl,
|
||||
magnet: this.trimmedMagnet,
|
||||
});
|
||||
|
||||
if (typeof service.deriveTorrentPlaybackConfig === "function") {
|
||||
this.playbackConfig = service.deriveTorrentPlaybackConfig({
|
||||
@@ -273,6 +282,24 @@ class PlaybackSession extends SimpleEventEmitter {
|
||||
this.magnetProvided = !!this.playbackConfig.provided;
|
||||
}
|
||||
|
||||
isActive() {
|
||||
return !this.finished;
|
||||
}
|
||||
|
||||
matchesRequestSignature(signature) {
|
||||
if (!this.isActive()) {
|
||||
return false;
|
||||
}
|
||||
if (typeof signature !== "string" || !signature) {
|
||||
return false;
|
||||
}
|
||||
return signature === this.requestSignature;
|
||||
}
|
||||
|
||||
getResult() {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
getPlaybackConfig() {
|
||||
return this.playbackConfig;
|
||||
}
|
||||
@@ -362,6 +389,14 @@ class PlaybackSession extends SimpleEventEmitter {
|
||||
}
|
||||
|
||||
async start() {
|
||||
if (this.startPromise) {
|
||||
return this.startPromise;
|
||||
}
|
||||
this.startPromise = this.execute();
|
||||
return this.startPromise;
|
||||
}
|
||||
|
||||
async execute() {
|
||||
const {
|
||||
videoElement,
|
||||
waitForCleanup,
|
||||
@@ -376,6 +411,7 @@ class PlaybackSession extends SimpleEventEmitter {
|
||||
} = this.options;
|
||||
|
||||
this.result = { source: null };
|
||||
this.finished = false;
|
||||
|
||||
const detail = {
|
||||
urlProvided: !!this.sanitizedUrl,
|
||||
@@ -721,6 +757,7 @@ class PlaybackSession extends SimpleEventEmitter {
|
||||
return this.result;
|
||||
} finally {
|
||||
this.cleanupWatchdog();
|
||||
this.finished = true;
|
||||
if (this.result) {
|
||||
this.emit("finished", this.result);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user