diff --git a/README.md b/README.md index 3bc7467e..79ca02e4 100644 --- a/README.md +++ b/README.md @@ -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 /CTRL+O. - Press SPACE to play/pause - Select the cut start and end time. Press I to select the start time, O 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 diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 98450a16..0dd2782c 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -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, ]; diff --git a/src/renderer.jsx b/src/renderer.jsx index 776290c1..9075dc1b 100644 --- a/src/renderer.jsx +++ b/src/renderer.jsx @@ -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 {
+ +