P2P sharing of HLS media streams using WebRTC for Hls.js
Useful links:
General steps are:
- Include P2P Medial Loader scripts.
- Create P2P Medial Loader engine instance.
- Create a player instance.
- Call init function for the player.
P2P Media Loader supports many players that use Hls.js as media engine. Lets pick Clappr just for this example:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Clappr/Hls.js with P2P Media Loader</title>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/p2p-media-loader-core@latest/build/p2p-media-loader-core.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@latest/build/p2p-media-loader-hlsjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clappr@latest"></script>
</head>
<body>
<div id="player"></div>
<script>
if (p2pml.hlsjs.Engine.isSupported()) {
var engine = new p2pml.hlsjs.Engine();
var player = new Clappr.Player({
parentId: "#player",
source: "https://akamai-axtest.akamaized.net/routes/lapd-v1-acceptance/www_c4/Manifest.m3u8",
mute: true,
autoPlay: true,
playback: {
hlsjsConfig: {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
}
}
});
p2pml.hlsjs.initClapprPlayer(player);
} else {
document.write("Not supported :(");
}
</script>
</body>
</html>
The library uses window.p2pml.hlsjs
as a root namespace in Web browser for:
Engine
- hls.js support engineinitHlsJsPlayer
- hls.js player integrationinitClapprPlayer
- Clappr player integrationinitFlowplayerHlsJsPlayer
- Flowplayer integrationinitJwPlayer
- JW Player integrationinitMediaElementJsPlayer
- MediaElement.js player integrationinitVideoJsContribHlsJsPlayer
- Video.js player integrationversion
- API version
hls.js support engine.
Returns result from p2pml.core.HybridLoader.isSupported()
.
Creates a new Engine
instance.
settings
object with the following fields:
segments
forwardSegmentCount
- Number of segments for building up predicted forward segments sequence; used to predownload and share via P2P. Default is 20;swarmId
- Override default swarm ID that is used to identify unique media stream with trackers (manifest URL without query parameters is used as the swarm ID if the parameter is not specified);
loader
- settings for
HybridLoader
(see P2P Media Loader Core API for details);
- settings for
Registers an event handler.
event
- Event you want to handle; available events you can find here.handler
- Function to handle the event
Returns engine instance settings.
Returns engine instance details.
Creates hls.js loader class bound to this engine.
Notifies engine about current playing segment.
Needed for own integrations with other players. If you write one, you should update engine with current playing segment from your player.
url
segment URL.
byterange
segment byte-range object with the following fields or undefined:
offset
segment offsetlength
segment length
Destroys engine; destroy loader and segment manager.
We support many players, but it is possible to write your own integration in case it is no supported at the moment. Feel free to make pull requests with your player integrations.
In order a player to be able to integrate with the Engine, it should meet following requirements:
- Player based on
hls.js
. - Player allows to pass
hls
configuration. This is needed for us to be able to override hls.jsloader
. - Player allows to subcribe to events on hls.js player.
- If player exposes
hls
object, you just callp2pml.hlsjs.initHlsJsPlayer(hls)
; - Or if player allows to directly subsctibe to hls.js events, you need to handle:
hlsFragChanged
- callengine.setPlayingSegment(url, byterange)
to notify Engine about current playing segment url;hlsDestroying
- callengine.destroy()
to inform Engine about destroying hls.js player;
- If player exposes
hls.js player integration.
player
should be valid hls.js instance.
Example
var engine = new p2pml.hlsjs.Engine();
var hls = new Hls({
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
});
p2pml.hlsjs.initHlsJsPlayer(hls);
hls.loadSource("https://example.com/path/to/your/playlist.m3u8");
var video = document.getElementById("video");
hls.attachMedia(video);
Clappr player integration.
player
should be valid Clappr player instance.
Example
var engine = new p2pml.hlsjs.Engine();
var player = new Clappr.Player({
parentId: "#video",
source: "https://example.com/path/to/your/playlist.m3u8",
playback: {
hlsjsConfig: {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
}
}
});
p2pml.hlsjs.initClapprPlayer(player);
Flowplayer integration.
player
should be valid Flowplayer instance.
Example
var engine = new p2pml.hlsjs.Engine();
var player = flowplayer("#video", {
clip: {
sources: [{
src: "https://example.com/path/to/your/playlist.m3u8",
type: "application/x-mpegurl"
}]
},
hlsjs: {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass(),
safari: true
}
});
p2pml.hlsjs.initFlowplayerHlsJsPlayer(player);
JW Player integration.
player
should be valid JW Player instance.
Example
var engine = new p2pml.hlsjs.Engine();
var player = jwplayer("player");
player.setup({
file: "https://example.com/path/to/your/playlist.m3u8"
});
var provider = require("@hola.org/jwplayer-hlsjs");
provider.attach();
p2pml.hlsjs.initJwPlayer(player, {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
});
MediaElement.js player integration.
mediaElement
should be valid value received from success handler of the MediaElementPlayer.
Example
var engine = new p2pml.hlsjs.Engine();
// allow only one supported renderer
mejs.Renderers.order = [ "native_hls" ];
var player = new MediaElementPlayer("video", {
hls: {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
},
success: function (mediaElement) {
p2pml.hlsjs.initMediaElementJsPlayer(mediaElement);
}
});
player.setSrc("https://example.com/path/to/your/playlist.m3u8");
player.load();
Video.js player integration.
player
should be valid Video.js player instance.
Example
var engine = new p2pml.hlsjs.Engine();
var player = videojs("video", {
html5: {
hlsjsConfig: {
liveSyncDurationCount: 7,
loader: engine.createLoaderClass()
}
}
});
p2pml.hlsjs.initVideoJsContribHlsJsPlayer(player);
player.src({
src: "https://example.com/path/to/your/playlist.m3u8",
type: "application/x-mpegURL"
});