Implemented back-end for basic time-based queueing system.

This commit is contained in:
rainbow napkin 2025-01-19 15:13:31 -05:00
parent f38eae170d
commit 4f6b3318a0
11 changed files with 329 additions and 140 deletions

View file

@ -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();
}
}

View file

@ -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