mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Support for faster playback rates.
The HTML5 video element already has a well-supported "playbackRate" attribute which can be used to increase playback rate. This change wires up that control to be displayed in the Jellyfish web player. The playback rates offered are between 0.5x and 2x in 0.25x increments, which matches the YouTube player. This change also wires up the ">" and "<" key events to increase and decrease the playback rate, which mirrors the keyboard shortcuts supported by YouTube.
This commit is contained in:
parent
dc682bce17
commit
afa56c18af
6 changed files with 122 additions and 0 deletions
|
@ -1112,6 +1112,52 @@ class PlaybackManager {
|
|||
}
|
||||
};
|
||||
|
||||
self.increasePlaybackRate = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (player) {
|
||||
let current = self.getPlaybackRate(player);
|
||||
let supported = self.getSupportedPlaybackRates(player);
|
||||
|
||||
let index = -1;
|
||||
for (let i = 0, length = supported.length; i < length; i++) {
|
||||
if (supported[i].id === current) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = Math.min(index + 1, supported.length - 1);
|
||||
self.setPlaybackRate(supported[index].id, player);
|
||||
}
|
||||
};
|
||||
|
||||
self.decreasePlaybackRate = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (player) {
|
||||
let current = self.getPlaybackRate(player);
|
||||
let supported = self.getSupportedPlaybackRates(player);
|
||||
|
||||
let index = -1;
|
||||
for (let i = 0, length = supported.length; i < length; i++) {
|
||||
if (supported[i].id === current) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = Math.max(index - 1, 0);
|
||||
self.setPlaybackRate(supported[index].id, player);
|
||||
}
|
||||
};
|
||||
|
||||
self.getSupportedPlaybackRates = function (player) {
|
||||
player = player || self._currentPlayer;
|
||||
if (player && player.getSupportedPlaybackRates) {
|
||||
return player.getSupportedPlaybackRates();
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
let brightnessOsdLoaded;
|
||||
self.setBrightness = function (val, player) {
|
||||
player = player || self._currentPlayer;
|
||||
|
@ -3697,6 +3743,9 @@ class PlaybackManager {
|
|||
case 'SetAspectRatio':
|
||||
this.setAspectRatio(cmd.Arguments.AspectRatio, player);
|
||||
break;
|
||||
case 'PlaybackRate':
|
||||
this.setPlaybackRate(cmd.Arguments.PlaybackRate, player);
|
||||
break;
|
||||
case 'SetBrightness':
|
||||
this.setBrightness(cmd.Arguments.Brightness, player);
|
||||
break;
|
||||
|
|
|
@ -149,6 +149,28 @@ function showAspectRatioMenu(player, btn) {
|
|||
});
|
||||
}
|
||||
|
||||
function showPlaybackRateMenu(player, btn) {
|
||||
// each has a name and id
|
||||
const currentId = playbackManager.getPlaybackRate(player);
|
||||
const menuItems = playbackManager.getSupportedPlaybackRates(player).map(i => ({
|
||||
id: i.id,
|
||||
name: i.name,
|
||||
selected: i.id === currentId
|
||||
}));
|
||||
|
||||
return actionsheet.show({
|
||||
items: menuItems,
|
||||
positionTo: btn
|
||||
}).then(function (id) {
|
||||
if (id) {
|
||||
playbackManager.setPlaybackRate(id, player);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return Promise.reject();
|
||||
});
|
||||
}
|
||||
|
||||
function showWithUser(options, player, user) {
|
||||
var supportedCommands = playbackManager.getSupportedCommands(player);
|
||||
|
||||
|
@ -166,6 +188,17 @@ function showWithUser(options, player, user) {
|
|||
});
|
||||
}
|
||||
|
||||
if (supportedCommands.indexOf('PlaybackRate') !== -1) {
|
||||
const currentPlaybackRateId = playbackManager.getPlaybackRate(player);
|
||||
const currentPlaybackRate = playbackManager.getSupportedPlaybackRates(player).filter(i => i.id === currentPlaybackRateId)[0];
|
||||
|
||||
menuItems.push({
|
||||
name: globalize.translate('PlaybackRate'),
|
||||
id: 'playbackrate',
|
||||
asideText: currentPlaybackRate ? currentPlaybackRate.name : null
|
||||
});
|
||||
}
|
||||
|
||||
if (user && user.Policy.EnableVideoPlaybackTranscoding) {
|
||||
var secondaryQualityText = getQualitySecondaryText(player);
|
||||
|
||||
|
@ -230,6 +263,8 @@ function handleSelectedOption(id, options, player) {
|
|||
return showQualityMenu(player, options.positionTo);
|
||||
case 'aspectratio':
|
||||
return showAspectRatioMenu(player, options.positionTo);
|
||||
case 'playbackrate':
|
||||
return showPlaybackRateMenu(player, options.positionTo);
|
||||
case 'repeatmode':
|
||||
return showRepeatModeMenu(player, options.positionTo);
|
||||
case 'stats':
|
||||
|
|
|
@ -1243,6 +1243,12 @@ import 'css!assets/css/videoosd';
|
|||
}
|
||||
break;
|
||||
}
|
||||
case '>':
|
||||
playbackManager.increasePlaybackRate(currentPlayer);
|
||||
break;
|
||||
case '<':
|
||||
playbackManager.decreasePlaybackRate(currentPlayer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1634,6 +1634,31 @@ function tryRemoveElement(elem) {
|
|||
return null;
|
||||
}
|
||||
|
||||
getSupportedPlaybackRates() {
|
||||
return [{
|
||||
name: '0.5x',
|
||||
id: 0.5
|
||||
}, {
|
||||
name: '0.75x',
|
||||
id: 0.75
|
||||
}, {
|
||||
name: '1x',
|
||||
id: 1.0
|
||||
}, {
|
||||
name: '1.25x',
|
||||
id: 1.25
|
||||
}, {
|
||||
name: '1.5x',
|
||||
id: 1.5
|
||||
}, {
|
||||
name: '1.75x',
|
||||
id: 1.75
|
||||
}, {
|
||||
name: '2x',
|
||||
id: 2.0
|
||||
}];
|
||||
}
|
||||
|
||||
setVolume(val) {
|
||||
const mediaElement = this.#mediaElement;
|
||||
if (mediaElement) {
|
||||
|
|
|
@ -185,6 +185,12 @@ import appHost from 'apphost';
|
|||
'changezoom': () => {
|
||||
playbackManager.toggleAspectRatio();
|
||||
},
|
||||
'increaseplaybackrate': () => {
|
||||
playbackManager.increasePlaybackRate();
|
||||
},
|
||||
'decreaseplaybackrate': () => {
|
||||
playbackManager.decreasePlaybackRate();
|
||||
},
|
||||
'changeaudiotrack': () => {
|
||||
playbackManager.changeAudioStream();
|
||||
},
|
||||
|
|
|
@ -1220,6 +1220,7 @@
|
|||
"Play": "Play",
|
||||
"PlayAllFromHere": "Play all from here",
|
||||
"PlaybackData": "Playback Data",
|
||||
"PlaybackRate": "Playback Rate",
|
||||
"PlayCount": "Play count",
|
||||
"PlayFromBeginning": "Play from beginning",
|
||||
"PlayNext": "Play next",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue