mirror of
https://github.com/mifi/lossless-cut.git
synced 2024-11-22 02:12:30 +01:00
Implement partial speed control
J, K, L, however backward playing is not supported by chromium. Also bump electron to 1.4.5 And don't use electron-compile anymore as it doesn't really give us anything
This commit is contained in:
parent
95ed72edef
commit
2abacd010d
@ -24,7 +24,9 @@ Simple, cross platform video editor for lossless trimming / cutting of videos. G
|
||||
The original video files will not be modified. Instead it creates a lossless export in the same directory as the original file with from/to timestamps. Note that the cut is currently not precise around the cutpoints, so video before/after the nearest keyframe will be lost. EXIF data is preserved.
|
||||
|
||||
### Keyboard shortcuts
|
||||
- <kbd>SPACE</kbd> Play/pause
|
||||
- <kbd>SPACE</kbd>, <kbd>k</kbd> Play/pause
|
||||
- <kbd>j</kbd> Slow down video
|
||||
- <kbd>l</kbd> Speed up video
|
||||
- <kbd>←</kbd> Seek backward 1 sec
|
||||
- <kbd>→</kbd> Seek forward 1 sec
|
||||
- <kbd>.</kbd> (period) Tiny seek forward
|
||||
|
10
package.json
10
package.json
@ -4,11 +4,12 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "electron src",
|
||||
"build": "rm -rf dist && babel src -d dist --copy-files && ln -s ../node_modules dist/ && ln -s ../package.json ./dist/",
|
||||
"start": "electron dist",
|
||||
"watch": "npm run build && babel src -d dist --copy-files -w",
|
||||
"start-dist": "./node_modules/electron-prebuilt-compile/node_modules/electron/cli.js dist",
|
||||
"build": "rm -rf dist && babel src -d dist --copy-files && ln -s ../node_modules dist/ && ln -s ../package.json ./dist/",
|
||||
"package": "electron-packager dist LosslessCut --out=package --asar --overwrite --all --version 1.3.8",
|
||||
"zip": "(cd package && for f in LosslessCut-*; do zip -r $f; done)",
|
||||
"gifify": "gifify -p 405:299 -r 5@3 Untitled.mov-00.00.00.971-00.00.19.780.mp4",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"author": {
|
||||
@ -20,8 +21,8 @@
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"electron-packager": "^8.1.0",
|
||||
"electron-prebuilt-compile": "^1.4.4",
|
||||
"eslint": "^3.8.0",
|
||||
"eslint-config-airbnb": "^12.0.0",
|
||||
"eslint-plugin-import": "^1.16.0",
|
||||
@ -33,6 +34,7 @@
|
||||
"capture-frame": "^1.0.0",
|
||||
"classnames": "^2.2.5",
|
||||
"configstore": "^2.1.0",
|
||||
"electron": "^1.4.5",
|
||||
"electron-default-menu": "^1.0.0",
|
||||
"execa": "^0.5.0",
|
||||
"jquery": "^3.1.1",
|
||||
|
@ -38,7 +38,7 @@ input, button, textarea, :focus {
|
||||
padding: .4em;
|
||||
}
|
||||
|
||||
.jump-cut-start, .jump-cut-end {
|
||||
.jump-cut-start, .jump-cut-end, .playback-rate {
|
||||
background: white;
|
||||
border-radius: .3em;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
|
@ -57,7 +57,7 @@ class App extends React.Component {
|
||||
|
||||
const defaultState = {
|
||||
working: false,
|
||||
filePath: '', // Setting video src="" prevents memory leak
|
||||
filePath: '', // Setting video src="" prevents memory leak in chromium
|
||||
playing: false,
|
||||
currentTime: undefined,
|
||||
duration: undefined,
|
||||
@ -67,7 +67,12 @@ class App extends React.Component {
|
||||
|
||||
this.state = _.cloneDeep(defaultState);
|
||||
|
||||
const resetState = () => this.setState(defaultState);
|
||||
const resetState = () => {
|
||||
const video = getVideo();
|
||||
video.currentTime = 0;
|
||||
video.playbackRate = 1;
|
||||
this.setState(defaultState);
|
||||
};
|
||||
|
||||
const load = (filePath) => {
|
||||
resetState();
|
||||
@ -88,6 +93,9 @@ class App extends React.Component {
|
||||
};
|
||||
|
||||
keyboardJs.bind('space', () => this.playCommand());
|
||||
keyboardJs.bind('k', () => this.playCommand());
|
||||
keyboardJs.bind('j', () => this.changePlaybackRate(-1));
|
||||
keyboardJs.bind('l', () => this.changePlaybackRate(1));
|
||||
keyboardJs.bind('left', () => seekRel(-1));
|
||||
keyboardJs.bind('right', () => seekRel(1));
|
||||
keyboardJs.bind('period', () => shortStep(1));
|
||||
@ -98,6 +106,14 @@ class App extends React.Component {
|
||||
keyboardJs.bind('o', () => this.setCutEnd());
|
||||
}
|
||||
|
||||
onPlay(playing) {
|
||||
this.setState({ playing });
|
||||
|
||||
if (!playing) {
|
||||
getVideo().playbackRate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
setCutStart() {
|
||||
this.setState({ cutStartTime: this.state.currentTime });
|
||||
}
|
||||
@ -125,11 +141,24 @@ class App extends React.Component {
|
||||
setCursor((relX / $target[0].offsetWidth) * this.state.duration);
|
||||
}
|
||||
|
||||
changePlaybackRate(dir) {
|
||||
const video = getVideo();
|
||||
if (!this.state.playing) {
|
||||
video.playbackRate = 0.5; // dir * 0.5;
|
||||
video.play();
|
||||
} else {
|
||||
const newRate = video.playbackRate + (dir * 0.15);
|
||||
video.playbackRate = _.clamp(newRate, 0.05, 16);
|
||||
}
|
||||
}
|
||||
|
||||
playbackRateChange() {
|
||||
this.state.playbackRate = getVideo().playbackRate;
|
||||
}
|
||||
|
||||
playCommand() {
|
||||
const video = getVideo();
|
||||
if (this.state.playing) {
|
||||
return video.pause();
|
||||
}
|
||||
if (this.state.playing) return video.pause();
|
||||
|
||||
return video.play().catch((err) => {
|
||||
console.log(err);
|
||||
@ -176,8 +205,9 @@ class App extends React.Component {
|
||||
<div id="player">
|
||||
<video
|
||||
src={this.state.filePath}
|
||||
onPlay={() => this.setState({ playing: true })}
|
||||
onPause={() => this.setState({ playing: false })}
|
||||
onRateChange={() => this.playbackRateChange()}
|
||||
onPlay={() => this.onPlay(true)}
|
||||
onPause={() => this.onPlay(false)}
|
||||
onDurationChange={e => this.setState({ duration: e.target.duration })}
|
||||
onTimeUpdate={e => this.setState({ currentTime: e.target.currentTime })}
|
||||
/>
|
||||
@ -264,6 +294,9 @@ class App extends React.Component {
|
||||
</div>
|
||||
|
||||
<div className="right-menu">
|
||||
<button className="playback-rate" title="Playback rate">
|
||||
{_.round(this.state.playbackRate, 1) || 1}x
|
||||
</button>
|
||||
<i
|
||||
title="Capture frame"
|
||||
className="button fa fa-camera"
|
||||
|
Loading…
Reference in New Issue
Block a user