Add additional video player keyboard shortcuts (#275)

*  Skip forward 10 seconds ((CMD OR CTRL) ALT right)
 Skip back 10 seconds ((CMD OR CTRL) ALT left)
 Increase video speed ((CMD OR CTRL) +)
 Decrease video speed ((CMD OR CTRL) -)

* Codestyle fix

* The 'steps' should be implemented in base2, standard players use 1x, 2x, 4x, 8x, 16x

fixed bug with shift + "=" which is "+"

* resolve conflicts

* remove ide specific data
make playback rate more granular
add to menu skip and speed entries

* intendation fix

* conflict resolve

* rename setPlaybackRate to changePlaybackRate
setRate return boolean depending on whether this cast target supports setting the playback rate.
if setRate returns false - don`t change state
redundant else if statement in changePlaybackRate function
This commit is contained in:
Sergey Bargamon
2016-05-23 10:15:57 +03:00
committed by DC
parent ffce76a9b1
commit 8af4f42c42
8 changed files with 126 additions and 4 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,2 @@
node_modules
dist
dist

View File

@@ -92,6 +92,30 @@ function openSubtitles () {
}
}
function skipForward () {
if (windows.main) {
windows.main.send('dispatch', 'skip', 1)
}
}
function skipBack () {
if (windows.main) {
windows.main.send('dispatch', 'skip', -1)
}
}
function increasePlaybackRate () {
if (windows.main) {
windows.main.send('dispatch', 'changePlaybackRate', 1)
}
}
function decreasePlaybackRate () {
if (windows.main) {
windows.main.send('dispatch', 'changePlaybackRate', -1)
}
}
function onWindowShow () {
log('onWindowShow')
getMenuItem('Full Screen').enabled = true
@@ -110,6 +134,10 @@ function onPlayerOpen () {
getMenuItem('Increase Volume').enabled = true
getMenuItem('Decrease Volume').enabled = true
getMenuItem('Add Subtitles File...').enabled = true
getMenuItem('Skip forward 10 seconds').enabled = true
getMenuItem('Skip back 10 seconds').enabled = true
getMenuItem('Increase video speed').enabled = true
getMenuItem('Decrease video speed').enabled = true
}
function onPlayerClose () {
@@ -118,6 +146,10 @@ function onPlayerClose () {
getMenuItem('Increase Volume').enabled = false
getMenuItem('Decrease Volume').enabled = false
getMenuItem('Add Subtitles File...').enabled = false
getMenuItem('Skip forward 10 seconds').enabled = false
getMenuItem('Skip back 10 seconds').enabled = false
getMenuItem('Increase video speed').enabled = false
getMenuItem('Decrease video speed').enabled = false
}
function onToggleFullScreen (isFullScreen) {
@@ -311,6 +343,36 @@ function getAppMenuTemplate () {
label: 'Add Subtitles File...',
click: openSubtitles,
enabled: false
},
{
type: 'separator'
},
{
label: 'Skip forward 10 seconds',
accelerator: 'CmdOrCtrl+Alt+Right',
click: skipForward,
enabled: false
},
{
label: 'Skip back 10 seconds',
accelerator: 'CmdOrCtrl+Alt+Left',
click: skipBack,
enabled: false
},
{
type: 'separator'
},
{
label: 'Increase video speed',
accelerator: 'CmdOrCtrl+plus',
click: increasePlaybackRate,
enabled: false
},
{
label: 'Decrease video speed',
accelerator: 'CmdOrCtrl+-',
click: decreasePlaybackRate,
enabled: false
}
]
},

View File

@@ -748,6 +748,13 @@ body.drag .app::after {
padding: 5px;
margin: 0 auto;
}
.player-controls .rate {
display: inline;
height: 30px;
padding: 5px;
margin-left: 20px;
float: left;
}
.player-controls .device,
.player-controls .fullscreen,

View File

@@ -285,6 +285,12 @@ function dispatch (action, ...args) {
if (action === 'playbackJump') {
jumpToTime(args[0] /* seconds */)
}
if (action === 'skip') {
jumpToTime(state.playing.currentTime + (args[0] /* direction */ * 10))
}
if (action === 'changePlaybackRate') {
changePlaybackRate(args[0] /* direction */)
}
if (action === 'changeVolume') {
changeVolume(args[0] /* increase */)
}
@@ -399,7 +405,26 @@ function jumpToTime (time) {
state.playing.jumpToTime = time
}
}
function changePlaybackRate (direction) {
var rate = state.playing.playbackRate
if (direction > 0 && rate >= 0.25 && rate < 2) {
rate += 0.25
} else if (direction < 0 && rate > 0.25 && rate <= 2) {
rate -= 0.25
} else if (direction < 0 && rate === 0.25) { /* when we set playback rate at 0 in html 5, playback hangs ;( */
rate = -1
} else if (direction > 0 && rate === -1) {
rate = 0.25
} else if ((direction > 0 && rate >= 1 && rate < 16) || (direction < 0 && rate > -16 && rate <= -1)) {
rate *= 2
} else if ((direction < 0 && rate > 1 && rate <= 16) || (direction > 0 && rate >= -16 && rate < -1)) {
rate /= 2
}
state.playing.playbackRate = rate
if (lazyLoadCast().isCasting() && !Cast.setRate(rate)) {
state.playing.playbackRate = 1
}
}
function changeVolume (delta) {
// change volume with delta value
setVolume(state.playing.volume + delta)

View File

@@ -8,7 +8,8 @@ module.exports = {
play,
pause,
seek,
setVolume
setVolume,
setRate
}
var airplay = require('airplay-js')
@@ -344,6 +345,22 @@ function pause () {
}
}
function setRate (rate) {
var device
var result = true
if (state.playing.location === 'chromecast') {
// TODO find how to control playback rate on chromecast
castCallback()
result = false
} else if (state.playing.location === 'airplay') {
device = state.devices.airplay
device.rate(rate, castCallback)
} else {
result = false
}
return result
}
function seek (time) {
var device = getDevice()
if (device) {

View File

@@ -80,6 +80,7 @@ function getDefaultPlayState () {
isStalled: false,
lastTimeUpdate: 0, /* Unix time in ms */
mouseStationarySince: 0, /* Unix time in ms */
playbackRate: 1,
subtitles: {
tracks: [], /* subtitle tracks, each {label, language, ...} */
selectedIndex: -1, /* current subtitle track */

View File

@@ -26,7 +26,8 @@ function App (state) {
state.playing.mouseStationarySince !== 0 &&
new Date().getTime() - state.playing.mouseStationarySince > 2000 &&
!state.playing.isPaused &&
state.playing.location === 'local'
state.playing.location === 'local' &&
state.playing.playbackRate === 1
// Hide the header on Windows/Linux when in the player
// On OSX, the header appears as part of the title bar

View File

@@ -48,6 +48,9 @@ function renderMedia (state) {
mediaElement.currentTime = state.playing.jumpToTime
state.playing.jumpToTime = null
}
if (state.playing.playbackRate !== mediaElement.playbackRate) {
mediaElement.playbackRate = state.playing.playbackRate
}
// Set volume
if (state.playing.setVolume !== null && isFinite(state.playing.setVolume)) {
mediaElement.volume = state.playing.setVolume
@@ -440,6 +443,12 @@ function renderPlayerControls (state) {
</span>
`)
// render playback rate
if (state.playing.playbackRate !== 1) {
elements.push(hx`
<span class="rate">speed: ${state.playing.playbackRate}X</span>
`)
}
// Finally, the big button in the center plays or pauses the video
elements.push(hx`
<i class='icon play-pause' onclick=${dispatcher('playPause')}>