Implemented seeking and settings persistence
This commit is contained in:
parent
c4569c46b5
commit
069d746871
181
multiplayer.js
181
multiplayer.js
@ -296,6 +296,17 @@
|
||||
// the progress bar
|
||||
this._progressPopup = null;
|
||||
|
||||
// all subtitle selection buttons
|
||||
this._subtitleChoices = [];
|
||||
|
||||
// all resolution selection buttons
|
||||
this._resolutionChoices = [];
|
||||
|
||||
// the mute toggle
|
||||
this._volumeButton = null;
|
||||
|
||||
// the volume slider
|
||||
this._volumeSlider = null;
|
||||
|
||||
// prepare shadow root
|
||||
this.attachShadow({'mode': 'open'});
|
||||
@ -322,7 +333,7 @@
|
||||
'canvas', {id: 'buffer'});
|
||||
this._progressBar = this._progressContainer.createChild(
|
||||
'div', {id: 'progress'});
|
||||
this._progressPopup = this._progressBar.createChild(
|
||||
this._progressPopup = this._progressContainer.createChild(
|
||||
'div', {id: 'progress-popup'});
|
||||
|
||||
this.initLeftControls(controlRoot.createChild(
|
||||
@ -472,7 +483,7 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
const volumeButton = parent.createChild(
|
||||
this._volumeButton = parent.createChild(
|
||||
'button',
|
||||
{'id': 'volume-button',
|
||||
'title': 'Stäng av ljud',
|
||||
@ -481,28 +492,34 @@
|
||||
'data-title_alt_en': 'Unmute'},
|
||||
[createIcon(['volume', 'mute'])]);
|
||||
|
||||
const volumeSlider = parent.createChild('input',
|
||||
this._volumeSlider = parent.createChild('input',
|
||||
{'id': 'volume',
|
||||
'type': 'range',
|
||||
'min': '0',
|
||||
'max': '1',
|
||||
'step': '0.01'});
|
||||
volumeSlider.value = 1;
|
||||
this._volumeSlider.value = 1;
|
||||
|
||||
volumeButton.addEventListener('click', (event) => {
|
||||
console.log(volumeButton);
|
||||
this._volumeButton.addEventListener('click', (event) => {
|
||||
const audio = this._audioSource;
|
||||
if(!audio.muted) {
|
||||
volumeSlider.setAttribute('value', 0);
|
||||
this._volumeSlider.value = 0;
|
||||
audio.muted = true;
|
||||
localStorage.setItem('multi-player-muted', true);
|
||||
} else {
|
||||
volumeSlider.value = audio.volume;
|
||||
this._volumeSlider.value = audio.volume;
|
||||
audio.muted = false;
|
||||
localStorage.removeItem('multi-player-muted');
|
||||
}
|
||||
this.toggleButtonState(volumeButton);
|
||||
this.toggleButtonState(this._volumeButton);
|
||||
});
|
||||
volumeSlider.addEventListener('input', (event) => {
|
||||
this._audioSource.volume = volumeSlider.valueAsNumber;
|
||||
this._volumeSlider.addEventListener('input', (event) => {
|
||||
const volume = this._volumeSlider.valueAsNumber;
|
||||
this._audioSource.volume = volume;
|
||||
if(this._audioSource.muted === true) {
|
||||
this._volumeButton.click();
|
||||
}
|
||||
localStorage.setItem('multi-player-volume', volume);
|
||||
});
|
||||
|
||||
this._elapsed = parent.createChild('span', {'id': 'elapsed'});
|
||||
@ -577,11 +594,6 @@
|
||||
const defaultRes = 0;
|
||||
const token = presentation.token;
|
||||
this.setResolutions(resolutions, defaultRes);
|
||||
if(presentation.subtitles) {
|
||||
this.setSubtitles(Object.keys(presentation.subtitles));
|
||||
} else {
|
||||
this._subtitlesSelect.classList.add('hidden');
|
||||
}
|
||||
|
||||
// create streams
|
||||
const streams = presentation.sources;
|
||||
@ -662,13 +674,20 @@
|
||||
event.currentTarget.querySelector('video'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(presentation.subtitles) {
|
||||
this.setSubtitles(Object.keys(presentation.subtitles));
|
||||
} else {
|
||||
this._subtitlesSelect.classList.add('hidden');
|
||||
}
|
||||
|
||||
this.setActivePlaylistItem();
|
||||
this.autoBlurControls();
|
||||
this.initProgressTracking();
|
||||
this.initProgressContainer();
|
||||
this.initBuffer();
|
||||
|
||||
this.recallSettings();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -709,20 +728,51 @@
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up progress tracking
|
||||
* Set up progress container with progress tracking, seeking etc.
|
||||
*/
|
||||
initProgressTracking() {
|
||||
this._controlSource.addEventListener(
|
||||
'timeupdate', (event) => {
|
||||
const elapsed = this._controlSource.currentTime;
|
||||
this._elapsed.textContent = this.formatTime(elapsed);
|
||||
const progressWidth = (
|
||||
elapsed
|
||||
/ this._controlSource.duration
|
||||
* this._progressContainer.clientWidth);
|
||||
this._progressBar.style.width = progressWidth + 'px';
|
||||
initProgressContainer() {
|
||||
// Initialize hover timestamp popup
|
||||
const popup = this._progressContainer.querySelector(
|
||||
'#progress-popup');
|
||||
this._progressContainer.addEventListener('mousemove', (event) => {
|
||||
const bounds =
|
||||
this._progressContainer.getBoundingClientRect();
|
||||
const xRel = event.clientX - bounds.x;
|
||||
const fraction = xRel / this._progressContainer.clientWidth;
|
||||
const time = fraction * this._controlSource.duration;
|
||||
popup.textContent = this.formatTime(time);
|
||||
|
||||
const margin = popup.clientWidth / 2;
|
||||
const xmax = this._progressContainer.clientWidth - margin;
|
||||
let pos = xRel;
|
||||
if(pos < margin) {
|
||||
pos = margin;
|
||||
} else if(pos > xmax) {
|
||||
pos = xmax;
|
||||
}
|
||||
);
|
||||
popup.style.left = pos + 'px';
|
||||
});
|
||||
|
||||
// Enable seeking
|
||||
this._progressContainer.addEventListener('click', (event) => {
|
||||
const bounds =
|
||||
this._progressContainer.getBoundingClientRect();
|
||||
const xRel = event.clientX - bounds.x;
|
||||
const fraction = xRel / this._progressContainer.clientWidth;
|
||||
const time = fraction * this._controlSource.duration;
|
||||
this.setTime(time);
|
||||
});
|
||||
|
||||
// Initialize progressbar
|
||||
this._controlSource.addEventListener('timeupdate', (event) => {
|
||||
const elapsed = this._controlSource.currentTime;
|
||||
this._elapsed.textContent = this.formatTime(elapsed);
|
||||
const progressWidth = (
|
||||
elapsed
|
||||
/ this._controlSource.duration
|
||||
* this._progressContainer.clientWidth);
|
||||
this._progressBar.style.width = progressWidth + 'px';
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@ -767,6 +817,54 @@
|
||||
window.requestAnimationFrame(paintBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply any saved settings from previous usage
|
||||
*/
|
||||
recallSettings() {
|
||||
// Set subtitles state
|
||||
const savedState = localStorage.getItem(
|
||||
'multi-player-subs-state');
|
||||
if(savedState === 'showing') {
|
||||
const savedTrack = localStorage.getItem(
|
||||
'multi-player-subs-track');
|
||||
let found = false;
|
||||
this._subtitleChoices.forEach((button) => {
|
||||
if(savedTrack === button.textContent) {
|
||||
button.click();
|
||||
found = true;
|
||||
}
|
||||
});
|
||||
if(!found) {
|
||||
this._subtitleChoices[0].click();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply saved volume
|
||||
const savedLevel = localStorage.getItem('multi-player-volume');
|
||||
if(savedLevel !== null) {
|
||||
this._volumeSlider.value = savedLevel;
|
||||
this._audioSource.volume = savedLevel;
|
||||
}
|
||||
|
||||
// Apply saved mute state
|
||||
const muted = localStorage.getItem('multi-player-muted');
|
||||
if(muted) {
|
||||
this._volumeButton.click();
|
||||
}
|
||||
|
||||
// Apply saved resolution choice
|
||||
const savedResolution = localStorage.getItem(
|
||||
'multi-player-resolution');
|
||||
if(savedResolution) {
|
||||
this._resolutionChoices.forEach((button) => {
|
||||
if(button.textContent === savedResolution) {
|
||||
button.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
//¤¤¤
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the playlist to reflect which item is playing
|
||||
*
|
||||
@ -818,9 +916,9 @@
|
||||
resolutions.reverse(),
|
||||
resolutions.length - defaultIndex - 1);
|
||||
const current = select.querySelector('#resolution-current');
|
||||
const buttons = select.querySelectorAll(
|
||||
this._resolutionChoices = select.querySelectorAll(
|
||||
'#resolution-list button');
|
||||
buttons.forEach((button) => {
|
||||
this._resolutionChoices.forEach((button) => {
|
||||
button.addEventListener('click', (event) => {
|
||||
const res = event.currentTarget.textContent;
|
||||
const time = this._mainSource.currentTime;
|
||||
@ -841,6 +939,7 @@
|
||||
if(!paused) {
|
||||
this.togglePlayback();
|
||||
}
|
||||
localStorage.setItem('multi-player-resolution', res);
|
||||
});
|
||||
});
|
||||
|
||||
@ -876,8 +975,16 @@
|
||||
} else {
|
||||
track.mode = 'disabled';
|
||||
}
|
||||
localStorage.setItem('multi-player-subs-state',
|
||||
track.mode);
|
||||
this.toggleButtonState(select);
|
||||
});
|
||||
|
||||
const savedState = localStorage.getItem(
|
||||
'multi-player-subs-state');
|
||||
if(savedState === 'showing') {
|
||||
select.click();
|
||||
}
|
||||
} else {
|
||||
select = createElement('div', {'id': 'subtitles-select',
|
||||
'class': 'select'});
|
||||
@ -908,8 +1015,9 @@
|
||||
'data-choice': 'off'},
|
||||
['Av']);
|
||||
|
||||
const buttons = list.querySelectorAll('button');
|
||||
buttons.forEach((button) => {
|
||||
this._subtitleChoices = list.querySelectorAll('button');
|
||||
console.log('foo', this._subtitleChoices);
|
||||
this._subtitleChoices.forEach((button) => {
|
||||
button.addEventListener('click', (event) => {
|
||||
const choice = event.currentTarget.dataset.choice;
|
||||
if(choice === current.dataset.subtitlesState) {
|
||||
@ -929,10 +1037,17 @@
|
||||
current.title = current.dataset.titleOff;
|
||||
onIcon.classList.add('hidden');
|
||||
offIcon.classList.remove('hidden');
|
||||
localStorage.setItem('multi-player-subs-state',
|
||||
'disabled');
|
||||
localStorage.removeItem('multi-player-subs-track');
|
||||
} else {
|
||||
current.title = choice;
|
||||
offIcon.classList.add('hidden');
|
||||
onIcon.classList.remove('hidden');
|
||||
localStorage.setItem('multi-player-subs-state',
|
||||
'showing');
|
||||
localStorage.setItem('multi-player-subs-track',
|
||||
choice);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user