diff --git a/src/renderer.jsx b/src/renderer.jsx index 8958d6d3..aed978bc 100644 --- a/src/renderer.jsx +++ b/src/renderer.jsx @@ -1,8 +1,7 @@ -import React, { memo, useEffect, useState, useCallback, useRef } from 'react'; +import React, { memo, useEffect, useState, useCallback, useRef, Fragment } from 'react'; import { IoIosHelpCircle, IoIosCamera } from 'react-icons/io'; import { FaPlus, FaMinus, FaAngleLeft, FaAngleRight, FaTrashAlt, FaVolumeMute, FaVolumeUp, FaYinYang, FaFileExport } from 'react-icons/fa'; import { MdRotate90DegreesCcw, MdCallSplit, MdCallMerge } from 'react-icons/md'; -import { GiYinYang } from 'react-icons/gi'; import { FiScissors } from 'react-icons/fi'; import { AnimatePresence, motion } from 'framer-motion'; import Swal from 'sweetalert2'; @@ -504,6 +503,31 @@ const App = memo(() => { if (!zoomed) seekRel((e.deltaX + e.deltaY) / 15); } + function showUnsupportedFileMessage() { + toast.fire({ timer: 10000, icon: 'warning', title: 'This video is not natively supported', text: 'This means that there is no audio in the preview and it has low quality. The final export operation will however be lossless and contains audio!' }); + } + + const createDummyVideo = useCallback(async (fp) => { + const html5ifiedDummyPathDummy = getOutPath(customOutDir, fp, 'html5ified-dummy.mkv'); + await ffmpeg.html5ifyDummy(fp, html5ifiedDummyPathDummy); + setDummyVideoPath(html5ifiedDummyPathDummy); + setHtml5FriendlyPath(); + showUnsupportedFileMessage(); + }, [customOutDir]); + + const tryCreateDummyVideo = useCallback(async () => { + try { + if (working) return; + setWorking(true); + await createDummyVideo(filePath); + } catch (err) { + console.error(err); + errorToast('Failed to playback this file. Try to convert to friendly format from the menu'); + } finally { + setWorking(false); + } + }, [createDummyVideo, filePath, working]); + const playCommand = useCallback(() => { const video = videoRef.current; if (playing) return video.pause(); @@ -511,10 +535,11 @@ const App = memo(() => { return video.play().catch((err) => { console.error(err); if (err.name === 'NotSupportedError') { - toast.fire({ icon: 'error', title: 'This format/codec is not supported. Try to convert it to a friendly format/codec in the player from the "File" menu.', timer: 10000 }); + console.log('NotSupportedError, trying to create dummy'); + tryCreateDummyVideo(filePath); } }); - }, [playing]); + }, [playing, filePath, tryCreateDummyVideo]); const deleteSource = useCallback(async () => { if (!filePath) return; @@ -613,10 +638,6 @@ const App = memo(() => { autoMerge, customOutDir, fileFormat, haveInvalidSegs, copyStreamIds, numStreamsToCopy, ]); - function showUnsupportedFileMessage() { - toast.fire({ timer: 10000, icon: 'warning', title: 'This video is not natively supported', text: 'This means that there is no audio in the preview and it has low quality. The final export operation will however be lossless and contains audio!' }); - } - // TODO use ffmpeg to capture frame const capture = useCallback(async () => { if (!filePath) return; @@ -645,14 +666,6 @@ const App = memo(() => { const getHtml5ifiedPath = useCallback((fp, type) => getOutPath(customOutDir, fp, `html5ified-${type}.mp4`), [customOutDir]); - const createDummyVideo = useCallback(async (fp) => { - const html5ifiedDummyPathDummy = getOutPath(customOutDir, fp, 'html5ified-dummy.mkv'); - await ffmpeg.html5ifyDummy(fp, html5ifiedDummyPathDummy); - setDummyVideoPath(html5ifiedDummyPathDummy); - setHtml5FriendlyPath(); - showUnsupportedFileMessage(); - }, [customOutDir]); - const checkExistingHtml5FriendlyFile = useCallback(async (fp, speed) => { const existing = getHtml5ifiedPath(fp, speed); const ret = existing && await exists(existing); @@ -667,7 +680,7 @@ const App = memo(() => { const load = useCallback(async (fp, html5FriendlyPathRequested) => { console.log('Load', { fp, html5FriendlyPathRequested }); if (working) { - errorToast('I\'m busy'); + errorToast('Tried to load file while busy'); return; } @@ -1135,20 +1148,19 @@ const App = memo(() => { const CutIcon = areWeCutting ? FiScissors : FaFileExport; function renderInvertCutButton() { - const KeepOrDiscardIcon = invertCutSegments ? GiYinYang : FaYinYang; - return ( -
- - - setInvertCutSegments(v => !v))} - /> - - +
+ + setInvertCutSegments(v => !v))} + /> +
); } @@ -1172,64 +1184,73 @@ const App = memo(() => { return (
- setStreamsSelectorShown(false)} - > - - - + {filePath && ( + + setStreamsSelectorShown(false)} + > + + + + + )}
- + {filePath && ( + - {renderOutFmt({ width: 60 })} + - + {renderOutFmt({ width: 60 })} - + - + + + + + )}