Integrate quality selection into Plyr

Signed-off-by: Jesús <heckyel@hyperbola.info>
This commit is contained in:
James Taylor 2021-08-25 14:47:57 -07:00 committed by Jesús
parent ee581c56a3
commit 9f44e0474b
No known key found for this signature in database
GPG Key ID: F6EE7BC59A315766
3 changed files with 117 additions and 29 deletions

View File

@ -11,6 +11,64 @@ default:
captionsActive = false;
}
var qualityOptions = [];
var qualityDefault;
for (var src of data['uni_sources']) {
qualityOptions.push(src.quality_string)
}
for (var src of data['pair_sources']) {
qualityOptions.push(src[0].quality_string)
}
if (data['using_pair_sources'])
qualityDefault = data['pair_sources'][data['pair_idx']][0].quality_string;
else if (data['uni_sources'].length != 0)
qualityDefault = data['uni_sources'][data['uni_idx']].quality_string;
else
qualityDefault = 'None';
// Fix plyr refusing to work with qualities that are strings
Object.defineProperty(Plyr.prototype, 'quality', {
set: function(input) {
const config = this.config.quality;
const options = this.options.quality;
if (!options.length) {
return;
}
// removing this line:
//let quality = [!is.empty(input) && Number(input), this.storage.get('quality'), config.selected, config.default].find(is.number);
// replacing with:
quality = input;
let updateStorage = true;
if (!options.includes(quality)) {
// Plyr sets quality to null at startup, resulting in the erroneous
// calling of this setter function with input = null, and the
// commented out code below would set the quality to something
// unrelated at startup. Comment out and just return.
return;
/*const value = closest(options, quality);
this.debug.warn(`Unsupported quality option: ${quality}, using ${value} instead`);
quality = value; // Don't update storage if quality is not supported
updateStorage = false;*/
} // Update config
config.selected = quality; // Set quality
this.media.quality = quality; // Save to storage
if (updateStorage) {
this.storage.set({
quality
});
}
}
});
const player = new Plyr(document.getElementById('js-video-player'), {
disableContextMenu: false,
captions: {
@ -32,5 +90,35 @@ const player = new Plyr(document.getElementById('js-video-player'), {
iconUrl: "/youtube.com/static/modules/plyr/plyr.svg",
blankVideo: "/youtube.com/static/modules/plyr/blank.webm",
debug: false,
storage: {enabled: false}
storage: {enabled: false},
quality: {
default: qualityDefault,
options: qualityOptions,
forced: true,
onChange: function(quality) {
if (quality == 'None')
return;
if (quality.includes('(integrated)')) {
for (var i=0; i < data['uni_sources'].length; i++) {
if (data['uni_sources'][i].quality_string == quality) {
changeQuality({'type': 'uni', 'index': i});
return;
}
}
} else {
for (var i=0; i < data['pair_sources'].length; i++) {
if (data['pair_sources'][i][0].quality_string == quality) {
changeQuality({'type': 'pair', 'index': i});
return;
}
}
}
},
},
settings: ['captions', 'quality', 'speed', 'loop'],
});
// Hide the external quality selector
window.addEventListener('DOMContentLoaded', function(){
document.getElementById('quality-select').hidden = true;
});

View File

@ -56,6 +56,30 @@
</figure>
<script src="/youtube.com/static/js/av-merge.js"></script>
<script>
function changeQuality(selection) {
var video = document.getElementById('js-video-player');
var currentVideoTime = video.currentTime;
var videoPaused = video.paused;
var videoSpeed = video.playbackRate;
var videoSource;
if (avMerge)
avMerge.close();
if (selection.type == 'uni'){
videoSource = data['uni_sources'][selection.index];
video.src = videoSource.url;
} else {
let srcPair = data['pair_sources'][selection.index];
videoSource = srcPair[0];
avInitialize(video, srcPair, currentVideoTime);
}
video.currentTime = currentVideoTime;
if (!videoPaused){
video.play();
}
video.playbackRate = videoSpeed;
}
</script>
{% if using_pair_sources %}
<!-- Initialize av-merge -->
<script>
@ -104,7 +128,7 @@
<script src="/youtube.com/static/js/speedyplay.js"></script>
<select id="quality-select">
{% for src in uni_sources %}
<option value='{"type": "uni", "index": {{ loop.index0 }}}' {{ 'selected' if loop.index0 == uni_idx and not using_pair_sources else '' }} >{{ src['quality_string'] }} (integrated)</option>
<option value='{"type": "uni", "index": {{ loop.index0 }}}' {{ 'selected' if loop.index0 == uni_idx and not using_pair_sources else '' }} >{{ src['quality_string'] }}</option>
{% endfor %}
{% for src_pair in pair_sources %}
<option value='{"type": "pair", "index": {{ loop.index0}}}' {{ 'selected' if loop.index0 == pair_idx and using_pair_sources else '' }} >{{ src_pair[0]['quality_string'] }}, {{ src_pair[1]['quality_string'] }}</option>
@ -113,28 +137,7 @@
<script>
document.getElementById('quality-select').addEventListener(
'change', function(e) {
var video = document.getElementById('js-video-player');
var selection = JSON.parse(this.value);
var currentVideoTime = video.currentTime;
var videoPaused = video.paused;
var videoSpeed = video.playbackRate;
var videoSource;
if (avMerge)
avMerge.close();
if (selection.type == 'uni'){
videoSource = data['uni_sources'][selection.index];
video.src = videoSource.url;
} else {
let srcPair = data['pair_sources'][selection.index];
videoSource = srcPair[0];
avInitialize(video, srcPair, currentVideoTime);
}
setVideoDimensions(videoSource.height, videoSource.width);
video.currentTime = currentVideoTime;
if (!videoPaused){
video.play();
}
video.playbackRate = videoSpeed;
changeQuality(JSON.parse(this.value))
}
);
</script>
@ -445,11 +448,6 @@
</div>
<script>
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
data = {{ js_data|tojson }};
// @license-end
</script>
<script src="/youtube.com/static/js/common.js"></script>
<script src="/youtube.com/static/js/transcript-table.js"></script>
{% if settings.use_video_player == 2 %}

View File

@ -48,6 +48,7 @@ def get_video_sources(info):
'type': 'video/' + fmt['ext'],
'quality_string': short_video_quality_string(fmt),
}
source['quality_string'] += ' (integrated)'
source.update(fmt)
uni_sources.append(source)
continue
@ -661,6 +662,7 @@ def get_watch_page(video_id=None):
'settings': settings.current_settings_dict,
'has_manual_captions': any(s.get('on') for s in subtitle_sources),
**source_info,
'using_pair_sources': using_pair_sources,
},
font_family=youtube.font_choices[settings.font],
**source_info,