Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Ptitloup/feature video p2p #925

Draft
wants to merge 73 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
4bdbc70
implement p2p-media-loader : https://github.com/Novage/p2p-media-load…
ptitloup Aug 28, 2023
ce34c8e
add p2p configuration in video script - show p2p stat in video_page_c…
ptitloup Aug 29, 2023
1b15d8f
add minus in stats info
ptitloup Aug 30, 2023
183a1cb
Merge branch 'develop' of https://github.com/EsupPortail/Esup-Pod int…
ptitloup Aug 30, 2023
e781dd7
change npm package to get videojs8 and p2p media loader from peertube…
ptitloup Sep 7, 2023
8c30e02
merge package.json
ptitloup Sep 7, 2023
6d7d0fc
add videojs-hlsjs-plugin.js
ptitloup Sep 7, 2023
74b20c2
workon videojs 8 plugin - ok for logo, quality selector, p2p, remove …
ptitloup Sep 7, 2023
d310993
remove chapter plugin from videojs and use video text track in webvtt…
ptitloup Sep 8, 2023
22f80c8
merge develop - fix conflicts
ptitloup Sep 8, 2023
743e85f
remove chapter from video element and add overview
ptitloup Sep 8, 2023
a4c081e
fix get element by id for playlist
ptitloup Sep 8, 2023
810ab24
remove plugin to show info in modal and use videojs api modal plyaer …
ptitloup Sep 8, 2023
56337bf
add settgins for the p2p function and improve display of p2p stats
ptitloup Sep 8, 2023
319ff1d
add jsdoc and readme - add p2p js only if p2p feature is activated - …
ptitloup Sep 11, 2023
9b23773
Merge branch 'develop' of https://github.com/EsupPortail/Esup-Pod int…
ptitloup Sep 11, 2023
334227f
add video-p2p-stats.js to store all p2p event function - add p2p to l…
ptitloup Sep 11, 2023
ed9a83e
create template to show p2p stats and call it from another template -…
ptitloup Sep 12, 2023
e4dd235
pull develop and remove videojs-info-controlbar.js
ptitloup Sep 12, 2023
5e796af
change firstplay by one play to deal with new videojs8 api - improvin…
ptitloup Sep 12, 2023
c25774d
use default configuration in live script for p2p
ptitloup Sep 13, 2023
c507eb4
replace videojs hlsjs plugin by the original - use the good init func…
ptitloup Sep 18, 2023
31aa5f8
[WIP] Update HLS with hls-plugin (#4)
SebastienCozeDev Oct 12, 2023
d2978ed
Merge develop
SebastienCozeDev Oct 13, 2023
200252c
make lang
SebastienCozeDev Oct 13, 2023
42ad6e3
Fix .mo
SebastienCozeDev Oct 13, 2023
add831d
Add buffer length
SebastienCozeDev Oct 13, 2023
04b935f
Fix conflicts
AymericJak Nov 6, 2023
523e35b
Merge branch 'develop' of https://github.com/EsupPortail/Esup-Pod int…
AymericJak Nov 7, 2023
d2f86ea
Replace deprecated methods & fix viewcounter
AymericJak Nov 7, 2023
4046e4b
Replace deprecated functions & remove redundant import
AymericJak Nov 7, 2023
1e5565b
Improve QoC of event-script.html file
AymericJak Nov 8, 2023
c6b2e57
Add Pod resolutions plugin
AymericJak Nov 8, 2023
add2355
Fix viewcounter import
AymericJak Nov 8, 2023
ab8a71e
Replace deprecated methods & remove imports
AymericJak Nov 9, 2023
a110b0c
Add parameters for video hls js config
AymericJak Nov 9, 2023
945079f
Pull develop
AymericJak Nov 9, 2023
93aff4c
QoC - Part 1
AymericJak Nov 10, 2023
10f50fb
QoC - Part 2 - hls-plugin
AymericJak Nov 10, 2023
ec8d234
QoC - Part 3
AymericJak Nov 10, 2023
4adad31
Fix chapters
AymericJak Nov 10, 2023
f12eaad
Fix conflicts
AymericJak Nov 20, 2023
5c6e4e6
Create the peer to peer application & the USE_PEER_TO_PEER setting
SebastienCozeDev Dec 12, 2023
fdc41ca
Add test
SebastienCozeDev Dec 12, 2023
618881a
Add test
SebastienCozeDev Dec 13, 2023
df56953
Resolve request bug
SebastienCozeDev Dec 14, 2023
82c8b5a
Rename functions
SebastienCozeDev Dec 14, 2023
9152e09
Add getIds function
SebastienCozeDev Dec 14, 2023
917a6fd
Update the getIds() function
SebastienCozeDev Dec 14, 2023
e6299fe
Fix peerID
AymericJak Dec 14, 2023
1189eff
Merge branch 'ptitloup/feature_video_p2p' of https://github.com/ptitl…
AymericJak Dec 14, 2023
4eb2da2
Fix storeUrlsId
AymericJak Dec 14, 2023
46e7d46
Rename videoId
AymericJak Dec 14, 2023
453a8d5
Update p2p-script.js
SebastienCozeDev Dec 14, 2023
61b14b8
Merge branch 'ptitloup/feature_video_p2p' of https://github.com/ptitl…
SebastienCozeDev Dec 14, 2023
cfcf1e3
Linting & doc
AymericJak Dec 14, 2023
2774bfb
Fix conflicts
AymericJak Dec 14, 2023
853b733
Merge branch 'develop' of https://github.com/EsupPortail/Esup-Pod int…
AymericJak Dec 14, 2023
929e018
Add connection to an other peer
SebastienCozeDev Dec 14, 2023
113d0b7
Merge develop
SebastienCozeDev Dec 14, 2023
3ac24e1
Add connectToAnyPeers
SebastienCozeDev Dec 15, 2023
56e73b4
Add clear invalid peer from caches view
AymericJak Dec 15, 2023
04359c1
Merge branch 'ptitloup/feature_video_p2p' of https://github.com/ptitl…
AymericJak Dec 15, 2023
83c5ad0
Update caches
AymericJak Dec 15, 2023
485cc75
Add connectToAnyPeers and connectToNextPeer function (not work)
SebastienCozeDev Dec 15, 2023
91ff5a2
Add beforeRequest redefine
SebastienCozeDev Dec 15, 2023
cb6688b
Add the P2p object
SebastienCozeDev Dec 15, 2023
ebc3520
Increase timeout for caches
AymericJak Dec 15, 2023
ee7944b
Fix conflicts
AymericJak Jan 4, 2024
5b37864
Manage peers in caches
AymericJak Jan 5, 2024
c6d6bf1
- Add & update documentation
SebastienCozeDev Jan 5, 2024
0193cee
Add the numberofConnections var
SebastienCozeDev Jan 16, 2024
7bbea0f
Merge develop
SebastienCozeDev Jan 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 0 additions & 68 deletions pod/live/templates/live/event-iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,80 +140,12 @@ <h2 class="video-title">{{ event.title }}</h2>

{# affichage du bouton d'info sur le player #}
{% if event.is_coming and event.video_on_hold.is_video or event.is_current %}

<script>
{% if event.is_coming and event.video_on_hold.is_video %}
iframeplayer = videojs("podvideoonholdplayer");
{% else %}
iframeplayer = videojs("podvideoplayer");
{% endif %}

iframeplayer.videoJsInfo();

function setOnPlayerPlayPause() {
iframeplayer.on('play', function () {
isPlaying = true;
$('#div-video-wrapper').attr('class', '')
})
iframeplayer.on('pause', function () {
isPlaying = false;
})
}

$('#div-video-wrapper').append('<div id="overlay-footer"></div>')
iframeplayer.ready(function () {
const btinfo = $('.vjs-info-button:eq(0)')[0]
$(btinfo).clone().appendTo('#overlay-footer')
$('#overlay-footer .vjs-info-button').click(function () {
$(btinfo).click()
})
})
$(document).on('click', '.close', function () {
show_info_video()
});

// Responsive
const hdres = 1920 / 1080;
let isPlaying = false, wasPlaying = false
setOnPlayerPlayPause()

function resizeInfo() {
const ihead = document.querySelector('#info-video-wrapper > .iframe-header')
, ph = iframeplayer.el().offsetHeight
, pb = parseInt(iframeplayer.el().style.top) + ph - 30
, pw = ph * hdres//$('#podvideoplayer .vjs-poster').width()
$('#info-video').css('top', ihead.offsetHeight + 'px')
$('#info-video-wrapper').css({
top: iframeplayer.el().style.top,
height: (ph - 30) + 'px',
left: '50%',
'margin-left': -(pw / 2) + 'px',
width: pw + 'px'
})
$('#overlay-footer').css({'top': pb + 'px'})
}

let show_info_video = function () { // Call by videojs-controllbar
const hasStarted = $(iframeplayer.el()).hasClass('vjs-has-started')
, isOverlayed = $('#div-video-wrapper').hasClass('overlay')
, isInfoOverlayed = isOverlayed && $('#div-video-wrapper').hasClass('info')
, cls = 'overlay info'
if (!isOverlayed) { // No overlay is displayed
wasPlaying = isPlaying;
iframeplayer.pause();
$('#div-video-wrapper').attr('class', cls)
resizeInfo()
} else if (!isInfoOverlayed) { // One overlay is displayed but not Info
$('#div-video-wrapper').attr('class', cls)
resizeInfo()
} else { // Info overlay is displayed => close
$('#div-video-wrapper').attr('class', (hasStarted ? '' : 'vjs-not-started'))
if (wasPlaying) iframeplayer.play();
}
}

$('#video-meta .tab-pane').addClass('show').show();

</script>
{% endif %}

Expand Down
137 changes: 123 additions & 14 deletions pod/live/templates/live/event-script.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{% load custom_tags %}
{% load i18n %}
{% load static %}
{% get_setting "USE_VIDEO_P2P" False as use_video_p2p %}
{% get_setting "P2P_TRACKERS" "" as p2p_trackers %}
{% get_setting "P2P_STUNS" "" as p2p_stuns %}
{% if use_video_p2p %}
<script src="{% static 'js/video-p2p-stats.js' %}?ver={{VERSION}}"></script>
{% endif %}
<script>
// Debug if necessary, depends on the settings_local
const debug = "{% get_setting "DEBUG" False %}" === "True";
Expand All @@ -14,13 +20,99 @@
let stopped = false;
let video_on_hold_is_displayed = false;
let recordingDuration = 0;

{% if use_video_p2p %}
var downloadTotals = { http: 0, p2p: 0 };
var uploadTotal = 0;
var nb_peers = 0;
{% endif %}

var VideoHlsjsConfig = {
maxBufferSize: 0,
maxBufferLength: 10,
liveSyncDurationCount: 10,
}
{% if use_video_p2p %}
const p2p_config = {
segments:{
// number of segments to pass for processing to P2P algorithm
forwardSegmentCount:50, // usually should be equal or greater than p2pDownloadMaxPriority and httpDownloadMaxPriority
swarmId: '{{ event.broadcaster.url }}',
},
loader:{
/** configure personal tracker and STUN servers */
trackerAnnounce: [
{% for tracker in p2p_trackers %}
"{{tracker}}"{% if not forloop.last %},{%endif%}
{% endfor %}
],
rtcConfig: {
iceServers: [
{% for stun in p2p_stuns %}
{ urls: "{{stun}}" }{% if not forloop.last %},{%endif%}
{% endfor %}
]
},
// how long to store the downloaded segments for P2P sharing
cachedSegmentExpiration:86400000,
// count of the downloaded segments to store for P2P sharing
cachedSegmentsCount:1000,

// first 4 segments (priorities 0, 1, 2 and 3) are required buffer for stable playback
requiredSegmentsPriority:3,

// each 1 second each of 10 segments ahead of playhead position gets 6% probability for random HTTP download
httpDownloadMaxPriority:9,
httpDownloadProbability:0.06,
httpDownloadProbabilityInterval: 1000,

// disallow randomly download segments over HTTP if there are no connected peers
httpDownloadProbabilitySkipIfNoPeers: true,

// P2P will try to download only first 51 segment ahead of playhead position
p2pDownloadMaxPriority: 50,

// 1 second timeout before retrying HTTP download of a segment in case of an error
httpFailedSegmentTimeout:1000,

// number of simultaneous downloads for P2P and HTTP methods
simultaneousP2PDownloads:20,
simultaneousHttpDownloads:3,

// enable mode, that try to prevent HTTP downloads on stream start-up
httpDownloadInitialTimeout: 120000, // try to prevent HTTP downloads during first 2 minutes
httpDownloadInitialTimeoutPerSegment: 17000, // try to prevent HTTP download per segment during first 17 seconds

// allow to continue aborted P2P downloads via HTTP
httpUseRanges: true,
}
};

if (p2pml.hlsjs.Engine.isSupported()) {
downloadTotals = { http: 0, p2p: 0 };
uploadTotal = 0;
nb_peers = 0;
engineHlsJs = new p2pml.hlsjs.Engine(p2p_config);
VideoHlsjsConfig["loader"] = engineHlsJs.createLoaderClass();
engineHlsJs.on(p2pml.core.Events.PeerConnect, onPeerConnect.bind(this));
engineHlsJs.on(p2pml.core.Events.PeerClose, onPeerClose.bind(this));
engineHlsJs.on(p2pml.core.Events.PieceBytesDownloaded, onBytesDownloaded.bind(this));
engineHlsJs.on(p2pml.core.Events.PieceBytesUploaded, onBytesUploaded.bind(this));
//engineHlsJs.on("segment_loaded", (segment, peerId) => console.log("segment_loaded from", peerId ? `peer ${peerId}` : "HTTP", segment.url));
}
{% endif %}


let options = {
notSupportedMessage: "{% trans 'Please use different browser' %} (Mozilla Firefox, Google Chrome, Safari, Microsoft Edge)",
language: "fr", //en or nl
fluid: !{{ request.GET.is_iframe|yesno:"true,false" }},
playbackRates: [0.5, 1, 1.5, 2],
errorDisplay: false,
loop: false
notSupportedMessage: "{% trans 'Please use different browser' %} (Mozilla Firefox, Google Chrome, Safari, Microsoft Edge)",
language: "fr", //en or nl
fluid: !{{ request.GET.is_iframe|yesno:"true,false" }},
//playbackRates: [0.5, 1, 1.5, 2],
errorDisplay: false,
loop: false,
html5: {
hlsjsConfig: VideoHlsjsConfig
},
}

/**
Expand Down Expand Up @@ -56,8 +148,8 @@
}

// Management of the end of the stream (for Firefox, Chrome... not working for Edge, Safari)
videojs.Hls.xhr.beforeRequest = function (options) {

/*videojs.Hls.xhr.beforeRequest = function (options) { */
videojs.Vhs.xhr.beforeRequest = (options) => {
if ('{{event.is_past }}' === 'False') {

// Reset counter if video state is ok
Expand Down Expand Up @@ -102,13 +194,26 @@
// Management of the streaming live
let player = videojs("podvideoplayer", options, function() {
});

{% if use_video_p2p %}
if (p2pml.hlsjs.Engine.isSupported()) {
p2pml.hlsjs.initVideoJsContribHlsJsPlayer(player);
}
{% endif %}
var srcOptions = {
src: '{{ event.broadcaster.url }}',
type: 'application/x-mpegURL',
};
//Add source to player
player.src(srcOptions);
player.videoJsLogo({
imgsrc: '{% static LOGO_PLAYER %}',
linktitle: '{{ TITLE_SITE }} - {% if LINK_PLAYER_NAME %}{{ LINK_PLAYER_NAME }}{% else %}{% trans "Home" %}{% endif %} - {% trans "New window" %}',
link: '{{ LINK_PLAYER }}'
});

//add quality selector to player
player.qualitySelectorHls({
displayCurrentQuality: true,
});
player.on("error", function() {
// Handle successives errors to avoid multiple reload
if (typeof (errored) == "undefined" || !errored) {
Expand Down Expand Up @@ -141,8 +246,10 @@

// dispose onHold resources
video_on_hold_is_displayed = false;
videojs(document.getElementById("divvideoonhold")).dispose();

let divvideoonhold = document.getElementById("divvideoonhold");
ptitloup marked this conversation as resolved.
Show resolved Hide resolved
if (divvideoonhold) {
videojs(document.getElementById("divvideoonhold")).dispose();
}
// Affichage du flux direct
started = true;
document.getElementById("divvideoplayer").style.display = "block";
Expand Down Expand Up @@ -653,7 +760,9 @@
});

let mp4_sources = {{event.video_on_hold.get_video_mp4_json|safe|default:'null'}};
playerOnHold.src(mp4_sources);
if(mp4_sources) {
playerOnHold.src(mp4_sources);
}

document.getElementById("divvideoonhold").style.display = "block";
if (document.getElementById("divvideoplayer"))
Expand Down Expand Up @@ -839,4 +948,4 @@
}, 1000);
}

</script>
</script>
ptitloup marked this conversation as resolved.
Show resolved Hide resolved
9 changes: 5 additions & 4 deletions pod/live/templates/live/event.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ <h3 id="livename" data-eventid="{{ event.id }}"><i class="bi bi-broadcast pe-2"
<video id="podvideoplayer"
class="video-js vjs-default-skin vjs-big-play-centered"
controls height="360" muted autoplay>
<source src="{{ event.broadcaster.url }}" type="application/x-mpegURL">
</video>
</div>
{% if event.aside_iframe_url %}
Expand Down Expand Up @@ -152,6 +151,10 @@ <h3 id="livename" data-eventid="{{ event.id }}"><i class="bi bi-broadcast pe-2"
{% if not request.GET.is_iframe %}
<div class="container-fluid">
<div class="row">
{% get_setting "USE_VIDEO_P2P" False as use_video_p2p %}
{% if use_video_p2p %}
{% include 'videos/video_p2p_stats.html' %}
{% endif %}
<h1 class="col-auto page_title pt-3 h2">
{{ event.title|capfirst }}
</h1>
Expand All @@ -161,13 +164,12 @@ <h1 class="col-auto page_title pt-3 h2">
title="{% trans 'Report the event' %}">
<i class="bi bi-exclamation-octagon" aria-hidden="true"></i>
</a>

{% if event.is_current and can_record %}
{% if can_manage_stream %}
<div id="stream_btns" class="col-auto border border-secondary rounded d-none" style="margin: 10px 10px 10px 0">
<button type="button" class="btn btn-outline-primary btn-sm border-0 m-1" disabled
id="startstream" title="{% trans 'Start stream' %}" aria-label="{% trans 'Start stream' %}"
data-url="{% url 'live:ajax_event_start_streaming'%}">
data-url="{% url 'live:ajax_event_start_streaming' %}">
<i class="bi bi-person-video" aria-hidden="true" style="font-size: 2em"></i>
</button>
<button type="button" class="btn btn-outline-primary btn-sm border-0 m-1" disabled
Expand Down Expand Up @@ -218,7 +220,6 @@ <h4>{% trans 'Current event videos' %}</h4>
<div id="event_videos_list"></div>
</div>
</div>

<div id="info-video-all">{% include 'live/event-all-info.html' %}</div>

{% endif %}
Expand Down
Binary file modified pod/locale/fr/LC_MESSAGES/django.mo
Binary file not shown.
Loading