Implemented back-end for basic time-based queueing system.
This commit is contained in:
parent
f38eae170d
commit
4f6b3318a0
11 changed files with 329 additions and 140 deletions
|
|
@ -15,11 +15,15 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
||||
|
||||
class mediaHandler{
|
||||
constructor(client, player, media){
|
||||
constructor(client, player, media, type){
|
||||
//Get parents
|
||||
this.client = client;
|
||||
this.player = player;
|
||||
|
||||
//Set handler type
|
||||
this.type = type
|
||||
|
||||
//Set last received timestamp to 0
|
||||
this.lastTimestamp = 0;
|
||||
|
||||
//Ingest media object from server
|
||||
|
|
@ -122,7 +126,20 @@ class mediaHandler{
|
|||
class nullHandler extends mediaHandler{
|
||||
constructor(client, player){
|
||||
//Call derived constructor
|
||||
super(client, player, {});
|
||||
super(client, player, {}, null);
|
||||
|
||||
this.defineListeners();
|
||||
}
|
||||
|
||||
defineListeners(){
|
||||
//Disable right clicking
|
||||
this.video.addEventListener('contextmenu', (e)=>{e.preventDefault()});
|
||||
this.video.addEventListener('loadedmetadata', this.onMetadataLoad.bind(this));
|
||||
}
|
||||
|
||||
onMetadataLoad(event){
|
||||
//Resize aspect (if locked), since the video doesn't properly report it's resolution until it's been loaded
|
||||
this.client.chatBox.resizeAspect();
|
||||
}
|
||||
|
||||
start(){
|
||||
|
|
@ -133,7 +150,7 @@ class nullHandler extends mediaHandler{
|
|||
this.video.src = '/video/static.webm';
|
||||
|
||||
//Set video title manually
|
||||
this.player.title.textContent = 'Channel Off Air';
|
||||
this.player.title.textContent = 'Channel Off Air';
|
||||
|
||||
//play the placeholder video
|
||||
this.video.play();
|
||||
|
|
@ -143,16 +160,18 @@ class nullHandler extends mediaHandler{
|
|||
class rawFileHandler extends mediaHandler{
|
||||
constructor(client, player, media){
|
||||
//Call derived constructor
|
||||
super(client, player, media);
|
||||
super(client, player, media, 'raw');
|
||||
|
||||
//Since this media type has no way to tell between the user and code seek events, we need a flag to mark them
|
||||
this.selfSeek = false;
|
||||
//Since this media type has no way to tell between events that originate from either the user or code
|
||||
//That's what this boolean is for :P
|
||||
this.selfAct = false;
|
||||
|
||||
//Define listeners
|
||||
this.defineListeners();
|
||||
}
|
||||
|
||||
defineListeners(){
|
||||
this.video.addEventListener('loadedmetadata', this.onMetadataLoad.bind(this));
|
||||
this.video.addEventListener('pause', this.onPause.bind(this));
|
||||
this.video.addEventListener('seeking', this.onSeek.bind(this));
|
||||
}
|
||||
|
|
@ -180,37 +199,56 @@ class rawFileHandler extends mediaHandler{
|
|||
}
|
||||
|
||||
sync(timestamp = this.lastTimestamp){
|
||||
//Set self seek flag
|
||||
this.selfSeek = true;
|
||||
//Skip sync calls that won't seek so we don't pointlessly throw selfAct
|
||||
if(timestamp != this.video.currentTime){
|
||||
//Set self act flag
|
||||
this.selfAct = true;
|
||||
|
||||
//Set current video time based on timestamp received from server
|
||||
this.video.currentTime = timestamp;
|
||||
//Set current video time based on timestamp received from server
|
||||
this.video.currentTime = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
reload(){
|
||||
//Throw self seek flag to make sure we don't un-sync the player
|
||||
this.selfSeek = true;
|
||||
//Throw self act flag to make sure we don't un-sync the player
|
||||
this.selfAct = true;
|
||||
|
||||
//Call derived reload function
|
||||
super.reload();
|
||||
}
|
||||
|
||||
onMetadataLoad(event){
|
||||
//Resize aspect (if locked), since the video doesn't properly report it's resolution until it's been loaded
|
||||
this.client.chatBox.resizeAspect();
|
||||
}
|
||||
|
||||
onPause(event){
|
||||
this.player.unlockSync();
|
||||
//If the video was paused out-side of code
|
||||
if(!this.selfAct){
|
||||
this.player.unlockSync();
|
||||
}
|
||||
|
||||
this.selfAct = false;
|
||||
}
|
||||
|
||||
onSeek(event){
|
||||
//If the video was seeked out-side of code
|
||||
if(!this.selfSeek){
|
||||
if(!this.selfAct){
|
||||
this.player.unlockSync();
|
||||
}
|
||||
|
||||
//reset self seek flag
|
||||
this.selfSeek = false;
|
||||
//reset self act flag
|
||||
this.selfAct = false;
|
||||
}
|
||||
|
||||
getTimestamp(){
|
||||
//Return current timestamp
|
||||
return this.video.currentTime;
|
||||
}
|
||||
|
||||
end(){
|
||||
//Throw self act to prevent unlock on video end
|
||||
this.selfAct = true;
|
||||
super.end();
|
||||
}
|
||||
}
|
||||
|
|
@ -41,13 +41,12 @@ class player{
|
|||
this.reloadIcon = document.querySelector("#media-panel-reload-icon");
|
||||
|
||||
//Numbers
|
||||
this.syncTolerance = 1;
|
||||
this.syncTolerance = 0.4;
|
||||
this.syncDelta = 6;
|
||||
|
||||
//run setup functions
|
||||
this.setupInput();
|
||||
this.defineListeners();
|
||||
this.lockSync();
|
||||
}
|
||||
|
||||
setupInput(){
|
||||
|
|
@ -97,6 +96,9 @@ class player{
|
|||
}
|
||||
}
|
||||
|
||||
//Lock synchronization since everyone starts at 0, and update the UI
|
||||
this.lockSync();
|
||||
|
||||
//Re-size to aspect since video may now be a different size
|
||||
this.client.chatBox.resizeAspect();
|
||||
}
|
||||
|
|
@ -133,27 +135,32 @@ class player{
|
|||
|
||||
//Replace it with a null handler
|
||||
this.mediaHandler = new nullHandler(client, this);
|
||||
|
||||
//Re-lock sync since we're probably gonna start new media soon anywho, and we need to update the UI anywho
|
||||
this.lockSync();
|
||||
}
|
||||
|
||||
lockSync(){
|
||||
//Light up the sync icon to show that we're actively synchronized
|
||||
this.syncIcon.classList.add('positive');
|
||||
|
||||
//Enable syncing
|
||||
this.syncLock = true;
|
||||
|
||||
//If we have a media handler
|
||||
if(this.mediaHandler != null){
|
||||
if(this.mediaHandler != null && this.mediaHandler.type != null){
|
||||
//Light up the sync icon to show that we're actively synchronized
|
||||
this.syncIcon.classList.add('positive');
|
||||
|
||||
//Sync to last timestamp
|
||||
this.mediaHandler.sync();
|
||||
|
||||
//Play
|
||||
this.mediaHandler.play();
|
||||
}else{
|
||||
//Unlight the sync icon since there is nothing to sync
|
||||
this.syncIcon.classList.remove('positive');
|
||||
}
|
||||
}
|
||||
|
||||
unlockSync(){
|
||||
//Unlight the sync icon
|
||||
//Unlight the sync icon since we're no longer actively synced
|
||||
this.syncIcon.classList.remove('positive');
|
||||
|
||||
//Disable syncing
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue