1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-22 02:12:30 +01:00

Allow pre-formatting or pre-encoding the video for more format support

Will still cut in original file.
This commit is contained in:
Mikael Finstad 2018-05-21 00:56:27 +02:00
parent 80afd9c91b
commit ef54e1b29f
3 changed files with 63 additions and 8 deletions

View File

@ -92,6 +92,27 @@ async function cut({
return util.transferTimestamps(filePath, outPath);
}
async function html5ify(filePath, outPath, encodeVideo) {
console.log('Making HTML5 friendly version', { filePath, outPath, encodeVideo });
const videoArgs = encodeVideo
? ['-vf', 'scale=-2:400,format=yuv420p', '-sws_flags', 'neighbor', '-vcodec', 'libx264', '-profile:v', 'baseline', '-x264opts', 'level=3.0', '-preset:v', 'ultrafast', '-crf', '28']
: ['-vcodec', 'copy'];
const ffmpegArgs = [
'-i', filePath, ...videoArgs, '-an',
'-y',
outPath,
];
console.log('ffmpeg', ffmpegArgs.join(' '));
const ffmpegPath = await getFfmpegPath();
const process = execa(ffmpegPath, ffmpegArgs);
const result = await process;
console.log(result.stdout);
}
/**
* ffmpeg only supports encoding certain formats, and some of the detected input
* formats are not the same as the names used for encoding.
@ -145,4 +166,5 @@ module.exports = {
cut,
getFormat,
showFfmpegFail,
html5ify,
};

View File

@ -25,6 +25,18 @@ module.exports = (app, mainWindow, newVersion) => {
});
},
},
{
label: 'Convert to friendly format (fast)',
click() {
mainWindow.webContents.send('html5ify', false);
},
},
{
label: 'Convert to friendly codec (slow)',
click() {
mainWindow.webContents.send('html5ify', true);
},
},
],
});

View File

@ -85,6 +85,7 @@ class App extends React.Component {
const defaultState = {
working: false,
filePath: '', // Setting video src="" prevents memory leak in chromium
html5FriendlyPath: undefined,
playing: false,
currentTime: undefined,
duration: undefined,
@ -95,6 +96,7 @@ class App extends React.Component {
fileFormat: undefined,
captureFormat: 'jpeg',
rotation: 360,
cutProgress: undefined,
};
this.state = _.cloneDeep(defaultState);
@ -106,8 +108,8 @@ class App extends React.Component {
this.setState(defaultState);
};
const load = (filePath) => {
console.log('Load', filePath);
const load = (filePath, html5FriendlyPath) => {
console.log('Load', { filePath, html5FriendlyPath });
if (this.state.working) return alert('I\'m busy');
resetState();
@ -120,7 +122,7 @@ class App extends React.Component {
.then((fileFormat) => {
if (!fileFormat) return alert('Unsupported file');
setFileNameTitle(filePath);
return this.setState({ filePath, fileFormat });
return this.setState({ filePath, html5FriendlyPath, fileFormat });
})
.catch((err) => {
if (err.code === 1 || err.code === 'ENOENT') {
@ -137,6 +139,23 @@ class App extends React.Component {
load(filePaths[0]);
});
electron.ipcRenderer.on('html5ify', async (event, encodeVideo) => {
const { filePath, customOutDir } = this.state;
if (!filePath) return;
try {
this.setState({ working: true });
const html5ifiedPath = util.getOutPath(customOutDir, filePath, 'html5ified.mp4');
await ffmpeg.html5ify(filePath, html5ifiedPath, encodeVideo);
this.setState({ working: false });
load(filePath, html5ifiedPath);
} catch (err) {
alert('Failed to html5ify file');
console.error('Failed to html5ify file', err);
this.setState({ working: false });
}
});
document.ondragover = document.ondragend = ev => ev.preventDefault();
document.body.ondrop = (ev) => {
@ -194,7 +213,7 @@ class App extends React.Component {
}
getFileUri() {
return (this.state.filePath || '').replace(/#/g, '%23');
return (this.state.html5FriendlyPath || this.state.filePath || '').replace(/#/g, '%23');
}
getOutputDir() {
@ -275,7 +294,7 @@ class App extends React.Component {
return video.play().catch((err) => {
console.log(err);
if (err.name === 'NotSupportedError') {
alert('This video format is not supported, maybe you can re-format the file first using ffmpeg');
alert('This video format or codec is not supported. Try to convert it to a friendly format/codec in the player from the "File" menu.');
}
});
}
@ -380,9 +399,11 @@ class App extends React.Component {
{this.state.working && (
<div id="working">
<i className="fa fa-cog fa-spin fa-3x fa-fw" style={{ verticalAlign: 'middle' }} />
{this.state.cutProgress != null &&
<span style={{ color: 'rgba(255, 255, 255, 0.7)' }}>
{Math.floor((this.state.cutProgress || 0) * 100)} %
{Math.floor(this.state.cutProgress * 100)} %
</span>
}
</div>
)}