Novage P2P Media Loader is an open-source JavaScript library that uses modern browser technologies — HTML5 video and WebRTC — to enable peer-to-peer (P2P) media delivery. In this guide we will review how to use Novage P2P Media Loader with Radiant Media Player for both HLS and MPEG-DASH streaming. This can be used for live and on-demand media streaming and can increase viewer experience, reduce bandwidth cost and help preserve the environment.
Radiant Media Player does not provide server-side production-ready support for using Novage P2P Media Loader. By default P2P Media Loader uses publicly available servers. Those servers can be used for testing and development but are not suitable for production environment. You will need to set up a STUN server (like coturn) and WebTorrent tracker (see this guide) for production usage
Novage P2P Media Loader support in Radiant Media Player is available for the following environments:
All Radiant Media Player features can be used in conjunction with Novage P2P Media Loader technology. Where Novage P2P Media Loader support is not available (e.g. older iOS) the player will gracefully fallback to "classic" HLS or MPEG-DASH delivery (e.g. not WebRTC-accelerated).
We will now prepare our player code. To help you out, we have made this as straight-forward as possible to use Novage P2P Media Loader with Radiant Media Player.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover"> <title>TODO supply a title</title> <!-- Import map for P2P Media Loader modules --> <script type="importmap"> { "imports": { "p2p-media-loader-core": "https://cdn.jsdelivr.net/npm/p2p-media-loader-core@^2/dist/p2p-media-loader-core.es.min.js", "p2p-media-loader-hlsjs": "https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@^2/dist/p2p-media-loader-hlsjs.es.min.js" } } </script> <!-- Import Radiant Media Player as a module --> <script type="importmap"> { "imports": { "rmp": "https://cdn.radiantmediatechs.com/rmp/10.7.0/js/rmp.min.mjs" } } </script> </head> <body> <!-- Player container element --> <div id="rmp"></div> <!-- Set up player configuration options --> <script type="module"> import { HlsJsP2PEngine } from 'p2p-media-loader-hlsjs'; import RadiantMP from 'rmp'; const src = { hls: 'https://your-hls-url.m3u8' }; const settings = { licenseKey: 'your-license-key', src, width: 640, height: 360, autoplay: true, // Radiant Media Player settings for best P2P assisted streaming hlsJSMaxBufferAhead: 60, hlsJSMaxBufferBehind: Infinity, // Passing P2P Media Loader settings p2pMediaLoaderEngine: HlsJsP2PEngine, p2pMediaLoaderConfig: { core: { swarmId: 'https://your-hls-url.m3u8' // Other P2P engine config parameters go here }, onHlsJsCreated(hls) { // This can be useful for development and debugging hls.p2pEngine.addEventListener('onPeerConnect', (params) => { console.log('Peer connected:', params.peerId); }); hls.p2pEngine.addEventListener('onSegmentLoaded', (details) => { console.log('Segment Loaded:', details); }); hls.p2pEngine.addEventListener('onChunkDownloaded', (bytesLength, downloadSource, peerId) => { console.log(`Downloaded ${bytesLength} bytes from ${downloadSource} ${peerId ? 'from peer ' + peerId : 'from server'}`); }); } } }; const elementID = 'rmp'; const rmp = new RadiantMP(elementID); async function initRmpPlayer() { try { await rmp.init(settings); } catch (error) { console.error('Radiant Media Player failed to initialize', error); } } initRmpPlayer(); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover"> <title>TODO supply a title</title> <!-- Import map for P2P Media Loader modules --> <script type="importmap"> { "imports": { "p2p-media-loader-core": "https://cdn.jsdelivr.net/npm/p2p-media-loader-core@^2/dist/p2p-media-loader-core.es.min.js", "p2p-media-loader-shaka": "https://cdn.jsdelivr.net/npm/p2p-media-loader-shaka@^2/dist/p2p-media-loader-shaka.es.min.js" } } </script> <!-- Import Radiant Media Player as a module --> <script type="importmap"> { "imports": { "rmp": "https://cdn.radiantmediatechs.com/rmp/10.7.0/js/rmp.min.mjs" } } </script> </head> <body> <!-- Player container element --> <div id="rmp"></div> <!-- Set up player configuration options --> <script type="module"> import { ShakaP2PEngine } from 'p2p-media-loader-shaka'; import RadiantMP from 'rmp'; const src = { dash: 'https://your-mpeg-dash-url.mpd' }; const settings = { licenseKey: 'your-license-key', src, width: 640, height: 360, autoplay: true, // Radiant Media Player settings for best P2P assisted streaming shakaMaxBufferAhead: 60, shakaMaxBufferBehind: Infinity, // Passing P2P Media Loader settings p2pMediaLoaderEngine: ShakaP2PEngine, p2pMediaLoaderConfig: { core: { swarmId: 'https://your-mpeg-dash-url.mpd' // Other P2P engine config parameters go here } } }; const elementID = 'rmp'; const rmp = new RadiantMP(elementID); async function initRmpPlayer() { try { await rmp.init(settings); rmp.on('shakap2pengineavailable', (engine) => { const shakaP2PEngine = engine.data; console.log('Shaka P2P Engine is available:', shakaP2PEngine); shakaP2PEngine.addEventListener('onPeerConnect', (params) => { console.log('Peer connected:', params.peerId); }); shakaP2PEngine.addEventListener('onSegmentLoaded', (details) => { console.log('Segment Loaded:', details); }); shakaP2PEngine.addEventListener('onChunkDownloaded', (bytesLength, downloadSource, peerId) => { console.log(`Downloaded ${bytesLength} bytes from ${downloadSource} ${peerId ? 'from peer ' + peerId : 'from server'}`); }); }); } catch (error) { console.error('Radiant Media Player failed to initialize', error); } } initRmpPlayer(); </script> </body> </html>
©2015-2025 Radiant Media Player. All Rights Reserved.