diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 978ce426d..f250a1969 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -69,7 +69,7 @@ jobs: - name: Generate dependencies run: | - python -m pip install --upgrade pip py setuptools wheel requirements-builder + python -m pip install --upgrade pip py "setuptools<82" wheel requirements-builder requirements-builder -e $EXTRAS --level=pypi setup.py > .pypi-${{ matrix.python-version }}-requirements.txt - name: Cache pip diff --git a/cds/modules/previewer/templates/cds_previewer/macros/player.html b/cds/modules/previewer/templates/cds_previewer/macros/player.html index 9f849024a..aa165dcd7 100644 --- a/cds/modules/previewer/templates/cds_previewer/macros/player.html +++ b/cds/modules/previewer/templates/cds_previewer/macros/player.html @@ -201,6 +201,130 @@ player.currentTime = startTime; } })(); + + // Keyboard shortcuts + (function() { + var SEEK_STEP = 5; + var VOLUME_STEP = 0.05; + + function togglePlay() { + if (player.paused) { + player.play(); + } else { + player.pause(); + } + } + + function rewind() { + var timeToSeek = Math.max(0, player.currentTime - SEEK_STEP); + player.currentTime = timeToSeek; + } + + function forward() { + var timeToSeek = Math.min(player.duration || 0, player.currentTime + SEEK_STEP); + player.currentTime = timeToSeek; + } + + function increaseVolume() { + player.volume = Math.min(1, player.volume + VOLUME_STEP); + } + + function decreaseVolume() { + player.volume = Math.max(0, player.volume - VOLUME_STEP); + } + + function toggleFullScreen() { + if (player.presentation.currentMode === 'fullscreen') { + player.presentation.requestMode('inline'); + } else { + player.presentation.requestMode('fullscreen'); + } + } + + function toggleSubtitles() { + var tracks = player.textTracks; + for (var i = 0; i < tracks.length; i++) { + var t = tracks[i]; + if (t.kind === 'subtitles' || t.kind === 'captions') { + t.mode = (t.mode === 'showing') ? 'hidden' : 'showing'; + return; + } + } + } + + function toggleMute() { + player.muted = !player.muted; + } + + function handleKeydown(e) { + // Ignore typing in form fields + var tag = (e.target.tagName || '').toLowerCase(); + if ( + tag === 'input' || + tag === 'textarea' || + tag === 'select' || + e.target.isContentEditable + ) { + return; + } + + var key = e.key; + var action = false; + + switch (key) { + case ' ': + case 'Spacebar': // legacy support + togglePlay(); + action = true; + break; + + case 'ArrowLeft': + rewind(); + action = true; + break; + + case 'ArrowRight': + forward(); + action = true; + break; + + case 'ArrowUp': + increaseVolume(); + action = true; + break; + + case 'ArrowDown': + decreaseVolume(); + action = true; + break; + + case 'f': + case 'F': + toggleFullScreen(); + action = true; + break; + + case 'c': + case 'C': + toggleSubtitles(); + action = true; + break; + + case 'm': + case 'M': + toggleMute(); + action = true; + break; + } + + if (action) { + e.preventDefault(); + e.stopPropagation(); + } + } + + document.addEventListener('keydown', handleKeydown); + })(); {% endif %} {%- endmacro %} diff --git a/scripts/bootstrap b/scripts/bootstrap index 6b6e7370f..eee534d9c 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -29,6 +29,7 @@ script_path=$(dirname "$0") requirements_file=${1:-'requirements.txt'} +pip install "setuptools<82" pip install -r $requirements_file pip install -e . --upgrade