mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2025-09-08 06:58:43 +00:00
trying to fix some CORS issues
This commit is contained in:
115
src/js/app.js
115
src/js/app.js
@@ -700,44 +700,46 @@ class bitvidApp {
|
||||
async loadVideos() {
|
||||
console.log("Starting loadVideos...");
|
||||
|
||||
// 1) If there's an existing subscription, unsubscribe it
|
||||
if (this.videoSubscription) {
|
||||
this.videoSubscription.unsub();
|
||||
this.videoSubscription = null;
|
||||
}
|
||||
|
||||
// 2) Show "Loading..." message
|
||||
if (this.videoList) {
|
||||
this.videoList.innerHTML = `
|
||||
<p class="text-center text-gray-500">
|
||||
Loading videos...
|
||||
</p>`;
|
||||
}
|
||||
|
||||
try {
|
||||
// 3) Force a bulk fetch
|
||||
await nostrClient.fetchVideos();
|
||||
|
||||
// 4) Instead of reusing the entire fetched array,
|
||||
// use getActiveVideos() for the final display:
|
||||
const newestActive = nostrClient.getActiveVideos();
|
||||
this.renderVideoList(newestActive);
|
||||
|
||||
// 5) Subscribe for updates
|
||||
this.videoSubscription = nostrClient.subscribeVideos((video) => {
|
||||
// Whenever we get a new or updated event, re-render the newest set:
|
||||
const activeAll = nostrClient.getActiveVideos();
|
||||
this.renderVideoList(activeAll);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Could not load videos:", err);
|
||||
this.showError("Could not load videos from relays.");
|
||||
// If we already have a subscription, don’t unsubscribe/resubscribe—
|
||||
// just update the UI from local cache.
|
||||
if (!this.videoSubscription) {
|
||||
// First-time load: show “Loading...” message
|
||||
if (this.videoList) {
|
||||
this.videoList.innerHTML = `
|
||||
<p class="text-center text-gray-500">
|
||||
No videos available at this time.
|
||||
Loading videos...
|
||||
</p>`;
|
||||
}
|
||||
|
||||
// 1) Do a bulk fetch once
|
||||
try {
|
||||
await nostrClient.fetchVideos();
|
||||
} catch (err) {
|
||||
console.error("Could not load videos initially:", err);
|
||||
this.showError("Could not load videos from relays.");
|
||||
if (this.videoList) {
|
||||
this.videoList.innerHTML = `
|
||||
<p class="text-center text-gray-500">
|
||||
No videos available at this time.
|
||||
</p>`;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Render the newest set after the fetch
|
||||
const newestActive = nostrClient.getActiveVideos();
|
||||
this.renderVideoList(newestActive);
|
||||
|
||||
// 3) Create a single subscription that updates our UI
|
||||
this.videoSubscription = nostrClient.subscribeVideos(() => {
|
||||
// Each time a new/updated event arrives, we just re-render from local
|
||||
const updatedAll = nostrClient.getActiveVideos();
|
||||
this.renderVideoList(updatedAll);
|
||||
});
|
||||
} else {
|
||||
// If we’ve already subscribed before, just update from cache
|
||||
const allCached = nostrClient.getActiveVideos();
|
||||
this.renderVideoList(allCached);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,26 +1019,27 @@ class bitvidApp {
|
||||
return;
|
||||
}
|
||||
|
||||
// Look up the video in our subscription map
|
||||
// 1) Check local 'videosMap' or 'nostrClient.getActiveVideos()'
|
||||
let matchedVideo = Array.from(this.videosMap.values()).find(
|
||||
(v) => v.magnet === decodedMagnet
|
||||
);
|
||||
|
||||
// If not found in the map, do a fallback fetch
|
||||
if (!matchedVideo) {
|
||||
const allVideos = await nostrClient.fetchVideos();
|
||||
matchedVideo = allVideos.find((v) => v.magnet === decodedMagnet);
|
||||
// Instead of forcing a full `fetchVideos()`,
|
||||
// try looking in the activeVideos from local cache:
|
||||
const activeVideos = nostrClient.getActiveVideos();
|
||||
matchedVideo = activeVideos.find((v) => v.magnet === decodedMagnet);
|
||||
}
|
||||
|
||||
// If still not found, you can do a single event-based approach or just show an error:
|
||||
if (!matchedVideo) {
|
||||
this.showError("No matching video found.");
|
||||
this.showError("No matching video found in local cache.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update our tracking
|
||||
// Update tracking
|
||||
this.currentMagnetUri = decodedMagnet;
|
||||
|
||||
// Hand off to the method that already sets modal fields and streams
|
||||
// Delegate to the main method
|
||||
await this.playVideoByEventId(matchedVideo.id);
|
||||
} catch (error) {
|
||||
console.error("Error in playVideo:", error);
|
||||
@@ -1465,27 +1468,31 @@ class bitvidApp {
|
||||
return video;
|
||||
}
|
||||
|
||||
// 2) Bulk fetch from relays
|
||||
const allFromBulk = await nostrClient.fetchVideos();
|
||||
|
||||
// 2a) Deduplicate so we only keep newest version per root
|
||||
const newestPerRoot = dedupeToNewestByRoot(allFromBulk);
|
||||
|
||||
// 2b) Find the requested ID within the deduplicated set
|
||||
video = newestPerRoot.find((v) => v.id === eventId);
|
||||
if (video) {
|
||||
// Store it in our local map, so we can open it instantly next time
|
||||
this.videosMap.set(video.id, video);
|
||||
return video;
|
||||
// 2) Already in nostrClient.allEvents?
|
||||
// (assuming nostrClient.allEvents is a Map of id => video)
|
||||
const fromAll = nostrClient.allEvents.get(eventId);
|
||||
if (fromAll && !fromAll.deleted) {
|
||||
this.videosMap.set(eventId, fromAll);
|
||||
return fromAll;
|
||||
}
|
||||
|
||||
// 3) Final fallback: direct single-event fetch
|
||||
// 3) Direct single-event fetch (fewer resources than full fetchVideos)
|
||||
const single = await nostrClient.getEventById(eventId);
|
||||
if (single && !single.deleted) {
|
||||
this.videosMap.set(single.id, single);
|
||||
return single;
|
||||
}
|
||||
|
||||
// 4) If you wanted a final fallback, you could do it here:
|
||||
// But it's typically better to avoid repeated full fetches
|
||||
// console.log("Falling back to full fetchVideos...");
|
||||
// const allFetched = await nostrClient.fetchVideos();
|
||||
// video = allFetched.find(v => v.id === eventId && !v.deleted);
|
||||
// if (video) {
|
||||
// this.videosMap.set(video.id, video);
|
||||
// return video;
|
||||
// }
|
||||
|
||||
// Not found or was deleted
|
||||
return null;
|
||||
}
|
||||
|
@@ -7,8 +7,6 @@ export class TorrentClient {
|
||||
this.client = new WebTorrent();
|
||||
this.currentTorrent = null;
|
||||
this.TIMEOUT_DURATION = 60000; // 60 seconds
|
||||
// We remove the “statsInterval” since we’re not using it here anymore
|
||||
// this.statsInterval = null;
|
||||
}
|
||||
|
||||
log(msg) {
|
||||
@@ -43,6 +41,7 @@ export class TorrentClient {
|
||||
return false;
|
||||
};
|
||||
|
||||
// Check if already active
|
||||
if (checkActivation()) return;
|
||||
|
||||
registration.addEventListener("activate", () => {
|
||||
@@ -60,6 +59,9 @@ export class TorrentClient {
|
||||
});
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// UPDATED: setupServiceWorker
|
||||
// --------------------------
|
||||
async setupServiceWorker() {
|
||||
try {
|
||||
const isBraveBrowser = await this.isBrave();
|
||||
@@ -83,6 +85,7 @@ export class TorrentClient {
|
||||
throw new Error("Please enable WebRTC in Brave Shield settings");
|
||||
}
|
||||
|
||||
// Unregister any existing SW
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
for (const registration of registrations) {
|
||||
await registration.unregister();
|
||||
@@ -90,17 +93,13 @@ export class TorrentClient {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
const currentPath = window.location.pathname;
|
||||
const basePath = currentPath.substring(
|
||||
0,
|
||||
currentPath.lastIndexOf("/") + 1
|
||||
);
|
||||
|
||||
this.log("Registering service worker...");
|
||||
// Directly register sw.min.js at /src/sw.min.js
|
||||
// with a scope that covers /src/ (which includes /src/webtorrent).
|
||||
this.log("Registering service worker at /src/sw.min.js...");
|
||||
const registration = await navigator.serviceWorker.register(
|
||||
"./sw.min.js",
|
||||
"/src/sw.min.js",
|
||||
{
|
||||
scope: basePath,
|
||||
scope: "/src/",
|
||||
updateViaCache: "none",
|
||||
}
|
||||
);
|
||||
@@ -129,6 +128,7 @@ export class TorrentClient {
|
||||
await this.waitForServiceWorkerActivation(registration);
|
||||
this.log("Service worker activated");
|
||||
|
||||
// Make sure the SW is fully ready
|
||||
const readyRegistration = await Promise.race([
|
||||
navigator.serviceWorker.ready,
|
||||
new Promise((_, reject) =>
|
||||
@@ -171,8 +171,14 @@ export class TorrentClient {
|
||||
throw new Error("Service worker setup failed");
|
||||
}
|
||||
|
||||
// 2) Create WebTorrent server
|
||||
this.client.createServer({ controller: registration });
|
||||
// ------------------------------------------------
|
||||
// UPDATED: Pass pathPrefix to createServer
|
||||
// so that it uses /src/webtorrent/... for streaming
|
||||
// ------------------------------------------------
|
||||
this.client.createServer({
|
||||
controller: registration,
|
||||
pathPrefix: "/src/webtorrent",
|
||||
});
|
||||
this.log("WebTorrent server created");
|
||||
|
||||
const isFirefoxBrowser = this.isFirefox();
|
||||
@@ -202,11 +208,37 @@ export class TorrentClient {
|
||||
}
|
||||
}
|
||||
|
||||
// Minimal handleChromeTorrent — no internal setInterval
|
||||
// Minimal handleChromeTorrent
|
||||
handleChromeTorrent(torrent, videoElement, resolve, reject) {
|
||||
const file = torrent.files.find((f) =>
|
||||
/\.(mp4|webm|mkv)$/.test(f.name.toLowerCase())
|
||||
);
|
||||
// OPTIONAL: Listen for “warning” events
|
||||
torrent.on("warning", (err) => {
|
||||
if (err && typeof err.message === "string") {
|
||||
if (
|
||||
err.message.includes("CORS") ||
|
||||
err.message.includes("Access-Control-Allow-Origin")
|
||||
) {
|
||||
console.warn(
|
||||
"CORS warning detected. Attempting to remove the failing webseed/tracker."
|
||||
);
|
||||
// Example cleanup approach...
|
||||
if (torrent._opts?.urlList?.length) {
|
||||
torrent._opts.urlList = torrent._opts.urlList.filter((url) => {
|
||||
return !url.includes("distribution.bbb3d.renderfarming.net");
|
||||
});
|
||||
console.warn("Cleaned up webseeds =>", torrent._opts.urlList);
|
||||
}
|
||||
if (torrent._opts?.announce?.length) {
|
||||
torrent._opts.announce = torrent._opts.announce.filter((url) => {
|
||||
return !url.includes("fastcast.nz");
|
||||
});
|
||||
console.warn("Cleaned up trackers =>", torrent._opts.announce);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Then proceed with normal file selection
|
||||
const file = torrent.files.find((f) => /\.(mp4|webm|mkv)$/i.test(f.name));
|
||||
if (!file) {
|
||||
return reject(new Error("No compatible video file found in torrent"));
|
||||
}
|
||||
@@ -215,7 +247,7 @@ export class TorrentClient {
|
||||
videoElement.muted = true;
|
||||
videoElement.crossOrigin = "anonymous";
|
||||
|
||||
// Catch video errors
|
||||
// Catch video-level errors
|
||||
videoElement.addEventListener("error", (e) => {
|
||||
this.log("Video error:", e.target.error);
|
||||
});
|
||||
@@ -227,7 +259,6 @@ export class TorrentClient {
|
||||
});
|
||||
});
|
||||
|
||||
// Actually stream
|
||||
try {
|
||||
file.streamTo(videoElement);
|
||||
this.currentTorrent = torrent;
|
||||
@@ -237,7 +268,6 @@ export class TorrentClient {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
// Also handle torrent error events
|
||||
torrent.on("error", (err) => {
|
||||
this.log("Torrent error (Chrome path):", err);
|
||||
reject(err);
|
||||
@@ -286,7 +316,6 @@ export class TorrentClient {
|
||||
*/
|
||||
async cleanup() {
|
||||
try {
|
||||
// No local interval to clear here
|
||||
if (this.currentTorrent) {
|
||||
this.currentTorrent.destroy();
|
||||
}
|
||||
|
Reference in New Issue
Block a user