### Start Development Environment Source: https://github.com/novage/p2p-media-loader/blob/main/CONTRIBUTING.md Run this command in the integrated terminal of a GitHub Codespace to start the development environment. All dependencies are pre-installed. ```bash pnpm dev ``` -------------------------------- ### Install Dependencies Source: https://github.com/novage/p2p-media-loader/blob/main/CONTRIBUTING.md Install all workspace project dependencies after cloning the repository. This command is used for local development setup. ```bash pnpm i ``` -------------------------------- ### Integrating P2P Media Loader with Shaka Player Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example shows how to integrate P2P Media Loader with Shaka Player. It includes necessary HTML structure, Shaka Player UI scripts, and P2P Media Loader modules. The script initializes the P2P engine, registers its plugins, and binds it to the Shaka Player instance before loading the stream. ```html
``` -------------------------------- ### Install P2P Media Loader for Shaka Player via npm Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Install the Shaka Player integration package using npm. This is required before importing and using the library in your project. ```bash npm install p2p-media-loader-shaka ``` -------------------------------- ### Integrate P2P Media Loader with standalone Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example demonstrates integrating P2P Media Loader directly with an Hls.js player instance. It shows how to create an Hls.js instance with P2P capabilities and attach it to a video element. ```html ``` -------------------------------- ### Integrate P2P Media Loader with Vidstack and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example shows how to use P2P Media Loader with the Vidstack player. It injects P2P capabilities into Hls.js and configures the player to use the P2P engine. ```html
``` -------------------------------- ### Clone Repository Source: https://github.com/novage/p2p-media-loader/blob/main/CONTRIBUTING.md Clone the P2P Media Loader repository to your local machine. Ensure you have pnpm installed globally. ```bash git clone https://github.com/Novage/p2p-media-loader.git ``` -------------------------------- ### Integrate P2P Media Loader with DPlayer and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example demonstrates integrating P2P Media Loader with the DPlayer. It defines a custom HLS type within DPlayer to inject P2P capabilities into Hls.js. ```html ``` -------------------------------- ### Integrating P2P with DPlayer and Shaka Player Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example illustrates integrating P2P Media Loader with DPlayer using Shaka Player. It covers registering P2P plugins, initializing the P2P engine, and binding it to a Shaka Player instance created within DPlayer's custom type configuration for HLS or DASH streams. ```html ``` -------------------------------- ### Install P2P Media Loader for Hls.js via npm Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Install the Hls.js integration package using npm. This is required before importing and using the library in your project. ```bash npm install p2p-media-loader-hlsjs ``` -------------------------------- ### Integrate P2P Media Loader with PlayerJS and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This example shows how to integrate P2P Media Loader with PlayerJS. It globally injects P2P capabilities into Hls.js and configures PlayerJS to use the modified Hls.js instance. ```html ``` -------------------------------- ### Configure Personal Trackers and STUN Servers Source: https://github.com/novage/p2p-media-loader/blob/main/FAQ.md Configure custom tracker and STUN servers for P2P connections. This setup is used when initializing the P2P engine for both Shaka Player and HLS.js. ```javascript const config = { core: { announceTrackers: [ "wss://personal.tracker1.com", "wss://personal.tracker2.com", ], rtcConfig: { iceServers: [ { urls: "stun:stun.l.google.com:19302" }, { urls: "stun:global.stun.twilio.com:3478?transport=udp" }, ], }, }, }; const engineShaka = new ShakaP2PEngine(config, shaka); // or const engineHlsJs = new HlsJsP2PEngine(config); ``` ```javascript const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); const hls = new HlsWithP2P({ p2p: { core: { announceTrackers: [ "wss://personal.tracker1.com", "wss://personal.tracker2.com", ], rtcConfig: { iceServers: [ { urls: "stun:stun.l.google.com:19302" }, { urls: "stun:global.stun.twilio.com:3478?transport=udp" }, ], }, }, onHlsJsCreated(hls) { // Subscribe to P2P engine and Hls.js events here hls.p2pEngine.addEventListener("onSegmentLoaded", (details) => { console.log("Segment Loaded:", details); }); }, }, }); ``` -------------------------------- ### WebTorrentClient Constructor Configuration Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-client/spec.md Configuration options for initializing a new WebTorrentClient instance. ```APIDOC ## Constructor Configuration ```typescript interface WebTorrentClientConfig { wsClient: WebSocketClient; // The underlying WebSocket client infoHash: string; // 20-character ASCII string representing the torrent (derived from Base64 hash) peerId: string; // 20-byte string representing this client rtcConfig?: RTCConfiguration; // Optional custom STUN/TURN server configuration channelConfig?: RTCDataChannelInit; // Optional Data Channel overrides offerTimeout?: number; // Time (in ms) to keep unanswered offers before destroying them. Default: 50000 (50s). offersCount?: number; // Maximum number of offers to generate per announce interval. Default: 5. connectionTimeout?: number; // Time (in ms) to wait for the data channel to open. Default: 15000 (15s). // Callback invoked when a peer_id is discovered via an offer or answer. // Attempts to claim the peer to prevent duplicate connections. // Return true to accept and connect, false if the peer is already claimed/connected. claimPeer?: (peerId: string) => boolean; // Callback invoked before every announce to determine if new offers should be generated. // Return false to stop generating offers (numwant: 0), while still answering incoming offers. shouldGenerateOffers?: () => boolean; } ``` ``` -------------------------------- ### Integrate P2P with OpenPlayerJS and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Set up OpenPlayerJS with P2P support by configuring the hls.p2p options and initializing the player. ```html ``` -------------------------------- ### WebTorrentManager Configuration Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-manager/spec.md Configuration interface for initializing a WebTorrentManager. ```APIDOC ## WebTorrentManagerConfig ### Description Configuration options for the WebTorrentManager. ### Properties - **infoHash** (string) - Required - 20-character ASCII string representing the torrent (derived from Base64 hash). - **peerId** (string) - Required - 20-byte string representing this client. - **trackerUrls** (string[]) - Required - Array of WebSocket tracker URLs to connect to. - **rtcConfig** (RTCConfiguration) - Optional - WebRTC STUN/TURN configuration. - **channelConfig** (RTCDataChannelInit) - Optional - Data Channel configuration. - **socketPool** (WebTorrentSocketPool) - Required - Shared socket pool. - **offerTimeout** (number) - Optional - Time (in ms) to keep unanswered offers before destroying them. Default: 50000. - **offersCount** (number) - Optional - Maximum number of offers to generate per announce interval. Default: 5. - **connectionTimeout** (number) - Optional - Time (in ms) to wait for the data channel to open. Default: 15000. ``` -------------------------------- ### Integrating P2P with Clappr and Shaka Player Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This snippet demonstrates integrating P2P Media Loader with Clappr player using Shaka Player as the playback engine. It shows how to register P2P plugins, configure the P2P engine, and bind it to the Shaka Player instance within the Clappr player's configuration. ```html ``` -------------------------------- ### Initialize Shaka Player with P2P Media Loader (IIFE) Source: https://github.com/novage/p2p-media-loader/blob/main/demo/public/modules-demo/shaka-iife.html This snippet initializes the Shaka Player and integrates the P2P Media Loader using an IIFE bundle. Ensure the P2P Media Loader IIFE bundle is loaded globally before executing this code. It includes error handling for player initialization and manifest loading. ```javascript const manifestUri = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; async function initApp() { if (shaka.Player.isBrowserSupported()) { const video = document.getElementById("video"); // The IIFE bundle exports its contents on the global variable defined in vite config const { ShakaP2PEngine } = window.p2pml.shaka; ShakaP2PEngine.registerPlugins(); const engine = new ShakaP2PEngine(); const player = new shaka.Player(); await player.attach(video); player.addEventListener("error", function (event) { console.error( "Error code", event.detail.code, "object", event.detail, ); }); engine.bindShakaPlayer(player); try { await player.load(manifestUri); } catch (e) { console.error("Error code", e.code, "object", e); } } else { console.error("Shaka Player not supported in this browser."); } } document.addEventListener("DOMContentLoaded", initApp); ``` -------------------------------- ### Integrating P2P with Plyr and Shaka Player Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md This code snippet shows how to integrate P2P Media Loader with Plyr, utilizing Shaka Player for playback. It demonstrates registering P2P plugins, initializing the P2P engine, binding it to a Shaka Player instance, and then initializing Plyr with the video element. ```html ``` -------------------------------- ### Initialize HLS.js with P2P Media Loader (IIFE) Source: https://github.com/novage/p2p-media-loader/blob/main/demo/public/modules-demo/hlsjs-iife.html This snippet initializes HLS.js with the P2P Media Loader engine using an IIFE bundle. Ensure the P2P engine is globally available before calling this code. ```javascript const manifestUri = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; function initApp() { if (Hls.isSupported()) { const video = document.getElementById("video"); // The IIFE bundle exports its contents on the global variable defined in vite config const { HlsJsP2PEngine } = window.p2pml.hlsjs; const HlsWithP2P = HlsJsP2PEngine.injectMixin(window.Hls); const hls = new HlsWithP2P(); hls.attachMedia(video); hls.on(Hls.Events.ERROR, function (event, data) { console.error("Error code", data.details, "object", data); }); try { hls.loadSource(manifestUri); } catch (e) { console.error(e); } } else { console.error("HLS not supported in this browser."); } } document.addEventListener("DOMContentLoaded", initApp); ``` -------------------------------- ### WebTorrent Client Configuration Interface Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-client/spec.md Defines the configuration options for initializing a WebTorrent client. Includes parameters for WebSocket client, torrent info, peer ID, WebRTC settings, and various timeouts and callbacks. ```typescript interface WebTorrentClientConfig { wsClient: WebSocketClient; // The underlying WebSocket client infoHash: string; // 20-character ASCII string representing the torrent (derived from Base64 hash) peerId: string; // 20-byte string representing this client rtcConfig?: RTCConfiguration; // Optional custom STUN/TURN server configuration channelConfig?: RTCDataChannelInit; // Optional Data Channel overrides offerTimeout?: number; // Time (in ms) to keep unanswered offers before destroying them. Default: 50000 (50s). offersCount?: number; // Maximum number of offers to generate per announce interval. Default: 5. connectionTimeout?: number; // Time (in ms) to wait for the data channel to open. Default: 15000 (15s). // Callback invoked when a peer_id is discovered via an offer or answer. // Attempts to claim the peer to prevent duplicate connections. // Return true to accept and connect, false if the peer is already claimed/connected. claimPeer?: (peerId: string) => boolean; // Callback invoked before every announce to determine if new offers should be generated. // Return false to stop generating offers (numwant: 0), while still answering incoming offers. shouldGenerateOffers?: () => boolean; } ``` -------------------------------- ### Integrate P2P with Clappr and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Use HlsJsP2PEngine with Clappr player. Configure P2P engine and bind it to the Clappr player's HLS instance. ```html ``` -------------------------------- ### WebTorrentClient Methods Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-client/spec.md Core methods for managing the WebTorrent client's lifecycle and event listeners. ```APIDOC ## Methods - `start(): void`: Begins the `announce` loop if the injected `WebSocketClient` is already connected, or waits for it to connect. It does not call `connect()` on the injected client. - `destroy(): void`: Complete teardown. Sends a final `event: "stopped"` announce to the tracker (if connected), clears all pending offers and timers, removes all event listeners, and disposes the abort controllers. Does NOT dispose the `WebSocketClient` as it may be pooled. - `addEventListener(eventName: K, listener: WebTorrentClientEventMap[K]): void`: Registers an event listener. - `removeEventListener(eventName: K, listener: WebTorrentClientEventMap[K]): void`: Removes a registered event listener. ``` -------------------------------- ### Integrate P2P with MediaElement and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Integrate P2P engine with MediaElement.js by injecting the P2P mixin into Hls.js and configuring the player. ```html ``` -------------------------------- ### Bash script for live audio stream with multiple qualities Source: https://github.com/novage/p2p-media-loader/wiki/Home This script sets up directories for different audio qualities and uses ffmpeg to create HLS playlists for each quality level from a live stream. It ensures segments are deleted after creation. ```bash #!/bin/bash DIRS=("high" "medium" "low") for dir in "${DIRS[@]}"; do if [ -d "$dir" ]; then rm -rf "$dir"/* else mkdir -p "$dir" fi done ffmpeg -i https://streamvideol1.luxnet.ua/nostalgi/nostalgi.stream/playlist.m3u8 \ -map 0 -c:a aac -b:a 128k -f hls -hls_time 10 -hls_list_size 0 -hls_list_size 10 -hls_flags delete_segments high/playlist.m3u8 \ -map 0 -c:a aac -b:a 96k -f hls -hls_time 10 -hls_list_size 0 -hls_list_size 10 -hls_flags delete_segments medium/playlist.m3u8 \ -map 0 -c:a aac -b:a 64k -f hls -hls_time 10 -hls_list_size 0 -hls_list_size 10 -hls_flags delete_segments low/playlist.m3u8 ``` -------------------------------- ### Integrate P2P with Shaka Player (IIFE) Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Use this snippet to integrate P2P Media Loader with Shaka Player in older browsers. Ensure Shaka Player and the P2P Media Loader IIFE build are loaded before this script. ```html ``` -------------------------------- ### acquire Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-socket-pool/spec.md Acquires a WebSocketClient for a given URL, managing connection pooling and reference counting. ```APIDOC ## acquire(url: string): { client: WebSocketClient; release: () => void } ### Description Acquires a `WebSocketClient` for the given URL. If a connection for the URL already exists and is active, its reference count is incremented. Otherwise, a new connection is established. ### Parameters #### Path Parameters - **url** (string) - Required - The URL of the WebTorrent tracker for which to acquire a WebSocket client. ### Response #### Success Response - **client** (`WebSocketClient`) - The WebSocket client instance. - **release** (`() => void`) - A function to release the reference to the client. Calling this decrements the reference count, and if it reaches zero, the socket is disposed. ``` -------------------------------- ### WebTorrentManager Methods Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-manager/spec.md Public methods available on the WebTorrentManager instance. ```APIDOC ## WebTorrentManager Methods ### `start()` #### Description Acquires sockets from the pool, instantiates the `WebTorrentClient`s, and calls `start()` on all of them. #### Method `start(): void` ### `destroy()` #### Description Destroys all child `WebTorrentClient` instances, releases all sockets back to the pool, closes all active and connecting peer connections, dispatches `peerDisconnected` events for all connected peers, and clears all internal event listeners. #### Method `destroy(): void` ### `addEventListener()` #### Description Registers an event listener for manager events. #### Method `addEventListener(eventName: K, listener: WebTorrentManagerEventMap[K]): void` ### `removeEventListener()` #### Description Removes a registered event listener from the manager. #### Method `removeEventListener(eventName: K, listener: WebTorrentManagerEventMap[K]): void` ``` -------------------------------- ### WebSocketClientConfig Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/websocket-client/spec.md Configuration interface for initializing the WebSocket client. ```APIDOC ## WebSocketClientConfig ### Description Configuration options for the WebSocket client, including connection URL and reconnection parameters. ### Properties - **url** (string) - Required - The WebSocket endpoint to connect to. - **initialDelay** (number) - Optional - The initial wait time before the first reconnection attempt. Default: 1000 (1s). - **maxDelay** (number) - Optional - The maximum wait time between reconnection attempts. Default: 30000 (30s). - **jitterMultiplier** (number) - Optional - A multiplier used to add randomness to the delay. Default: 0.2. ``` -------------------------------- ### Integrate P2P Media Loader with Shaka Player Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Import and register the P2P Media Loader engine with Shaka Player. This enables Shaka Player to utilize P2P for media delivery. ```typescript import shaka from "shaka-player/dist/shaka-player.ui"; import { ShakaP2PEngine } from "p2p-media-loader-shaka"; ShakaP2PEngine.registerPlugins(shaka); ``` -------------------------------- ### Create New Feature Branch Source: https://github.com/novage/p2p-media-loader/blob/main/CONTRIBUTING.md Create a new branch for your feature or bug fix. Replace 'your-feature' with a descriptive name. ```bash git checkout -b feature/your-feature ``` -------------------------------- ### Integrate P2P with Hls.js Player (IIFE) Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Use this snippet to integrate P2P Media Loader with a standalone Hls.js player in older browsers. Ensure Hls.js and the P2P Media Loader IIFE build are loaded before this script. ```html ``` -------------------------------- ### Integrate P2P with Plyr and Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Configure Plyr player with P2P capabilities by using the HlsJsP2PEngine mixin and setting up quality options. ```html ``` -------------------------------- ### Integrate P2P Media Loader with Hls.js Source: https://github.com/novage/p2p-media-loader/blob/main/api_documentation.md Import and integrate the P2P Media Loader engine with Hls.js. This allows Hls.js to leverage P2P capabilities. ```typescript import Hls from "hls.js"; import { HlsJsP2PEngine } from "p2p-media-loader-hlsjs"; const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); ``` -------------------------------- ### WebSocket Client Configuration Interface Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/websocket-client/spec.md Defines the configuration options for initializing the WebSocket client, including the WebSocket endpoint URL and parameters for controlling the reconnection backoff strategy. ```typescript interface WebSocketClientConfig { url: string; // The WebSocket endpoint to connect to initialDelay?: number; // The initial wait time before the first reconnection attempt. Default: 1000 (1s) maxDelay?: number; // The maximum wait time between reconnection attempts. Default: 30000 (30s) jitterMultiplier?: number; // A multiplier used to add randomness to the delay. Default: 0.2 } ``` -------------------------------- ### WebTorrentManager Configuration Interface Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-manager/spec.md Defines the configuration options for creating a WebTorrentManager instance, including torrent infoHash, peerId, tracker URLs, WebRTC/Data Channel configurations, and a shared socket pool. ```typescript interface WebTorrentManagerConfig { infoHash: string; // 20-character ASCII string representing the torrent (derived from Base64 hash) peerId: string; // 20-byte string representing this client trackerUrls: string[]; // Array of WebSocket tracker URLs to connect to rtcConfig?: RTCConfiguration; // WebRTC STUN/TURN configuration channelConfig?: RTCDataChannelInit; // Data Channel configuration socketPool: WebTorrentSocketPool; // Shared socket pool offerTimeout?: number; // Time (in ms) to keep unanswered offers before destroying them. Default: 50000. offersCount?: number; // Maximum number of offers to generate per announce interval. Default: 5. connectionTimeout?: number; // Time (in ms) to wait for the data channel to open. Default: 15000. } ``` -------------------------------- ### Configure vm-hls Elements for P2P Source: https://github.com/novage/p2p-media-loader/blob/main/demo/public/modules-demo/player-vime.html Configure individual elements by setting their 'config' property. This includes Hls.js specific configurations and P2P engine settings such as custom swarm IDs and event handlers for engine creation. ```javascript // Configure all elements for (const vmHls of document.querySelectorAll("vm-hls")) { vmHls.config = { startLevel: 0, // example of Hls.js config parameter // ... other Hls.js config parameters go here // example of P2P engine config section p2p: { onHlsJsCreated: (hls) => { // Subscribe to P2P engine and Hls.js events here console.log( "Hls.js engine with P2P mixin created", hls.p2pEngine.getConfig(), hls.config, ); }, core: { swarmId: "custom swarm ID for stream 2000341", }, }, }; } ``` -------------------------------- ### Receiving an Offer from Tracker Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-client/spec.md The JSON format when a tracker routes an incoming offer from another peer to the client. ```json { "action": "announce", "info_hash": "<20-character-binary-string>", "peer_id": "", "offer_id": "", "offer": { "type": "offer", "sdp": "v=0\r\no=..." } } ``` -------------------------------- ### Log P2P Segment Loaded Events Source: https://github.com/novage/p2p-media-loader/blob/main/FAQ.md Subscribe to the 'onSegmentLoaded' event to log details about each segment loaded via P2P. This helps in observing P2P activity. ```javascript const engine = new HlsJsP2PEngine(); engine.addEventListener("onSegmentLoaded", (details) => { console.log("Segment Loaded:", details); }); ``` -------------------------------- ### Push Branch to GitHub Source: https://github.com/novage/p2p-media-loader/blob/main/CONTRIBUTING.md Push your local branch to GitHub to make it available for a pull request. Ensure 'your-feature' is replaced with your branch name. ```bash git push origin feature/your-feature ``` -------------------------------- ### WebSocket Client Methods Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/websocket-client/spec.md Core methods for managing the WebSocket client's lifecycle and communication. ```APIDOC ## WebSocket Client Methods ### connect() #### Description Initiates the WebSocket connection. #### Method `connect` ### send(data) #### Description Sends data over the WebSocket. Must support binary data. Throws an error if called when not connected. #### Method `send` #### Parameters - **data** (string | ArrayBuffer | Blob | ArrayBufferView) - Required - The data to send. ### dispose() #### Description Completely tears down the client, clears callbacks, stops all timers, closes the socket, clears event listeners, and prevents future automatic reconnections. #### Method `dispose` ### addEventListener(eventName, listener) #### Description Registers an event listener for client events. #### Method `addEventListener` #### Parameters - **eventName** (K) - Required - The name of the event to listen for. - **listener** (WebSocketClientEventMap[K]) - Required - The callback function to execute when the event is fired. ### removeEventListener(eventName, listener) #### Description Removes a registered event listener. #### Method `removeEventListener` #### Parameters - **eventName** (K) - Required - The name of the event to remove the listener from. - **listener** (WebSocketClientEventMap[K]) - Required - The callback function to remove. ``` -------------------------------- ### WebSocket Client Properties and Events Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/websocket-client/spec.md Details on the client's state property and the events it emits. ```APIDOC ## WebSocket Client Properties and Events ### Properties - **state** (`'connecting' | 'connected' | 'reconnecting' | 'disconnected' | 'disposed'`) - Read-only getter returning the current state of the client. ### Events The client implements an `EventTarget` system emitting the following lifecycle events: - **connected** (payload: `void`): Fired when the WebSocket connection is successfully established. - **disconnected** (payload: `void`): Fired when the connection is lost (or deliberately closed). - **reconnecting** (payload: `void`): Fired when a reconnection attempt is scheduled. - **error** (payload: `Event`): Fired when a WebSocket error occurs. - **message** (payload: `ArrayBuffer | string`): Fired when a message is received from the server. ``` -------------------------------- ### Peer Claiming Logic in WebTorrentManager Source: https://github.com/novage/p2p-media-loader/blob/main/packages/p2p-media-loader-core/src/webtorrent/webtorrent-manager/spec.md This callback is passed to WebTorrentClient to prevent managing duplicate peers. It checks existing collections of connecting and connected peers before adding a new one. ```typescript #claimPeer = (remotePeerId: string): boolean => { if (this.#destroyed) return false; if ( this.#connectingPeers.has(remotePeerId) || this.#connectedPeers.has(remotePeerId) ) { return false; } this.#connectingPeers.add(remotePeerId); return true; }; ```