From d0b2f05113798fef80dcd4991a8112659bcaffbe Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Sat, 15 Jan 2022 20:44:05 +0700 Subject: [PATCH] add setting for auto convert to supported format also remove unnecessary notification closes #414 --- public/configStore.js | 1 + src/App.jsx | 30 +++++++++++++++++++----------- src/Settings.jsx | 14 +++++++++++++- src/hooks/useUserPreferences.js | 4 ++++ 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/public/configStore.js b/public/configStore.js index 44d79c11..4c110964 100644 --- a/public/configStore.js +++ b/public/configStore.js @@ -40,6 +40,7 @@ const defaults = { outFormatLocked: undefined, safeOutputFileName: true, windowBounds: undefined, + enableAutoHtml5ify: true, }; // For portable app: https://github.com/mifi/lossless-cut/issues/645 diff --git a/src/App.jsx b/src/App.jsx index 43113848..b666f390 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -190,7 +190,7 @@ const App = memo(() => { const isCustomFormatSelected = fileFormat !== detectedFileFormat; const { - captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, + captureFormat, setCaptureFormat, customOutDir, setCustomOutDir, keyframeCut, setKeyframeCut, preserveMovData, setPreserveMovData, movFastStart, setMovFastStart, avoidNegativeTs, setAvoidNegativeTs, autoMerge, setAutoMerge, timecodeFormat, setTimecodeFormat, invertCutSegments, setInvertCutSegments, autoExportExtraStreams, setAutoExportExtraStreams, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, playbackVolume, setPlaybackVolume, autoSaveProjectFile, setAutoSaveProjectFile, wheelSensitivity, setWheelSensitivity, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, ffmpegExperimental, setFfmpegExperimental, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, autoDeleteMergedSegments, setAutoDeleteMergedSegments, exportConfirmEnabled, setExportConfirmEnabled, segmentsToChapters, setSegmentsToChapters, preserveMetadataOnMerge, setPreserveMetadataOnMerge, simpleMode, setSimpleMode, outSegTemplate, setOutSegTemplate, keyboardSeekAccFactor, setKeyboardSeekAccFactor, keyboardNormalSeekSpeed, setKeyboardNormalSeekSpeed, enableTransferTimestamps, setEnableTransferTimestamps, outFormatLocked, setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, enableAutoHtml5ify, setEnableAutoHtml5ify, } = useUserPreferences(); const { @@ -878,7 +878,7 @@ const App = memo(() => { }, [hideAllNotifications]); const showPreviewFileLoadedMessage = useCallback((fileName) => { - if (!hideAllNotifications) toast.fire({ text: i18n.t('Loaded existing preview file: {{ fileName }}', { fileName }) }); + if (!hideAllNotifications) toast.fire({ icon: 'info', text: i18n.t('Loaded existing preview file: {{ fileName }}', { fileName }) }); }, [hideAllNotifications]); const html5ify = useCallback(async ({ customOutDir: cod, filePath: fp, speed, hasAudio: ha, hasVideo: hv }) => { @@ -927,6 +927,7 @@ const App = memo(() => { const path = await html5ify({ customOutDir: cod, filePath: fp, speed, hasAudio: ha, hasVideo: shouldIncludeVideo }); return path; } + const path = await doHtml5ify(); if (!path) return; @@ -935,6 +936,14 @@ const App = memo(() => { showUnsupportedFileMessage(); }, [html5ify, html5ifyDummy, showUnsupportedFileMessage]); + const getConvertToSupportedFormat = useCallback((fallback) => rememberConvertToSupportedFormat || fallback, [rememberConvertToSupportedFormat]); + + const html5ifyAndLoadWithPreferences = useCallback(async (cod, fp, speed, hv, ha) => { + if (!enableAutoHtml5ify) return; + setWorking(i18n.t('Converting to supported format')); + await html5ifyAndLoad(cod, fp, getConvertToSupportedFormat(speed), hv, ha); + }, [enableAutoHtml5ify, setWorking, html5ifyAndLoad, getConvertToSupportedFormat]); + const showPlaybackFailedMessage = () => errorToast(i18n.t('Unable to playback this file. Try to convert to supported format from the menu')); const togglePlay = useCallback((resetPlaybackRate) => { @@ -1289,7 +1298,6 @@ const App = memo(() => { loadCutSegments(await readEdlFile({ type, path })); }, [loadCutSegments]); - const loadMedia = useCallback(async ({ filePath: fp, customOutDir: cod, projectPath }) => { console.log('loadMedia', fp, cod, projectPath); @@ -1352,8 +1360,7 @@ const App = memo(() => { // 'fastest' works with almost all video files if (!hasLoadedExistingHtml5FriendlyFile && !doesPlayerSupportFile(streams) && validDuration) { - setWorking(i18n.t('Converting to supported format')); - await html5ifyAndLoad(cod, fp, rememberConvertToSupportedFormat || 'fastest', haveVideoStream, haveAudioStream); + await html5ifyAndLoadWithPreferences(cod, fp, 'fastest', haveVideoStream, haveAudioStream); } try { @@ -1401,7 +1408,7 @@ const App = memo(() => { resetState(); throw err; } - }, [resetState, html5ifyAndLoad, loadEdlFile, getEdlFilePath, getEdlFilePathOld, loadCutSegments, enableAskForImportChapters, autoLoadTimecode, outFormatLocked, showPreviewFileLoadedMessage, rememberConvertToSupportedFormat, setWorking, setCopyStreamIdsForPath]); + }, [resetState, html5ifyAndLoadWithPreferences, loadEdlFile, getEdlFilePath, getEdlFilePathOld, loadCutSegments, enableAskForImportChapters, autoLoadTimecode, outFormatLocked, showPreviewFileLoadedMessage, setWorking, setCopyStreamIdsForPath]); const toggleHelp = useCallback(() => setHelpVisible(val => !val), []); const toggleSettings = useCallback(() => setSettingsVisible(val => !val), []); @@ -1799,16 +1806,15 @@ const App = memo(() => { setWorking(i18n.t('Converting to supported format')); console.log('Trying to create preview'); - if (!hideAllNotifications) toast.fire({ icon: 'info', text: 'This file is not natively supported. Creating a preview file...' }); if (!isDurationValid(await getDuration(filePath))) throw new Error('Invalid duration'); if (hasVideo) { // "fastest" is the most likely type not to fail for video (but it is muted). - await html5ifyAndLoad(customOutDir, filePath, rememberConvertToSupportedFormat || 'fastest', hasVideo, hasAudio); + await html5ifyAndLoadWithPreferences(customOutDir, filePath, 'fastest', hasVideo, hasAudio); } else if (hasAudio) { // For audio do a fast re-encode - await html5ifyAndLoad(customOutDir, filePath, rememberConvertToSupportedFormat || 'fastest-audio', hasVideo, hasAudio); + await html5ifyAndLoadWithPreferences(customOutDir, filePath, 'fastest-audio', hasVideo, hasAudio); } } catch (err) { console.error(err); @@ -1819,7 +1825,7 @@ const App = memo(() => { } catch (err) { handleError(err); } - }, [fileUri, usingPreviewFile, hasVideo, hasAudio, html5ifyAndLoad, hideAllNotifications, customOutDir, filePath, rememberConvertToSupportedFormat, setWorking]); + }, [fileUri, usingPreviewFile, hasVideo, hasAudio, html5ifyAndLoadWithPreferences, customOutDir, filePath, setWorking]); useEffect(() => { function showOpenAndMergeDialog2() { @@ -2110,11 +2116,13 @@ const App = memo(() => { setAutoLoadTimecode={setAutoLoadTimecode} enableTransferTimestamps={enableTransferTimestamps} setEnableTransferTimestamps={setEnableTransferTimestamps} + enableAutoHtml5ify={enableAutoHtml5ify} + setEnableAutoHtml5ify={setEnableAutoHtml5ify} AutoExportToggler={AutoExportToggler} renderCaptureFormatButton={renderCaptureFormatButton} onTunerRequested={onTunerRequested} /> - ), [changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments, autoSaveProjectFile, setAutoSaveProjectFile, timecodeFormat, setTimecodeFormat, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, ffmpegExperimental, setFfmpegExperimental, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, AutoExportToggler, renderCaptureFormatButton, onTunerRequested, enableTransferTimestamps, setEnableTransferTimestamps]); + ), [changeOutDir, customOutDir, keyframeCut, setKeyframeCut, invertCutSegments, setInvertCutSegments, autoSaveProjectFile, setAutoSaveProjectFile, timecodeFormat, setTimecodeFormat, askBeforeClose, setAskBeforeClose, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, ffmpegExperimental, setFfmpegExperimental, invertTimelineScroll, setInvertTimelineScroll, language, setLanguage, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, AutoExportToggler, renderCaptureFormatButton, onTunerRequested, enableTransferTimestamps, setEnableTransferTimestamps, enableAutoHtml5ify, setEnableAutoHtml5ify]); useEffect(() => { if (!isStoreBuild) loadMifiLink().then(setMifiLink); diff --git a/src/Settings.jsx b/src/Settings.jsx index 325e3960..db1f71d6 100644 --- a/src/Settings.jsx +++ b/src/Settings.jsx @@ -38,7 +38,7 @@ const Settings = memo(({ invertTimelineScroll, setInvertTimelineScroll, ffmpegExperimental, setFfmpegExperimental, enableAskForImportChapters, setEnableAskForImportChapters, enableAskForFileOpenAction, setEnableAskForFileOpenAction, hideNotifications, setHideNotifications, autoLoadTimecode, setAutoLoadTimecode, - enableTransferTimestamps, setEnableTransferTimestamps, + enableTransferTimestamps, setEnableTransferTimestamps, enableAutoHtml5ify, setEnableAutoHtml5ify }) => { const { t } = useTranslation(); @@ -245,6 +245,18 @@ const Settings = memo(({ + + {t('Try to automatically convert to supported format when opening unsupported file?')} + + setEnableAutoHtml5ify(e.target.checked)} + /> + + + + {t('Hide informational notifications?')} diff --git a/src/hooks/useUserPreferences.js b/src/hooks/useUserPreferences.js index 8fc13789..3fd3a52e 100644 --- a/src/hooks/useUserPreferences.js +++ b/src/hooks/useUserPreferences.js @@ -88,6 +88,8 @@ export default () => { useEffect(() => safeSetConfig('outFormatLocked', outFormatLocked), [outFormatLocked]); const [safeOutputFileName, setSafeOutputFileName] = useState(configStore.get('safeOutputFileName')); useEffect(() => safeSetConfig('safeOutputFileName', safeOutputFileName), [safeOutputFileName]); + const [enableAutoHtml5ify, setEnableAutoHtml5ify] = useState(configStore.get('enableAutoHtml5ify')); + useEffect(() => safeSetConfig('enableAutoHtml5ify', enableAutoHtml5ify), [enableAutoHtml5ify]); // NOTE! This useEffect must be placed after all usages of firstUpdateRef.current (safeSetConfig) @@ -163,5 +165,7 @@ export default () => { setOutFormatLocked, safeOutputFileName, setSafeOutputFileName, + enableAutoHtml5ify, + setEnableAutoHtml5ify, }; };