Started work on HLS Livestreaming. Created basic HLS Livestream Media Handler.
This commit is contained in:
parent
c6de68b474
commit
dd00a11b92
6 changed files with 208 additions and 72 deletions
|
|
@ -141,6 +141,10 @@ class mediaHandler{
|
|||
//reset self act flag
|
||||
this.selfAct = false;
|
||||
}
|
||||
|
||||
onBuffer(){
|
||||
this.selfAct = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Basic building blocks for anything that touches a <video> tag
|
||||
|
|
@ -184,7 +188,7 @@ class rawFileBase extends mediaHandler{
|
|||
this.video.load();
|
||||
|
||||
//Set it back to the proper time
|
||||
this.video.currentTime = timestamp;
|
||||
this.video.currentTime = this.lastTimestamp;
|
||||
|
||||
//Play the video
|
||||
this.video.play();
|
||||
|
|
@ -234,18 +238,22 @@ class nullHandler extends rawFileBase{
|
|||
}
|
||||
|
||||
start(){
|
||||
//call derived start function
|
||||
super.start();
|
||||
|
||||
//Lock the player
|
||||
this.setPlayerLock(true);
|
||||
|
||||
//Set the static placeholder
|
||||
this.video.src = '/video/static.webm';
|
||||
|
||||
//Set video title manually
|
||||
this.player.title.textContent = 'Channel Off Air';
|
||||
|
||||
//play the placeholder video
|
||||
this.video.play();
|
||||
}
|
||||
|
||||
setVideoTitle(title){
|
||||
this.player.title.textContent = `Channel Off Air`;
|
||||
}
|
||||
}
|
||||
|
||||
//Basic building blocks needed for proper time-synchronized raw-file playback
|
||||
|
|
@ -263,10 +271,14 @@ class rawFileHandler extends rawFileBase{
|
|||
super.defineListeners();
|
||||
|
||||
this.video.addEventListener('pause', this.onPause.bind(this));
|
||||
this.video.addEventListener('seeking', this.onSeek.bind(this));
|
||||
this.video.addEventListener('seeked', this.onSeek.bind(this));
|
||||
this.video.addEventListener('waiting', this.onBuffer.bind(this));
|
||||
}
|
||||
|
||||
start(){
|
||||
//Call derived start
|
||||
super.start();
|
||||
|
||||
//Set video
|
||||
this.video.src = this.nowPlaying.rawLink;
|
||||
|
||||
|
|
@ -505,7 +517,7 @@ class hlsBase extends rawFileBase{
|
|||
}
|
||||
|
||||
buildPlayer(){
|
||||
//Call derived player
|
||||
//Call derived buildPlayer function
|
||||
super.buildPlayer();
|
||||
|
||||
//Instantiate HLS object
|
||||
|
|
@ -522,6 +534,14 @@ class hlsBase extends rawFileBase{
|
|||
}
|
||||
|
||||
onMetadataLoad(){
|
||||
//Call derived method
|
||||
super.onMetadataLoad();
|
||||
}
|
||||
|
||||
start(){
|
||||
//Call derived method
|
||||
super.start();
|
||||
|
||||
//Start the video
|
||||
this.video.play();
|
||||
}
|
||||
|
|
@ -531,5 +551,74 @@ class hlsLiveStreamHandler extends hlsBase{
|
|||
constructor(client, player, media){
|
||||
//Call derived constructor
|
||||
super(client, player, media, "livehls");
|
||||
|
||||
//Create variable to determine if we need to resync after next seek
|
||||
this.reSync = false;
|
||||
|
||||
this.video.addEventListener('pause', this.onPause.bind(this));
|
||||
this.video.addEventListener('seeked', this.onSeek.bind(this));
|
||||
this.video.addEventListener('waiting', this.onBuffer.bind(this));
|
||||
}
|
||||
|
||||
sync(){
|
||||
//Kick the video back on if it was paused
|
||||
this.video.play();
|
||||
|
||||
//Pull video duration
|
||||
const duration = this.video.duration;
|
||||
|
||||
//Ignore bad timestamps
|
||||
if(duration > 0){
|
||||
//Seek to the end to sync up w/ the livestream
|
||||
this.video.currentTime = duration;
|
||||
}
|
||||
}
|
||||
|
||||
setVideoTitle(title){
|
||||
//Add title as text content for security :P
|
||||
this.player.title.textContent = `: ${title}`;
|
||||
|
||||
//Create glow span
|
||||
const glowSpan = document.createElement('span');
|
||||
//Fill glow span content
|
||||
glowSpan.textContent = "🔴LIVE";
|
||||
//Set glowspan class
|
||||
glowSpan.classList.add('critical-danger-text');
|
||||
|
||||
//Inject glowspan into title in a way that allows it to be easily replaced
|
||||
this.player.title.prepend(glowSpan);
|
||||
}
|
||||
|
||||
onBuffer(event){
|
||||
//Call derived function
|
||||
super.onBuffer(event);
|
||||
|
||||
|
||||
//If we're synced by the end of buffering
|
||||
if(this.player.syncLock){
|
||||
//Throw flag to manually sync since this works entirely differently from literally every other fucking media source
|
||||
this.reSync = true;
|
||||
}
|
||||
}
|
||||
|
||||
onSeek(event){
|
||||
//Call derived method
|
||||
super.onSeek(event);
|
||||
|
||||
//Calculate distance to end of stream
|
||||
const difference = this.video.duration - this.video.currentTime;
|
||||
|
||||
|
||||
//If we where buffering under sync lock
|
||||
if(this.reSync){
|
||||
//Set reSync to false
|
||||
this.reSync = false;
|
||||
|
||||
//If the difference is bigger than streamSyncTolerance
|
||||
if(difference > this.player.streamSyncTolerance){
|
||||
//Sync manually since we have no timestamp, and therefore the player won't do it for us
|
||||
this.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,8 @@ class player{
|
|||
|
||||
//Numbers
|
||||
this.syncTolerance = 0.4;
|
||||
//Might seem weird to keep this here instead of the HLS handler, but remember we may want to support other livestream services in the future...
|
||||
this.streamSyncTolerance = 2;
|
||||
this.syncDelta = 6;
|
||||
this.volume = 1;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue