1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-25 03:33:14 +01:00

Implement lossless rotation

Allow for setting rotation metadata
This commit is contained in:
Mikael Finstad 2018-01-23 18:00:25 +07:00
parent 988584591a
commit 7962e174e6
3 changed files with 33 additions and 2 deletions

View File

@ -29,6 +29,7 @@ For more information about supported formats / codecs, see https://www.chromium.
- Drag drop a video file into player to load or use <kbd></kbd>/<kbd>CTRL</kbd>+<kbd>O</kbd>.
- Press <kbd>SPACE</kbd> to play/pause
- Select the cut start and end time. Press <kbd>I</kbd> to select the start time, <kbd>O</kbd> to select the end time for the cut.
- Press the rotation button if you want to set rotation metadata
- Press the scissors button to export the slice
- Press the camera button to take a snapshot

View File

@ -55,7 +55,7 @@ function handleProgress(process, cutDuration, onProgress) {
});
}
async function cut(customOutDir, filePath, format, cutFrom, cutTo, onProgress) {
async function cut(customOutDir, filePath, format, cutFrom, cutTo, rotation, onProgress) {
const extWithoutDot = path.extname(filePath) || `.${format}`;
const ext = `.${extWithoutDot}`;
const duration = `${util.formatDuration(cutFrom)}-${util.formatDuration(cutTo)}`;
@ -66,11 +66,12 @@ async function cut(customOutDir, filePath, format, cutFrom, cutTo, onProgress) {
// https://github.com/mifi/lossless-cut/issues/50
const cutFromArgs = cutFrom === 0 ? [] : ['-ss', cutFrom];
const rotationArgs = rotation !== undefined ? ['-metadata:s:v:0', `rotate=${rotation}`] : [];
const ffmpegArgs = [
'-i', filePath, '-y', '-vcodec', 'copy', '-acodec', 'copy',
...cutFromArgs, '-t', cutTo - cutFrom,
'-map_metadata', '0',
...rotationArgs,
'-f', format,
outPath,
];

View File

@ -92,6 +92,7 @@ class App extends React.Component {
cutEndTime: undefined,
fileFormat: undefined,
captureFormat: 'jpeg',
rotation: 360,
};
this.state = _.cloneDeep(defaultState);
@ -198,6 +199,24 @@ class App extends React.Component {
return undefined;
}
getRotation() {
return this.state.rotation;
}
getRotationStr() {
return `${this.getRotation()}°`;
}
isRotationSet() {
// 360 means we don't modify rotation
return this.state.rotation !== 360;
}
increaseRotation() {
const rotation = (this.state.rotation + 90) % 450;
this.setState({ rotation });
}
toggleCaptureFormat() {
const isPng = this.state.captureFormat === 'png';
this.setState({ captureFormat: isPng ? 'jpeg' : 'png' });
@ -255,6 +274,8 @@ class App extends React.Component {
const cutStartTime = this.state.cutStartTime;
const cutEndTime = this.state.cutEndTime;
const filePath = this.state.filePath;
const rotation = this.isRotationSet() ? this.getRotation() : undefined;
if (cutStartTime === undefined || cutEndTime === undefined) {
return alert('Please select both start and end time');
}
@ -272,6 +293,7 @@ class App extends React.Component {
fileFormat,
cutStartTime,
cutEndTime,
rotation,
progress => this.onCutProgress(progress),
);
} catch (err) {
@ -415,6 +437,13 @@ class App extends React.Component {
</div>
<div className="right-menu">
<button
title={`Set output rotation. Current: ${this.isRotationSet() ? this.getRotationStr() : 'Don\'t modify'}`}
onClick={withBlur(() => this.increaseRotation())}
>
{this.isRotationSet() ? this.getRotationStr() : '-°'}
</button>
<button
title={`Custom output dir (cancel to restore default). Current: ${this.getOutputDir() || 'Not set (use input dir)'}`}
onClick={withBlur(() => this.setOutputDir())}