dropin

alternative frontend for dropout.tv
git clone https://git.ce9e.org/dropin.git

commit
046cf93b088f9b35e7413eca7dd426c869567a78
parent
6464704cca092ab85485d4b087c475e16709508e
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2025-02-06 15:07
add quality switcher

Diffstat

M static/style.css 20 +++++++++++++++++++-
A static/video.js 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
M templates/video.html 4 +++-

3 files changed, 76 insertions, 2 deletions


diff --git a/static/style.css b/static/style.css

@@ -34,16 +34,22 @@ h1, h2 {
   34    34     line-height: 1.2;
   35    35 }
   36    36 
   -1    37 button,
   37    38 input {
   38    39     border: 1px solid var(--border);
   39    40     border-radius: 4px;
   40    -1     padding-block: 0.3em;
   -1    41     padding-block: 0.2em;
   41    42     padding-inline: 0.75em;
   42    43     font-family: inherit;
   43    44     font-size: inherit;
   44    45     line-height: 1.8;
   45    46 }
   46    47 
   -1    48 button {
   -1    49     background-color: var(--bg-intense);
   -1    50     color: var(--fg2);
   -1    51 }
   -1    52 
   47    53 body {
   48    54     padding: 0;
   49    55     margin: 0;
@@ -150,3 +156,15 @@ video {
  150   156     padding-block: 0.1em;
  151   157     font-size: 90%;
  152   158 }
   -1   159 
   -1   160 .quality {
   -1   161     display: flex;
   -1   162     gap: 0.5em;
   -1   163     margin-block: 0.5em;
   -1   164     padding-inline: 1em;
   -1   165     justify-content: center;
   -1   166     font-size: 90%;
   -1   167 }
   -1   168 .quality li {
   -1   169     display: inline-block;
   -1   170 }

diff --git a/static/video.js b/static/video.js

@@ -0,0 +1,54 @@
   -1     1 var video = document.querySelector('video');
   -1     2 
   -1     3 var h = function(tag, attrs, children) {
   -1     4     var el = document.createElement(tag);
   -1     5     for (const attr in attrs) {
   -1     6         el.setAttribute(attr, attrs[attr]);
   -1     7     }
   -1     8     for (const child of children) {
   -1     9         el.append(child);
   -1    10     }
   -1    11     return el;
   -1    12 };
   -1    13 
   -1    14 var applyQuality = function(quality, lazy) {
   -1    15     var source = video.querySelector(`[data-quality="${quality}"]`);
   -1    16     if (quality !== 'auto' && (!quality || !source)) {
   -1    17         return;
   -1    18     }
   -1    19     var time = video.currentTime;
   -1    20     var paused = video.paused;
   -1    21     if (quality === 'auto') {
   -1    22         video.removeAttribute('src');
   -1    23     } else {
   -1    24         video.src = source.src;
   -1    25     }
   -1    26     if (!lazy) {
   -1    27         video.load();
   -1    28     }
   -1    29     video.currentTime = time;
   -1    30     if (!paused) {
   -1    31         video.play();
   -1    32     }
   -1    33 };
   -1    34 
   -1    35 var createMenu = function() {
   -1    36     var sources = Array.from(video.querySelectorAll('source')).reverse();
   -1    37     var ul = h('ul', {'class': 'quality'}, sources.map(source => h('li', {}, [
   -1    38         h('button', {'type': 'button'}, [source.dataset.quality]),
   -1    39     ])));
   -1    40     ul.append(h('li', {}, [
   -1    41         h('button', {'type': 'button'}, ['auto']),
   -1    42     ]));
   -1    43     ul.addEventListener('click', event => {
   -1    44         if (event.target.type === 'button') {
   -1    45             var quality = event.target.textContent;
   -1    46             localStorage.setItem('quality', quality);
   -1    47             applyQuality(quality);
   -1    48         }
   -1    49     });
   -1    50     return ul;
   -1    51 };
   -1    52 
   -1    53 applyQuality(localStorage.getItem('quality'), true);
   -1    54 video.after(createMenu());

diff --git a/templates/video.html b/templates/video.html

@@ -5,7 +5,7 @@
    5     5 {% block content %}
    6     6     <video controls poster="{{ thumbnail.large }}" preload="none" crossorigin="anonymous">
    7     7         {% for file in files %}
    8    -1             <source type="{{ file.mime_type }}" src="{{ file._links.source.href }}">
   -1     8             <source type="{{ file.mime_type }}" src="{{ file._links.source.href }}" {% if file.quality != 'adaptive' %}media="(min-height: {{ file.quality }}x)"{% endif %} data-quality="{{ file.quality }}">
    9     9         {% endfor %}
   10    10         {% for track in tracks.subtitles %}
   11    11             <track kind="{{ track.kind }}" label="{{ track.label }}" srclang="{{ track.srclang }}" src="{{ track._links.vtt.href }}">
@@ -32,4 +32,6 @@
   32    32             </ul>
   33    33         {% endif %}
   34    34     </div>
   -1    35 
   -1    36     <script src="/static/video.js" type="module"></script>
   35    37 {% endblock %}