pull/728/head
Mikael Finstad 5 years ago
parent 523bdb7daa
commit 4b565ccb37
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -94,9 +94,9 @@ const videoStyle = { width: '100%', height: '100%', objectFit: 'contain' };
const App = memo(() => { const App = memo(() => {
// Per project state // Per project state
const [html5FriendlyPath, setHtml5FriendlyPath] = useState(); const [previewFilePath, setPreviewFilePath] = useState();
const [working, setWorking] = useState(); const [working, setWorking] = useState();
const [dummyVideoPath, setDummyVideoPath] = useState(false); const [usingDummyVideo, setUsingDummyVideo] = useState(false);
const [playing, setPlaying] = useState(false); const [playing, setPlaying] = useState(false);
const [playerTime, setPlayerTime] = useState(); const [playerTime, setPlayerTime] = useState();
const [duration, setDuration] = useState(); const [duration, setDuration] = useState();
@ -271,15 +271,15 @@ const App = memo(() => {
}, [seekRel, detectedFps]); }, [seekRel, detectedFps]);
/* useEffect(() => () => { /* useEffect(() => () => {
if (dummyVideoPath) unlink(dummyVideoPath).catch(console.error); if (usingDummyVideo && previewFilePath) unlink(previewFilePath).catch(console.error);
}, [dummyVideoPath]); */ }, [usingDummyVideo, previewFilePath]); */
// 360 means we don't modify rotation // 360 means we don't modify rotation
const isRotationSet = rotation !== 360; const isRotationSet = rotation !== 360;
const effectiveRotation = isRotationSet ? rotation : (mainVideoStream && mainVideoStream.tags && mainVideoStream.tags.rotate && parseInt(mainVideoStream.tags.rotate, 10)); const effectiveRotation = isRotationSet ? rotation : (mainVideoStream && mainVideoStream.tags && mainVideoStream.tags.rotate && parseInt(mainVideoStream.tags.rotate, 10));
const zoomRel = useCallback((rel) => setZoom(z => Math.min(Math.max(z + rel, 1), zoomMax)), []); const zoomRel = useCallback((rel) => setZoom(z => Math.min(Math.max(z + rel, 1), zoomMax)), []);
const canvasPlayerRequired = !!(mainVideoStream && dummyVideoPath); const canvasPlayerRequired = !!(mainVideoStream && usingDummyVideo);
const canvasPlayerWanted = !!(mainVideoStream && isRotationSet && !hideCanvasPreview); const canvasPlayerWanted = !!(mainVideoStream && isRotationSet && !hideCanvasPreview);
// Allow user to disable it // Allow user to disable it
const canvasPlayerEnabled = (canvasPlayerRequired || canvasPlayerWanted); const canvasPlayerEnabled = (canvasPlayerRequired || canvasPlayerWanted);
@ -474,7 +474,7 @@ const App = memo(() => {
setCustomOutDir(newOutDir); setCustomOutDir(newOutDir);
}, [outputDir, setCustomOutDir]); }, [outputDir, setCustomOutDir]);
const effectiveFilePath = dummyVideoPath || html5FriendlyPath || filePath; const effectiveFilePath = previewFilePath || filePath;
const fileUri = effectiveFilePath ? filePathToUrl(effectiveFilePath) : ''; const fileUri = effectiveFilePath ? filePathToUrl(effectiveFilePath) : '';
const getEdlFilePath = useCallback((fp) => getOutPath(customOutDir, fp, 'llc-edl.csv'), [customOutDir]); const getEdlFilePath = useCallback((fp) => getOutPath(customOutDir, fp, 'llc-edl.csv'), [customOutDir]);
@ -724,8 +724,8 @@ const App = memo(() => {
video.playbackRate = 1; video.playbackRate = 1;
setFileNameTitle(); setFileNameTitle();
setHtml5FriendlyPath(); setPreviewFilePath();
setDummyVideoPath(); setUsingDummyVideo(false);
setWorking(); setWorking();
setPlaying(false); setPlaying(false);
setDuration(); setDuration();
@ -770,16 +770,19 @@ const App = memo(() => {
if (!hideAllNotifications) toast.fire({ text: i18n.t('Loaded existing preview file: {{ fileName }}', { fileName }) }); if (!hideAllNotifications) toast.fire({ text: i18n.t('Loaded existing preview file: {{ fileName }}', { fileName }) });
}, [hideAllNotifications]); }, [hideAllNotifications]);
const html5ifiedPrefix = 'html5ified-';
const html5dummySuffix = 'dummy';
const createDummyVideo = useCallback(async (cod, fp) => { const createDummyVideo = useCallback(async (cod, fp) => {
const html5ifiedDummyPathDummy = getOutPath(cod, fp, 'html5ified-dummy.mkv'); const html5ifiedDummyPath = getOutPath(cod, fp, `${html5ifiedPrefix}${html5dummySuffix}.mkv`);
try { try {
setCutProgress(0); setCutProgress(0);
await html5ifyDummy({ filePath: fp, outPath: html5ifiedDummyPathDummy, onProgress: setCutProgress }); await html5ifyDummy({ filePath: fp, outPath: html5ifiedDummyPath, onProgress: setCutProgress });
} finally { } finally {
setCutProgress(); setCutProgress();
} }
setDummyVideoPath(html5ifiedDummyPathDummy); setUsingDummyVideo(true);
setHtml5FriendlyPath(); setPreviewFilePath(html5ifiedDummyPath);
showUnsupportedFileMessage(); showUnsupportedFileMessage();
}, [html5ifyDummy, showUnsupportedFileMessage]); }, [html5ifyDummy, showUnsupportedFileMessage]);
@ -826,7 +829,7 @@ const App = memo(() => {
const cleanupFiles = useCallback(async () => { const cleanupFiles = useCallback(async () => {
// Because we will reset state before deleting files // Because we will reset state before deleting files
const saved = { html5FriendlyPath, dummyVideoPath, filePath, edlFilePath }; const saved = { previewFilePath, filePath, edlFilePath };
if (!closeFile()) return; if (!closeFile()) return;
@ -844,10 +847,8 @@ const App = memo(() => {
try { try {
setWorking(i18n.t('Cleaning up')); setWorking(i18n.t('Cleaning up'));
if (deleteTmpFiles && saved.html5FriendlyPath) await trash(saved.html5FriendlyPath).catch(console.error); if (deleteTmpFiles && saved.previewFilePath) await trash(saved.previewFilePath).catch(console.error);
if (deleteTmpFiles && saved.dummyVideoPath) await trash(saved.dummyVideoPath).catch(console.error);
if (deleteProjectFile && saved.edlFilePath) await trash(saved.edlFilePath).catch(console.error); if (deleteProjectFile && saved.edlFilePath) await trash(saved.edlFilePath).catch(console.error);
// throw new Error('test'); // throw new Error('test');
if (deleteOriginal) await trash(saved.filePath); if (deleteOriginal) await trash(saved.filePath);
toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') }); toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') });
@ -863,8 +864,7 @@ const App = memo(() => {
}); });
if (value) { if (value) {
if (deleteTmpFiles && saved.html5FriendlyPath) await unlink(saved.html5FriendlyPath).catch(console.error); if (deleteTmpFiles && saved.previewFilePath) await unlink(saved.previewFilePath).catch(console.error);
if (deleteTmpFiles && saved.dummyVideoPath) await unlink(saved.dummyVideoPath).catch(console.error);
if (deleteProjectFile && saved.edlFilePath) await unlink(saved.edlFilePath).catch(console.error); if (deleteProjectFile && saved.edlFilePath) await unlink(saved.edlFilePath).catch(console.error);
if (deleteOriginal) await unlink(saved.filePath); if (deleteOriginal) await unlink(saved.filePath);
toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') }); toast.fire({ icon: 'info', title: i18n.t('Cleanup successful') });
@ -876,7 +876,7 @@ const App = memo(() => {
} finally { } finally {
setWorking(); setWorking();
} }
}, [filePath, html5FriendlyPath, dummyVideoPath, closeFile, edlFilePath]); }, [filePath, previewFilePath, closeFile, edlFilePath]);
const outSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments), const outSegments = useMemo(() => (invertCutSegments ? inverseCutSegments : apparentCutSegments),
[invertCutSegments, inverseCutSegments, apparentCutSegments]); [invertCutSegments, inverseCutSegments, apparentCutSegments]);
@ -1065,10 +1065,9 @@ const App = memo(() => {
if (!filePath) return; if (!filePath) return;
try { try {
const mustCaptureFfmpeg = html5FriendlyPath || dummyVideoPath;
const currentTime = currentTimeRef.current; const currentTime = currentTimeRef.current;
const video = videoRef.current; const video = videoRef.current;
const outPath = mustCaptureFfmpeg const outPath = previewFilePath
? await captureFrameFfmpeg({ customOutDir, filePath, currentTime, captureFormat, enableTransferTimestamps }) ? await captureFrameFfmpeg({ customOutDir, filePath, currentTime, captureFormat, enableTransferTimestamps })
: await captureFrameFromTag({ customOutDir, filePath, currentTime, captureFormat, video, enableTransferTimestamps }); : await captureFrameFromTag({ customOutDir, filePath, currentTime, captureFormat, video, enableTransferTimestamps });
@ -1077,7 +1076,7 @@ const App = memo(() => {
console.error(err); console.error(err);
errorToast(i18n.t('Failed to capture frame')); errorToast(i18n.t('Failed to capture frame'));
} }
}, [filePath, captureFormat, customOutDir, html5FriendlyPath, dummyVideoPath, outputDir, enableTransferTimestamps]); }, [filePath, captureFormat, customOutDir, previewFilePath, outputDir, enableTransferTimestamps]);
const changePlaybackRate = useCallback((dir) => { const changePlaybackRate = useCallback((dir) => {
if (canvasPlayerEnabled) { if (canvasPlayerEnabled) {
@ -1096,8 +1095,6 @@ const App = memo(() => {
} }
}, [playing, canvasPlayerEnabled]); }, [playing, canvasPlayerEnabled]);
const html5ifiedPrefix = 'html5ified-';
const getHtml5ifiedPath = useCallback((cod, fp, type) => { const getHtml5ifiedPath = useCallback((cod, fp, type) => {
// See also inside ffmpegHtml5ify // See also inside ffmpegHtml5ify
const ext = (isMac && ['slowest', 'slow', 'slow-audio'].includes(type)) ? 'mp4' : 'mkv'; const ext = (isMac && ['slowest', 'slow', 'slow-audio'].includes(type)) ? 'mp4' : 'mkv';
@ -1174,7 +1171,7 @@ const App = memo(() => {
setWorking(i18n.t('Loading file')); setWorking(i18n.t('Loading file'));
async function checkAndSetExistingHtml5FriendlyFile() { async function checkAndSetExistingHtml5FriendlyFile() {
const speeds = ['slowest', 'slow-audio', 'slow', 'fast-audio', 'fast', 'fastest-audio']; const speeds = ['slowest', 'slow-audio', 'slow', 'fast-audio', 'fast', 'fastest-audio', html5dummySuffix];
const prefix = `${getFileBaseName(fp)}-${html5ifiedPrefix}`; const prefix = `${getFileBaseName(fp)}-${html5ifiedPrefix}`;
const outDir = getOutDir(cod, fp); const outDir = getOutDir(cod, fp);
@ -1183,26 +1180,22 @@ const App = memo(() => {
let path; let path;
// eslint-disable-next-line no-restricted-syntax // eslint-disable-next-line no-restricted-syntax
for (const entry of dirEntries) { for (const entry of dirEntries) {
const html5Match = entry.startsWith(prefix); const prefixMatch = entry.startsWith(prefix);
if (html5Match) { if (prefixMatch) {
path = pathJoin(outDir, entry);
const speedMatch = speeds.find((s) => new RegExp(`${s}\\..*$`).test(entry.replace(prefix, ''))); const speedMatch = speeds.find((s) => new RegExp(`${s}\\..*$`).test(entry.replace(prefix, '')));
if (speedMatch) { if (!speedMatch || speedMatch !== html5dummySuffix) { // skip dummy, as it's not very useful
speed = speedMatch; path = pathJoin(outDir, entry);
} if (speedMatch) speed = speedMatch; // We want to also capture any custom user suffix (but NOT dummy)
break; break;
} }
} }
}
if (!path) return false; if (!path) return false;
console.log('Found existing supported file', path, speed); console.log('Found existing supported file', path, speed);
if (speed === 'fastest-audio') { setUsingDummyVideo(speed === 'fastest-audio');
setDummyVideoPath(path); setPreviewFilePath(path);
setHtml5FriendlyPath();
} else {
setHtml5FriendlyPath(path);
}
showPreviewFileLoadedMessage(basename(path)); showPreviewFileLoadedMessage(basename(path));
return true; return true;
@ -1234,7 +1227,7 @@ const App = memo(() => {
if (streamFps != null) setDetectedFps(streamFps); if (streamFps != null) setDetectedFps(streamFps);
} }
const shouldDefaultCopyStream = (stream) => { const shouldCopyStreamByDefault = (stream) => {
if (!defaultProcessedCodecTypes.includes(stream.codec_type)) return false; if (!defaultProcessedCodecTypes.includes(stream.codec_type)) return false;
// Don't enable thumbnail stream by default if we have a main video stream // Don't enable thumbnail stream by default if we have a main video stream
// It's been known to cause issues: https://github.com/mifi/lossless-cut/issues/308 // It's been known to cause issues: https://github.com/mifi/lossless-cut/issues/308
@ -1244,7 +1237,7 @@ const App = memo(() => {
setMainStreams(streams); setMainStreams(streams);
setCopyStreamIdsForPath(fp, () => fromPairs(streams.map((stream) => [ setCopyStreamIdsForPath(fp, () => fromPairs(streams.map((stream) => [
stream.index, shouldDefaultCopyStream(stream), stream.index, shouldCopyStreamByDefault(stream),
]))); ])));
setFileNameTitle(fp); setFileNameTitle(fp);
@ -1259,11 +1252,12 @@ const App = memo(() => {
const validDuration = isDurationValid(parseFloat(fd.duration)); const validDuration = isDurationValid(parseFloat(fd.duration));
if (html5FriendlyPathRequested) { if (html5FriendlyPathRequested) {
setHtml5FriendlyPath(html5FriendlyPathRequested); setUsingDummyVideo(false);
setPreviewFilePath(html5FriendlyPathRequested);
showUnsupportedFileMessage(); showUnsupportedFileMessage();
} else if (dummyVideoPathRequested) { } else if (dummyVideoPathRequested) {
setDummyVideoPath(dummyVideoPathRequested); setUsingDummyVideo(true);
setHtml5FriendlyPath(); setPreviewFilePath(dummyVideoPathRequested);
showUnsupportedFileMessage(); showUnsupportedFileMessage();
} else if ( } else if (
!(await checkAndSetExistingHtml5FriendlyFile()) !(await checkAndSetExistingHtml5FriendlyFile())
@ -1559,9 +1553,8 @@ const App = memo(() => {
let audio; let audio;
if (ha) { if (ha) {
if (speed === 'slowest') audio = 'hq'; if (speed === 'slowest') audio = 'hq';
else if (speed === 'slow-audio') audio = 'lq'; else if (speed === 'slow-audio' || speed === 'fastest-audio') audio = 'lq';
else if (speed === 'fast-audio') audio = 'copy'; else if (speed === 'fast-audio') audio = 'copy';
else if (speed === 'fastest-audio') audio = 'silent-audio';
} }
let video; let video;
@ -1624,7 +1617,7 @@ const App = memo(() => {
} }
const MEDIA_ERR_SRC_NOT_SUPPORTED = 4; const MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
if (error.code === MEDIA_ERR_SRC_NOT_SUPPORTED && !dummyVideoPath) { if (error.code === MEDIA_ERR_SRC_NOT_SUPPORTED && !usingDummyVideo) {
console.error('MEDIA_ERR_SRC_NOT_SUPPORTED'); console.error('MEDIA_ERR_SRC_NOT_SUPPORTED');
if (hasVideo) { if (hasVideo) {
if (isDurationValid(await getDuration(filePath))) { if (isDurationValid(await getDuration(filePath))) {
@ -1636,7 +1629,7 @@ const App = memo(() => {
await html5ifyAndLoad('fastest-audio'); await html5ifyAndLoad('fastest-audio');
} }
} }
}, [tryCreateDummyVideo, fileUri, dummyVideoPath, hasVideo, hasAudio, html5ifyAndLoad, hideAllNotifications, filePath]); }, [tryCreateDummyVideo, fileUri, usingDummyVideo, hasVideo, hasAudio, html5ifyAndLoad, hideAllNotifications, filePath]);
useEffect(() => { useEffect(() => {
function showOpenAndMergeDialog2() { function showOpenAndMergeDialog2() {
@ -1952,7 +1945,7 @@ const App = memo(() => {
}, []); }, []);
// TODO fastest-audio shows muted // TODO fastest-audio shows muted
const VolumeIcon = muted || dummyVideoPath ? FaVolumeMute : FaVolumeUp; const VolumeIcon = muted || usingDummyVideo ? FaVolumeMute : FaVolumeUp;
useEffect(() => { useEffect(() => {
const keyScrollPreventer = (e) => { const keyScrollPreventer = (e) => {

@ -309,10 +309,6 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
} }
break; break;
} }
case 'silent-audio': {
audioArgs = ['-acodec', 'flac', '-ar', '11025', '-ac', '2'];
break;
}
case 'lq': { case 'lq': {
if (isMac) { if (isMac) {
audioArgs = ['-acodec', 'aac_at', '-ar', '44100', '-ac', '2', '-b:a', '96k']; audioArgs = ['-acodec', 'aac_at', '-ar', '44100', '-ac', '2', '-b:a', '96k'];

Loading…
Cancel
Save